% % Visualize Stuff, EchoView-like % % This is a simple attempt of implementing something similar to % EchoView's visualisation feature for PCC. The basic principle: % you enter an expression yielding a number, and PCC displays % bars of appropriate size at every planet/ship. PCC already has % something similar built in (object labels). % % There are 4 "layers" of visualisation, the appropriate bars are % displayed in northeast, northwest, southwest and southeast of the % labelled object. % % The main entry point is `Visualize'; it'll prompt for necessary % parameters. Although not required by the rest of the code, the % user interface fixes the ranges at 100..10000, that is, a % value less than 100 will not be displayed; values larger than % 10000 will yield a maximum-size bar (40 pixels, vis.Height). % % Besides being useful, this script demonstrates some funky uses of % the `Eval' statement ;-) % + PCC does not (yet) have array variables, so we simulate them by % generating variable names % + Variables containing "a, b, c" are split into pieces by passing % them to subroutines as parameters % % Author: January 2002 by Stefan Reuther % % Needs PCC 1.0.16 (older ones don't have Eval). % Print "[vis.q -- 02/Jan/2002]" % Specification of the four layers: x offset, y offset, color Shared vis.Layer1 = "2,2,11" Shared vis.Layer2 = "-2,2,12" Shared vis.Layer3 = "-2,-2,13" Shared vis.Layer4 = "2,-2,15" % These store the status foe convenience Shared vis.Expr1, vis.Expr2, vis.Expr3, vis.Expr4 Shared vis.Data1, vis.Data2, vis.Data3, vis.Data4 Shared vis.Height = 40 % height of a bar % Display once. expr=expression, layer=1..4, flags=objects to process % (p=planet, s=ship), min/max=ranges Sub vis.Display (expr, layer, flags, min, max) Local dx,dy,color,value Local a = Atom("vis.Layer" & layer) Local args Eval 'args := vis.Layer' & layer Eval 'vis.Parse ' & args If Instr(flags, 'p') Then ForEach Planet Do Try vis.Bar Next EndIf If Instr(flags, 's') Then ForEach Ship Do Try vis.Bar Next EndIf EndSub % Draw one bar. Takes dx,dy,color,loc.x,loc.y,a,min,max,expr from caller Sub vis.Bar Local value Eval 'value := ' & expr If value >= min Then Local he = If(value > max, vis.Height, value * vis.Height \ max) If dy<0 Then he := -he NewRectangle Loc.x+dx-1, Loc.y+dy, Loc.x+dx+1, Loc.y+dy+he, color, a, 0 NewLine Loc.x+dx, Loc.y+dy, Loc.x, Loc.y, color, a, 0 EndIf EndSub % How do we parse a vis.LayerX variable into three values? Using eval... Sub vis.Parse (pdx,pdy,pcolor) dx = pdx dy = pdy color = pcolor EndSub % Delete everything on the specified layer Sub vis.Delete (layer) Local a = Atom("vis.Layer" & layer) ForEach Marker Do If Tag=a Then Delete Next EndSub % Called by `Visualize'. Sub vis.Sub (expr, layer, flags, min, max) Local UI.Result UI.Input 'Expression for layer ' & layer & ':', 'Visualize', 255, '', expr If IsEmpty(UI.Result) Then Return expr := UI.Result UI.Message 'For which objects do you want to compute that?', 'Visualize', 'Planets Ships Both Cancel' If UI.Result=4 Then Return flags := '' If UI.Result<>2 Then flags := flags & 'p' If UI.Result<>1 Then flags := flags & 's' Eval 'vis.Expr' & layer & ' := expr' Eval 'vis.Data' & layer & " := '\"" & flags & "\", " & min & ', ' & max & "'" vis.Delete layer vis.Display expr, layer, flags, min, max EndSub % Main entry point Sub Visualize Local UI.Result, layer, data, expr UI.Message 'Which layer do you want to use?', 'Visualize', '1 2 3 4 Cancel' If UI.Result=5 Then Return layer := UI.Result Eval 'data := vis.Data' & layer Eval 'expr := vis.Expr' & layer If IsEmpty(data) Then data := '"ps", 100, 10000' Eval 'vis.Sub expr, layer, ' & data EndSub Bind Starchart 'c-v' := 'Visualize'