# The Inner Workings of CTK

**[scratch.mit.edu/projects/452865325](https://scratch.mit.edu/projects/452865325)**
CTK is an object oriented user interface platform written in scratch. It is designed for the CloudLine project, but can be implemented in other projects easily.
## Object structure:
```
0: id
1: parent
2: children
3: type
4: x
5: y
6: w
7: h
8:
9:
10:
11: text color
12: background color
13: border color
14: border width
15: draggable
16: resizable/button glyph
17: text
18: scroll
19: scroll length
```
All objects are stored in one grand list, and each one is headed by a unique ID number. They all have these same 20 values.
Each object has a list index number, which, even though it rarely does, can change. To find the list index number for an object, do:
`item # of ( join ( "⌘", id ) ) in ( ctk::objects )`
It is reccomended to store this value into a variable if you need to make multiple references to it within a short time.
Properties can be accessed using this value.
Say if we wanted to get the y value of an object who's index was in the "index" variable:
`item ( index + 5 ) of ( ctk::objects )`
## A Description of Every Value:
### ID:
Located at position 0.
A unique identifier for that object.
Cannot contain the character `;`
Do not change this value.
### Parent:
Located at position 1.
Contains the ID of the parent object.
If the object is free on the stage, then this value is blank.
Do not change this value, use the CTK blocks instead.
### Children:
Located at position 2.
Contains the IDs of the objects child object, separated by the `;` character.
Do not change this value, use the CTK blocks instead.
### Type:
Located at position 3.
The type of the object.
It can be one of these:
```
block
button
panel
glyph *(WORK IN PROGRESS)*
text
line
```
If the value is blank, the object will not be rendered (but its children still will). This is a great way to make a small object group, or container.
A panel has special properties: It's children will be offset from it differently, and the drag space is only on the title bar. It can also be manipulated via its title bar buttons.
### X, Y, W, and H:
Located at positions 4, 5, 6, and 7.
These determine the x and y position, as well as the width and height of the object.
If the object has a parent, it is drawn relative to that parent.
It is important to note that this uses a different coordinate system than the scratch one: it starts in teh top left of the screen, and the higher the y value, the lower down it is. This is how it works in most other programs.
*(WORK IN PROGRESS)* If the x value is negative, or equal to "right", the object will be drawn anchored to the right of its parent, and it will be that distance from the right most bound of it.
For example:
x = 5
```
##############
# #
# #### #
# #### #
# #
##############
```
x = -5
```
##############
# #
# #### #
# #### #
# #
##############
```
It will automatically adapt when the parent is resized.
This same concept applies the Y value, but instead it becomes anchored to the bottom.
If the x value equals "center", the object is centered horizontally. If the y equals "center", the object is centered vertically.
If the width is a decimal, the object will take up that times the parent object's width.
So for an object to take up one half of its parent's width, the width should be equal to 0.5.
This also applies to height.
### Text Color:
Located at position 11.
A color value denoting the text color of objects that have text or glyphs in them. If this is left blank, the object will default to its normal color.
### Background Color:
Located at position 12.
A color value denoting the background color of an object. If this is left blank, the object will default to its normal color *(WORK IN PROGRESS)*. If this value equals "none", it will have a transparent background.
### Border Color:
Located at position 13.
A color value denoting the border color of an object. If this is left blank, the object will default to its normal color *(WORK IN PROGRESS)*. If it is set to "shadow" in a line object, the line will be a semi-transparent black color (will be removed once transparency is added).
### Border Width:
Located at position 14.
A value denoting the corner radius and border width of an object. If this value is zero, there will be no border. A way to get rounded corners without a border would be to set the border color and background color to the same value.
If this value is left blank, the object will default to its default border width *(WORK IN PROGRESS)*.
### Draggable:
Located at position 15.
True if an object can be dragged, false if it can't.
This only applies to objects that are free on the stage.
### Resizable:
Located at position 16.
True if an object can be resized, false if it can't.
This only applies to objects that are free on the stage.
Since no sane person would want the user to resize a button, the resize value on buttons instead denotes what glyph the button has.
### Text:
Located at position 17.
If the object has a text field, then the text will go here.
It is handled differently for every object. A text object, for example, will use this as the text to display. A panel object, for example, will use this text as a title on it's title bar.
### Scroll:
*(WORK IN PROGRESS)*
Located at position 18.
This value defines how far scrolled down the obejct is.
### Scroll Length:
*(WORK IN PROGRESS)*
Locateed at positon 19.
This defines how long the scroll area for the object is. This is auto-calculated based on object positions, so it is pointless to change.
---
## Event Handling
CTK is event driven, and it provides functionality for handling these events.
The three main events in CTK are:
```
beginEvent
drawEvent
clickEvent
```
Each of these events has its own custom block, and whatever code is inside of the block will run when the event is triggered. And, since some events are specific to a particular object, they will have parameters that are passed when the event occurs.
## A Description of Every Event:
### Begin:
`ctk::beginEvent`
Whenever the green flag is pressed, CTK must set itself up before doing anything else. This involves resetting values and clearing out lists. Because of this, CTK can only be interacted with once it has finished setting itself up.
Anything in the `ctk::beginEvent` custom block is run imediately after CTK has completed the setup process. It is recommended to add objects to the scene here, as doing it when the green flag is clicked can cause problems.

It is also important to note that CTK will wait until this block has finished before drawing the screen. So, if you want to do something like start a forever loop when the project begins, you should use the `ctk::beginEvent` broadcast message:

### Draw:
`ctk::drawEvent (id, x, y, w, h)`
All objects are drawn on screen at mach speed, many times a second. This is what makes CTK look and feel like a real life desktop.
The following is the procedure CTK goes through to draw each object:
1. Calculate the position, bounds, width, height, etc.
2. Draw the object on screen.
3. Call `ctk::drawEvent` with the ID, position, and dimensions of the object being drawn.
4. Recursively do all of this for child objects.
So, anything in here:

Gets run every time an object is drawn, and the values of the inputs correspond to those of the object being currently drawn. This allows the user to combine functionality of the current project with the power of CTK.
To properly check *which* object the draw function is being called in, if statements should be used:

### Click:
`ctk::clickEvent (id)`
This one is fairly simple. Whenever an object is clicked, anything in the `ctk::clickEvent` block will be run, with the ID of the object that was clicked. This is how you make buttons do things.
---
## Interaction
Directly manipulating list values it time consuming and difficult. Instead, CTK provides functions to abstract the management of objects.
## A Description of Every Function:
### Add:
`ctk::objects::add(id, parent, type, x, y, w, h, ?, ?, ?, textcolor, bgcolor, bordercolor, borderwidth, draggable, sizeable, text)`
This block adds a new object to the specified parent, with the specified initial values. If a parameter is empty, it uses the default value. This is usually calculated on the fly.
#### Values and their defaults:
| Value | Default |
| ----------- | --------- |
| id | REQUIRED! |
| parent | stage |
| type | invisible |
| x | 0 |
| y | 0 |
| w | REQUIRED! |
| h | REQUIRED! |
| textcolor | VARIES* |
| bgcolor | VARIES* |
| bordercolor | VARIES* |
| borderwidth | VARIES* |
| draggable | false |
| sizeable | false |
| text | `""` |
*\*depends on the object type*