Traditionally CTC (Computer Train Control) windows have been manipulated using reserved words beginning with a dollar sign, such as $Draw message and $switch. Rather than extend this system new features will be added using the objects that many other features enjoy.
The CtcWindow objects take the name specified in the declarations part of the script, as with any variables. This name has no bearing upon the name (or title) of the displayed window. CTC windows default to having a title of 'CTC' followed by its window number but this can be changed either by editing the ctc file, or by using the ctcSetTitle method described below, or even the System.windowSetTitle method which can be used on almost any Tcc window.
A CtcWindow object has the following methods currently implemented:
setSize (cols, rows) |
Sets the current viewable area in terms of CTC cells. Note that cell size is constant so window size varies with number of cells displayed. |
setCellSize (colWidth, rowHeight) |
Sets the size of each cell in the window. Note that the window size is unchanged so the number of cells displayed will change. |
panTo (col, row) |
Set the offset to the cell displayed in the top left corner. panTo (0,0) restores the normal view. |
Set the colour of the track in this specified cell. A colour of zero means default to black. The stroke parameter has the following meanings: 0=Set track colour, turn others off; 1=Set track colour, leaving reserved and train settings; 2=Set reserved colour; 3=Turn off reserved markings, 4=Use wide train lines, 5=remove wide train lines. |
|
Set the colour of the block containing the specified cell. 'from' and 'to' are percentages that default to 0 and 100 that specify how much of the block to colour. Note that the cells in the ctc file must be in sequence for fractional colouring to make sense. |
|
Set the background colour (default if omitted) for the specified cell and optionally a rectangle of cells from that location. Set default background and grid colours for the whole window |
|
Set the track line to alarm width (25% wider than regular track) and colour. Omitting the colour returns the track to normal display. |
|
setTrackAspect (cellId, aspect) |
Select the aspect used to display the track segment specified. This replaces the $switch action. |
setTrackLines (cellId, lines, lines, ...) |
Set the pattern of track segments shown for the specified cell. The first 'lines' parameter is the default pattern, subsequent parameters (up to eight in all) specify other aspects. Each lines value is a number in the range 0 (blank) to 255 (a star symbol). |
popup (cellId, menu items, ...) |
Display a popup menu in the specified cell. See below for allowed formats of the cellId parameter. The popup is populated from the list of menu items. Each parameter can be a single menu item, a list of menu items, or even a database query to populate a sub-menu. See below for more details of cellId parameter formats and for menu item formats. |
popupName () |
Returns the name of the item last selected from a popup. |
popupSubName () |
Returns the name of the sub menu the last selection was from, or a null string is the last selection was from the main menu. |
ctcSetTitle (name) |
Set the title of the window. The title defaults to 'CTC<n>' where <n> is the CTC number, or to a string edited into the project/ctc.? File. |
drawMessage (cellId, message, [size], [position], [colour], [background]) |
Draw the message starting at the specified cell. The last four parameters are all optional and any may be omitted by leaving blank, for example drawMessage (1,1,"X",,4) skips the size, sets position to 4 and omits colour and background. See setMessageSize and setMessagePos below for accepted values for these parameters. See below for more details of cellId parameter formats. |
followMessage (cellId, variable, [size], [position]) |
Draw the contents of the specified variable (same as with drawMessage) but if the contents of the variable change the display will update to match. |
setMessageSize (cellId, size) |
Set the size of the message already drawn in the specified cell. Permitted sizes are: 1=small, 2=medium, 3=large |
setMessagePos (cellId, pos) |
Set the position of the message already drawn in the specified cell. Permitted values are as per the cell track line bitmap: 0=centre, 1=top-left, 2=top centre, 3=top right, 4=right, 5=bottom right, 6=bottom, 7=bottom left, 8=left |
Set the colour of the text, and optionally the background colour of the text in the specified cell. Foreground colour can be omitted by using two commas, for example colourMessage (1,1,,red) |
|
eraseMessage (cellId) |
Erase the message from the specified cell. See below for more details of cellId parameter formats. |
drawShape (cellId, “cmd1”, “cmd2”, ...) |
Define or edit a drawing for the cell. |
ctcFront () |
Bring this window to the front if it is open. This is the same as System.windowFront (ctc Number) |
ctcBack () |
Take this window to the back, behind other windows. |
ctcClear () |
Blank out this CTC window. |
ctcMetaName (cellId) |
Returns the META name given to the specified cell, or undefined (value 0) otherwise. This can be used to check that a meta name has been defined, by passing in a name and expecting the same name back. |
ctcMetaData (cellid) |
Returns the META value given to the specified cell, or undefined (value 0) if no meta data has been assigned. The returned value could be a numeric value, or a string dependant upon what has been assigned. |
ctcSetMeta (cellId, name, value) |
Assign META data to a cell. If "name" exist anywhere already, it is deleted before the new entry is added. Value may be a string or a numeric value. If a string that is a valid numeric value, such as "123" the numeric value is stored. |
setFullScreen (screenNumber) |
IF SUPPORTED: Make this CTC fill the specified screen. Screen numbers are system dependant. There is presently no script mechanism to end full screen mode. |
x=drawImage (cellId, filename, width, height) x=drawSprite (cellId, filename, width, height) |
Draw a new image loaded from file <filename> (a string parameter) at the specified cell (see below for allowed formats of cellId). If not specified height (number of cells) defaults to the same as width, and width defaults to 1. Negative images represent percentage of cell width, so -25 means one quarter. Images are associated with CTC cells (only one per cell), are aligned to cell boundaries, can be moved by specifying the cell (see moveImage) and are drawn behind the track lines. Sprites are independent of CTC cells (though are positioned using the same coordinates), can be drawn offset from cell boundaries and are drawn in front of track lines. Sprites cannot be moved by specifying the cell they are in. |
eraseImage (cellIdNum) |
Remove the image (or sprite) specified. |
addAspect (cellIdNum, fileName) |
Add another aspect to an existing image. The initially drawn image becomes aspect 1, and subsequently added aspects are number 2, 3 and so on. The displayed aspect is selected using setImageAspect (). This mechanism is more efficient than loading images repeatedly by cycling around several drawImage calls which can eventually lose memory. |
Modify first aspect, or add another aspect where each aspect is a re-coloured version of the basic image originally drawn. Any number of oldColour, newColour pairs may be specified and pixels which match or are close to the oldColour are replaced with newColour. See below for a definition of colours being close. For example if the original image is a three colour signal head with red, yellow and green lamps on then calling addAspect (cell, yellow, white, green, white) will make a new signal head with only the red light on as aspect 2. |
|
setImageAspect (cellIdNum, aspect) |
Select which aspect of a multi-aspect image to display. Values out of the range 1..<number of aspects> cause the image to be hidden until a valid aspect number is given. |
moveImage (CellIdFormat, newCellid) moveImageND (ditto) |
Move an existing image. The first parameter (or two) specifies the image to manipulate and can be any cellId format described below, or can be a value returned by drawImage. The second cellId optionally specifies where to move the image to. See "Drawing images and sprites" below for moveImageND. |
moveSprite (imageNumber, newCellId, xFraction, yFraction) moveSpriteND (ditto) |
Move an existing sprite. The first parameter is a value returned by drawSprite. The cellId specifies where to move the sprite to. The optional fraction parameters cause the image to be drawn off-grid by the specified percentage of cell size. If xFraction is 50 the left edge of the image is positioned 50% of the way across the specified cell. yFraction moves downwards. The fraction parameters are not restricted to the range 0..100. Fractional positioning can also be specified in an XYZ parameter for the newCellId. |
setOffset (cellIdNum, x, y) setOffsetND (ditto) |
Define the point within the image to be treated as the origin of the image. These values are percentages so 0,0 is the top left of the image, 100,0 is top right. If not specified they default to 50,50 which is the centre of the image. Note these are fractions of the drawn image size, not the cell size. |
rotateImage (cellIdNum, rotation, x, y) rotateImageND (ditto) rotateSprite (imageNumber, rotation, x, y) rotateSpriteND (ditto) |
Rotate an existing image or sprite to the specified rotation value (in degrees). Rotation is not limited to the range 0..360. The optional x and y parameters specify the point within the image to use as the centre of rotation. These values are percentages so 0,0 is the top left of the image, 100,0 is top right. If not specified they default to 50,50 which is the centre of the image. Note these are fractions of the drawn image size, not the cell size. See "Drawing images and sprites" below for rotateImageND. |
scaleImage (cellIdNum, scaleX, scaleY, fill) scaleImageND (ditto) scaleSprite (imageNumber, scaleX, scaleY, fill) scaleSpriteND (ditto) |
Scale an existing image to the size specified as a count of columns and rows. scaleY defaults to the same as scaleX. fill defaults to 0. If fill is zero the image is scaled proportionally until either width or height is the size specified. If fill is 1 then the image is scaled unequally so the specified number of cells are completely filled (if the image is not rotated). See "Drawing images and sprites" below for scaleImageND. |
flipImage (cellIdNum, flipX, flipY) flipImageND (ditto) flipSprite (imageNumber, flipX, flipY) flipSpriteND (ditto) |
If flipX is non-zero the image is reflected horizontally, if flipY is non-zero the image is reflected vertically. |
hideImage (cellIdNum) hideSprite (imageNumber) |
Make the specified image (or sprite) invisible. It is still in the cell or location it was previously but it is simply not drawn. |
showImage (cellIdNum) showSprite (imageNumber) |
Make the specified image visible again after being hidden. |
showCtc () hideCtc () |
Make the CTC window visible or invisible. |
setCtcCursor (cursurNum) |
Use the specified predefined cursor: Default = 0, Crosshair = 1, Text = 2, Wait = 3, Resize = 4..11, Hand = 12, Move = 13. |
embedCtc (cellId, fromWin, cellId, cols, rows) unembedCtc |
Display the block of cells specified in fromWin (another CtcObject) in this window. This is like placing symbolic links (shortcuts) in the cells so some other cell's contents are used for displaying. Any old contents of our window are hidden until the cells are unembedded, but unembed is not currently supported except by using ctcClear (). Note: the parameters to embedCtc are liable to change in future versions, to make them consistent with embedCol. |
embedCol (column, whereFrom, cols, rows) unembedCol (column) |
ONLY REMOTE WINDOWS: Insert after column (or before -column) a block of cells from another window. Note that this inserts space into the CTC window rather than overlaying existing cells. The number of rows in the inserted column does not have to match the number of rows in the body of the CTC window. |
addSlider (cellId, cols, rows, min, max, var) |
Display a slider (like a scroll-bar). Can be horizontal (rows=1) or vertical (cols=1). Min, max and var are all treated as follow variables. If min or max changes then the slider limits are re-calibrated. If var changes the slider is moved to suit. If the slider is moved using the mouse then var gets changed to suit. |
addSpinner (cellId, cols, rows, min, max, var) |
As for addSlider, but a spinner is displayed (a number entry box with up and down arrows). |
addCheckBox (cellId, var) |
Display a checkbox in the specified cell (size is system-dependant). When var is non-zero the checkbox is ticked, when zero the box is clear. Toggling the box changes the variable. |
AddTextBox (cellId, cols, stringVar {, wStart, wEnd} ) |
This displays the text presently in stringVar (it must be a string variable, not just a regular variable containing a string) in the cell specified, and spreading over the specified number of columns (just like sliders, but textBoxes can only be horizontal). By default the whole of stringVar is displayed (if it fits in the box) but if wStart, wEnd is specified then only the specified words (first word is number 1). Changes to the contents of the variable cause the CTC to be updated and manual edits to the textBox cause the variable (or some words in the variable) to change when the enter key is pressed after entering a change. |
removeControl (cellId) |
Remove the slider, spinner or checkbox from the specified cell. |
Other methods are expected to duplicate the set of CTC image functions and add support for textual images and sprites (foreground images) as well as background images.
The methods taking a CTC cell address (cellId) as a parameter will accept the following formats:
col, row |
Actually two parameters - two numbers or variables or expressions evaluating to two numbers which give column number (starting from 1) and row number (starting from 1) |
[col, row] or [col, row, windowId] [col, row, dx, dy] or [col, row, windowId, dx, dy] |
A bracketed set of two to five numeric values. This format is a single parameter and the row and column (and optionally the CTC window number) is encoded into a single value. This format is more normally used to store a cellId in a regular variable. Any window number is ignored by CtcWindow objects as that is naturally inferred by the use of a CtcWindow object. If dx and dy are supplied then they imply fractional cell locations as percentages, thus [4,5,50,0] means half way across cell 4.5. Fractional locations can only presently be used for sprite positioning. |
[“cell-meta”] or [“cell-meta”, dx, dy] [“block-meta”, cellNum] [“block-meta”, cellNum, dx, dy] [“block-meta”, position, length] |
A meta name (defined using the meta button in the tools pallette or by editing the CTC file) translates to a cell location. Fractional adjustments can be added when positioning sprites. The name of a block (requires CTC file editing) can be followed by a cell number (1 to size of block or negative numbers relative to end of block). A position (along the block) and length (of the block's track) will calculate a location along the track lines in that block (assuming cells are in order). |
variable |
A variable that has either an XYZ value ([col, row] or [col, row, window]) or a meta name string in it. |
"name" |
A meta name that should exist in the ctc file. Such names need to be manually edited into the ctc file. Meta names have the advantage that if the CTC diagram is edited, perhaps by inserting or deleting rows or columns (using the <^> tool in the pallette) the script doesn't need editing to keep cell Ids in line with the ctc file. |
In addition to the above, cellIdNum parameters can be a value returned from a previous drawImage call.
Images are pictures that are drawn behind track lines, as a backdrop. Sprites are pictures drawn in front, perhaps to illustrate a train moving on a track.
Both kinds may be manipulated by using the appropriate move, rotate and scale methods.
The methods ending ND (such as rotateImageND), meaning No-Draw, do not trigger a screen redraw, so if you need to move, rescale and rotate an image in one go, use all three methods, but use ND for all but the last one. This should reduce the likelihood of unwanted temporary images appearing on the screen.
Images can hold multiple aspects (several graphical pictures in a single CTC cell). Only a single aspect is visible at once and this can be selected using setImageAspect (). Selecting between multiple aspects (a signal for example) is more efficient than repeatedly loading images as the latter mechanism would eventually run out of memory.
When images are re-coloured using addAspect (imageid, oldColour, newColour) the following procedure is followed: If this is the first re-colouring of the image then the image is first converted to a 256 colour pallette to reduce the potential number of colours in the image. This pallette is formed using a 6/6/6 colour cube with the remainder of the space filled with grey scale. This means there are 6 levels of red, six of blue and six of green making 216 colours (plus the grey scale levels). A pixel matches oldColour if the sum of the three colour level deltas is less than 60. This means either the colours match exactly (within the 6/6/6 cube) or two (of red, green and blue) match and the third is off by one slot. The exact mechanism might change if some other comparison seems to work better across a range of images.
An example of how to use re-colouring is to load an image of a signal, with ALL coloured aspects showing at once:
CtcWindows: Signals
Actions:
WHEN init=0 DO
sig=Signals.drawImage (2,4,"images/sig3.jpg",1,2),wait 2
Signals.addAspect (sig,yellow,gray,green,gray), { convert the image to red aspect only }
Signals.addAspect (sig,red,gray,green,gray), { Add a yellow aspect }
Signals.addAspect (sig,red,gray,yellow,gray),cycle=1
WHILE cycle=1 DO
Signals.setImageAspect (sig,1), wait 1, { select red aspect }
Signals.setImageAspect (sig,2), wait 1,
Signals.setImageAspect (sig,3), wait 1,
|
The first statement load the image called "images/sig3.jpg" which is a 3 aspect signal with the three aspects already coloured red, yellow and green. The image is loaded into square 2,4 at two cells high. The wait 2 allows the image loading to complete before recolouring is attempted. Then the red aspect is created by turning both yellow and green into gray. Similarly the yellow and green aspects are created by converting the other two aspects (of the ORIGINAL) image to gray. In this example the signal is simply animated slowly between red, yellow and green.
If you want to create a four aspect signal which has two yellow aspects then perhaps the second yellow should be created blue. Then the blue converted to gray or yellow as appropriate.
The following colours are pre-defined in TCL, and are an adaptation of the colours defined at http://cloford.com/resources/colours/500col.htm
Black
Gray20
LtGray
Gray40
Gray
Gray60
DkGray
Gray80
White
|
RGB_000000 (or simply RGB_0)
RGB_333333
RGB_404040
RGB_666666
RGB_7F7F7F
RGB_999999
RGB_C0C0C0
RGB_CCCCCC
RGB_FFFFFF
|
transparent
|
RGB_00000000 (note more than 6 digits gives alpha)
|
Brown
Brown1
Brown2
RosyBrown
Maroon
DkGoldenRod
Red
Red2
OrangeRed
VioletRed
BurlyWood
Pink
HotPink
LtSalmon
Sienna
IndianRed
LtPink
Orange
Orange1
DkOrange
CadmiumYellow
YellowGreen
Gold
|
RGB_004890
RGB_3333FF
RGB_3333CC
RGB_9999CC
RGB_9933CC
RGB_006699
RGB_0000FF (or simply RGB_FF)
RGB_0000CC
RGB_0033CC
RGB_9933FF
RGB_99CCFF
RGB_CCCCFF
RGB_CC66FF
RGB_6699FF
RGB_3366CC
RGB_6666CC
RGB_666699
RGB_0080FF
RGB_0099FF
RGB_0066CC
RGB_0099FF
RGB_33CC99
RGB_00CCFF
|
DkPlum
Plum
Magenta
Orchid
|
RGB_996699
RGB_CC99CC
RGB_CC00CC
RGB_CC66CC
|
Chartreuse
Green
DkSeaGreen
SpringGreen
SpringGreen1
PaleGreen
DkGreen
DkOliveGreen
MintGreen
LimeGreen
Aquamarine
|
RGB_00CC66
RGB_00FF00
RGB_99CC99
RGB_99FF00
RGB_66CC00
RGB_99FF99
RGB_006600
RGB_66FFCC
RGB_CCFFCC
RGB_33CC33
RGB_99CC66
|
Yellow
LemonChiffon
|
RGB_00FFFF
RGB_99CCCC
|
LtBlue
Turquoise
CadetBlue
|
RGB_CCCC99
RGB_CCCC00
RGB_FFFF99
|
Blue
MedBlue
DkBlue
SkyBlue
DkSkyBlue
DeepSkyBlue
CornFlowerBlue
SteelBlue
RoyalBlue
Peacock
SlateBlue
Purple
Purple1
MedPurple
DkOrchid
|
RGB_FF0000
RGB_CC0000
RGB_990000
RGB_CC9966
RGB_996600
RGB_CC9900
RGB_FF9966
RGB_996633
RGB_CC6633
RGB_CC9933
RGB_CC6666
RGB_FF0080
RGB_FF3399
RGB_CC6699
RGB_CC3399
|
The lines in each cell are drawn according to the bitmap specified [using the pallette, editing the CTC file or using setTrackLines ()]. Different colours and widths can be obtained and the drawing is done in several stages, in the following order:
Grey lines (such as turnouts switched to one direction). Width 8, colour grey.
Track lines. Width 8. Colour from colourTrack, colourBlock else black.
Reserved track lines. Width 3. Colour from colourTrack, colourBlock else not drawn.
Train extent lines. Width 12. Colour from colourTrack, colourBlock else not drawn
Alarm lines. Width 10. Colour from alarmBlock else not drawn
Width values are relative, and vary with cell size.
The following transformations are applied to an image in its progress from disk to screen:
Scale to initial size |
The source files used can be images of wildly varying sizes and using the final scaling algorithm to render a large image into a small cell creates a very poor image, so the image is scaled to size using an advanced algorithm, but only once on initial loading. |
Flip the image |
Reflect the image left-right and/or top-bottom if required. This is done in such a way that the reflected image is at the same location as the original image. |
Apply offset |
Translate (shift left-right and/or up-down) so that the desired point on the image is at the location specified for drawing on the screen. Not that the offset applies after flipping. |
Scale to size |
Scale the image to the number of rows and columns specified (possibly expanding one dimension for a FILL operation). |
Rotate about some centre. |
Rotate any amount about some specified centre of rotation. A centre of rotation of 0, 0 refers to the offset location so any non-zero rotation centre causes a rotation away from the offset location. |
Translate to desired cell |
Shift the image to the required place on the screen. The origin (offset position) of an image is placed at the top-left of the specified cell. Sprites are drawn with the image origin at the specified fractional position in the cell. |
In addition to the methods a CTC object has the following elements:
numRows |
The number of rows currently displayed. |
numCols |
The number of columns currently displayed. |
panRow |
The row currently panned to. |
panCol |
The column currently panned to. |
popIndex |
The index into the main popup menu that was last selected. Indexes start from 1. This value is set to zero when a popup menu is displayed. |
popSubIndex |
The index into a submenu that was last selected. Indexes start from 1. This is set to zero when a popup menu is displayed and if the selection is not from a submenu then it is left at zero. |
The popup () method will accept any number of parameters specifying menu contents, and each of which can hold any number of menu specifiers, comma separated.
A single menu specifier consists of up to three items:
Menu item name |
The string to be displayed in the menu. This can contain spaces, or any characters except comma, ampersand or vertical bar. Such a name normally makes a regular menu item (unless an ampersand follows). |
& name of database query |
If an ampersand is present the the text after it (to the end of the item, the next comma, or the next vertical bar) is taken to be the name of a database query object. Name makes a sub menu (instead of a regular menu item) and the database query contents populate the sub-menu. The first column of query should contain the strings to populate the sub-menu and a second column (if present) should contain a list of image filenames to use as icons. |
| icon filename |
If a vertical bar is present then the text after it (to the end of the item or comma) is taken to be the name of a file containing an image to be displayed alongside the menu item name. Such files can be any format supported by $Draw Image and might be used perhaps to show an item of rolling stock. |
Presently there is no means of creating sub-menus without using a database query, nor can a database query populate the main popup.
Last updated 24 June 2019
© Howard Amos 2008-2019