How do I create a gauge?

Custom Components

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.

Gauge layout

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

FileMaker action

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.

0 Comments

Add your comment

E-Mail me when someone replies to this comment