How do I create a gauge?
Custom components are LiveCode stack files that have a `FileMakerAction` handler in their main stack script. This is the main event to be handled when the stack needs to do something. In this lesson we will create a simple notification dialog that stays on screen for a set number of seconds and then goes away. You will need the LiveCode IDE and a copy of FileMaker 14 or 15 in order to complete this lesson. If you don't have a copy of Livecode you can download a 30 day trial from here. The screenshots in this lesson were made with LiveCode 9. There may be some variations depending on the version of Livecode you use to complete the lesson.
Creating the stack
Open LiveCode IDE and choose `File > New Stack > Default Size` from the menu
Choose `Object > Stack Inspector` from the menu to open the inspector
In the inspector change the name of the stack to `Gauge`
Creating the controls for the gauge
Drag an oval graphic from the `Tools` palette to the stack.
Double-click the graphic and change its name to `background` (1), line thickness to 0 (2) and arc to 180 (3). When you change the line thickness you won't be able to see where the oval is but that's ok because we will change the color next.
Click on the `Color` tab (1) and set the background fill to white (2)
Click on the graphic and hold the alt key down while you drag away. This will duplicate the graphic. Double-click the new graphic and change the name to gauge then go to the color pane and set the background color to something that contrasts against the white background graphic.
Duplicate the graphic again and this time name the graphic `mask`. On the `Basic` properties pane set the `Arc` to 360. On the color pane set the ink property to `blendDstOut`.
Drag a label field from the `Tools` palette and set its name to `min`.
On the `Text` pane set its text align to centered.
Duplicate the field and name the new field `max`
Duplicate it again and name the new field `units`
Duplicate the field again and name it `value` then set the text size to 24
Duplicate the `value` field and name it `title`
Drag from the top left of the stack to the bottom right selecting all the objects. With all the objects selected click the `Group` button. Ensure the `Select Grouped` toggle button shows the crossed out circle to indicate the groups will be selected rather than the objects within them.
Double-click the group the open the inspector and name it `ExportGroup`. Set the `Margins` of the group to 0.
On the `Color` pane of the inspector set the ink property to `blendSrcOver`. The `mask` graphic will disappear but that's what we want.
Don't worry that the group currently looks nothing like a gauge. We are going to do all the object layout in script so that we can have parameters that change the way the gauge looks. Right click on the stack and choose `Stack > Edit Script` from the contextual menu.
We are going to implement the script as two commands. Firstly we will implement a LayoutGauge command that does all the layout. Then when that is implemented and tested we will add the FileMakerAction handler to read the parameters from FileMaker and return the exported image of the gauge. Copy the `LayoutGauge` handler below to the script editor.
on LayoutGauge pTitle, pWidth, pHeight, pMin, pMax, pValue, pUnits, pLineWidth lock screen set the clipsToRect of group "ExportGroup" to true set the rect of group "ExportGroup" to 0, 0, pWidth, pHeight put pTitle into field "title" set the width of field "title" to the formattedWidth of field "title" set the height of field "title" to the formattedHeight of field "title" put pMin into field "min" set the width of field "min" to the formattedWidth of field "min" set the height of field "min" to the formattedHeight of field "min" put pMax into field "max" set the width of field "max" to the formattedWidth of field "max" set the height of field "max" to the formattedHeight of field "max" put pUnits into field "units" set the width of field "units" to the formattedWidth of field "units" set the height of field "units" to the formattedHeight of field "units" put pValue into field "value" set the width of field "value" to the formattedWidth of field "value" set the height of field "value" to the formattedHeight of field "value" local tHPadding = 0 local tVPadding = 0 local tGaugeHeight put (pHeight - the height of field "min" - the height of field "title") * 2 into tGaugeHeight if tGaugeHeight > pWidth then put (tGaugeHeight - pWidth) / 4 into tVPadding else put (pWidth - tGaugeHeight) / 2 into tHPadding end if set the rect of graphic "background" to tHPadding, \ the height of field "title" + tVPadding, \ pWidth - tHPadding, \ the height of field "title" + tVPadding + (pHeight - the height of field "title" - the height of field "min" - tVPadding * 2) * 2 set the rect of graphic "gauge" to the rect of graphic "background" local tMaskRect put the rect of graphic "background" into tMaskRect add pLineWidth to item 1 of tMaskRect add pLineWidth + 1 to item 2 of tMaskRect subtract pLineWidth from item 3 of tMaskRect subtract pLineWidth - 1 from item 4 of tMaskRect set the rect of graphic "mask" to tMaskRect local tLocation put the location of graphic "background" into tLocation set the location of field "units" to tLocation set the bottom of field "units" to item 2 of tLocation set the location of field "title" to tLocation set the bottom of field "title" to the top of graphic "background" set the location of field "min" to tHPadding + pLineWidth / 2, item 2 of tLocation + the height of field "min" / 2 set the location of field "max" to pWidth - tHPadding - pLineWidth / 2, item 2 of tLocation + the height of field "min" / 2 subtract the height of graphic "mask" / 4 from item 2 of tLocation set the location of field "value" to tLocation local tAngle put pValue / (pMax - pMin) * 180 into tAngle set the arcAngle of graphic "gauge" to tAngle set the startAngle of graphic "gauge" to 180 - tAngle end LayoutGauge
Click `Apply` in the top left corner of the script editor. We will use the message box to test the new handler. Click on the `Message Box` button on the toolbar.
Copy the following command to the message box and type return. The gauge should then layout as in the image below.
LayoutGauge "Sprint Points", 300, 200, 0, 180, 50, "points", 40
Now that we have a handler that does all the layout of the gauge the FileMakerAction handler only needs to call it with the parameters from FileMaker and then export the image to return. Add the following handler to the stack script, apply and save the stack to a location you can easily remember for the next step.
on FileMakerAction pAction go invisible this stack LayoutGauge fmParam(1), fmParam(2), fmParam(3), fmParam(4), fmParam(5), fmParam(6), fmParam(7), fmParam(8) local tData put "binary" into tData["type"] put "PNGf" into tData["main"] put "gauge.png" into tData["filename"] put the width of group "ExportGroup" into tData["width"] put the height of group "ExportGroup" into tData["height"] export snapshot from group "ExportGroup" to tData["value"]["PNGf"] as PNG return tData end FileMakerAction
Importing into LiveCode for FM
The stack is now complete and just needs to be imported into LiveCode for FM as a custom component. Save the stack in a location you can remember and open the LiveCode for FM solution and click on the `Custom Components` button.
Click on the `+`(1) icon to add a new component and choose the saved stack file in the file dialog. Name the component `Gauge` to match the stack name and click `OK`. When you return to the `LiveCode Workspace` click the `Close`(2) button
Testing in a solution
Open an existing FileMaker solution or create a new solution in by choosing `File > New Solution...` from the FileMaker menubar
Open the `Field Picker` and add a `Value` number field and a `Gauge` calculation field.
Set the calculation result to `Container` and the calculation to use the `Gauge` custom component. Here we are using the `Value` field from the database but constants for all the other parameters. Click `OK`.
Drag the fields from the Field Picker to the layout.
Right click the `Gauge` field and choose `Object Style > Minimal Container` from the contextual menu then click `Exit Layout`
Choose `Records > New Record` from the menubar and enter a number between 0 and 100 into the value field.