|
| 1 | +/* |
| 2 | +Copyright (C) 2015-2016 LiveCode Ltd. |
| 3 | + |
| 4 | +This file is part of LiveCode. |
| 5 | + |
| 6 | +LiveCode is free software; you can redistribute it and/or modify it under |
| 7 | +the terms of the GNU General Public License v3 as published by the Free |
| 8 | +Software Foundation. |
| 9 | + |
| 10 | +LiveCode is distributed in the hope that it will be useful, but WITHOUT ANY |
| 11 | +WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 12 | +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 13 | +for more details. |
| 14 | + |
| 15 | +You should have received a copy of the GNU General Public License |
| 16 | +along with LiveCode. If not see <http://www.gnu.org/licenses/>. */ |
| 17 | + |
| 18 | +/** |
| 19 | +This widget is a spinner or activity indicator. Spinners provide visual |
| 20 | +feedback to users use when performing an activity for an unknown |
| 21 | +duration such as processing a large amount of data or presenting a |
| 22 | +complex user interface. |
| 23 | +*/ |
| 24 | + |
| 25 | +-- declaring extension as widget, followed by identifier |
| 26 | +widget com.livecode.widget.spinner |
| 27 | +-- |
| 28 | + |
| 29 | +-- dependency declarations |
| 30 | +use com.livecode.canvas |
| 31 | +use com.livecode.widget |
| 32 | +use com.livecode.engine |
| 33 | +use com.livecode.math |
| 34 | +-- |
| 35 | + |
| 36 | +-- adding metadata to ensure the extension displays correctly in livecode |
| 37 | +metadata title is "Spinner" |
| 38 | +metadata author is "LiveCode" |
| 39 | +metadata version is "0.0.0" |
| 40 | +metadata preferredSize is "36,36" |
| 41 | +metadata svgicon is "M496 1408Q496 1468 453.5 1510 411 1552 352 1552 292 1552 250 1510 208 1468 208 1408 208 1348 250 1306 292 1264 352 1264 411 1264 453.5 1306 496 1348 496 1408ZM928 1600Q928 1653 890.5 1690.5 853 1728 800 1728 747 1728 709.5 1690.5 672 1653 672 1600 672 1547 709.5 1509.5 747 1472 800 1472 853 1472 890.5 1509.5 928 1547 928 1600ZM320 960Q320 1026 273 1073 226 1120 160 1120 94 1120 47 1073 0 1026 0 960 0 894 47 847 94 800 160 800 226 800 273 847 320 894 320 960ZM1360 1408Q1360 1454 1327 1487 1294 1520 1248 1520 1202 1520 1169 1487 1136 1454 1136 1408 1136 1362 1169 1329 1202 1296 1248 1296 1294 1296 1327 1329 1360 1362 1360 1408ZM528 512Q528 585 476.5 636.5 425 688 352 688 279 688 227.5 636.5 176 585 176 512 176 439 227.5 387.5 279 336 352 336 425 336 476.5 387.5 528 439 528 512ZM992 320Q992 400 936 456 880 512 800 512 720 512 664 456 608 400 608 320 608 240 664 184 720 128 800 128 880 128 936 184 992 240 992 320ZM1536 960Q1536 1000 1508 1028 1480 1056 1440 1056 1400 1056 1372 1028 1344 1000 1344 960 1344 920 1372 892 1400 864 1440 864 1480 864 1508 892 1536 920 1536 960ZM1328 512Q1328 545 1304.5 568.5 1281 592 1248 592 1215 592 1191.5 568.5 1168 545 1168 512 1168 479 1191.5 455.5 1215 432 1248 432 1281 432 1304.5 455.5 1328 479 1328 512Z" |
| 42 | + |
| 43 | +metadata foregroundColor.label is "Marker color" |
| 44 | + |
| 45 | +/** |
| 46 | +Summary: Whether to scale the markers to or maintain a constant size |
| 47 | + |
| 48 | +Syntax: |
| 49 | +set the scaleMarkers of <widget> to { true | false } |
| 50 | +get the scaleMarkers of <widget> |
| 51 | + |
| 52 | +Value (boolean): True if markers should be scaled; false otherwise |
| 53 | + |
| 54 | +Description: |
| 55 | +If true, the markers will be scaled as in addition to changing |
| 56 | +transparency. The default value is true. |
| 57 | + |
| 58 | +*/ |
| 59 | +property scaleMarkers get mScaleMarkers set setScaleMarkers |
| 60 | +metadata scaleMarkers.default is "true" |
| 61 | +metadata scaleMarkers.label is "Scale markers" |
| 62 | +private variable mScaleMarkers as Boolean |
| 63 | + |
| 64 | +/** |
| 65 | +Summary: The number of markers to display in the spinner |
| 66 | + |
| 67 | +Syntax: |
| 68 | +set the markerCount of <widget> to <markers> |
| 69 | +get the markerCount of <widget> |
| 70 | + |
| 71 | +Value (integer): The number of markers to display around the circle |
| 72 | + |
| 73 | +Description: |
| 74 | +The markerCount is an integer greater than 4. The default value is 8. |
| 75 | + |
| 76 | +*/ |
| 77 | +property markerCount get mMarkerCount set setMarkerCount |
| 78 | +metadata markerCount.editor is "com.livecode.pi.integer" |
| 79 | +metadata markerCount.default is "8" |
| 80 | +metadata markerCount.step is "1" |
| 81 | +metadata markerCount.min is "5" |
| 82 | +metadata markerCount.label is "Marker count" |
| 83 | +private variable mMarkerCount as Integer |
| 84 | + |
| 85 | +private variable mRadius as Number |
| 86 | +private variable mCentre as List |
| 87 | +private variable mBigMarkerOffset as Integer |
| 88 | +private variable mBigMarkerSize as Number |
| 89 | + |
| 90 | +constant kUpdate is 0.3 |
| 91 | + |
| 92 | +public handler onSave(out rProperties as Array) |
| 93 | + put the empty array into rProperties |
| 94 | + put mScaleMarkers into rProperties["scaleMarkers"] |
| 95 | + put mMarkerCount into rProperties["markerCount"] |
| 96 | +end handler |
| 97 | + |
| 98 | +public handler onLoad(in pProperties as Array) |
| 99 | + put pProperties["scaleMarkers"] into mScaleMarkers |
| 100 | + put pProperties["markerCount"] into mMarkerCount |
| 101 | +end handler |
| 102 | + |
| 103 | +-- called when widget is created |
| 104 | +public handler onCreate() |
| 105 | + put true into mScaleMarkers |
| 106 | + put 8 into mMarkerCount |
| 107 | +end handler |
| 108 | + |
| 109 | +public handler onOpen() |
| 110 | + put 0 into mBigMarkerOffset |
| 111 | + schedule timer in kUpdate seconds |
| 112 | +end handler |
| 113 | + |
| 114 | +-- called whenever LiveCode needs to redraw the widget |
| 115 | +public handler onPaint() |
| 116 | + put (the minimum of my width and my height) / 2 into mRadius |
| 117 | + put [my width / 2, my height / 2] into mCentre |
| 118 | + put mRadius / mMarkerCount * 2 into mBigMarkerSize |
| 119 | + |
| 120 | + variable tPaint as Paint |
| 121 | + put my foreground paint into tPaint |
| 122 | + |
| 123 | + translate this canvas by mCentre |
| 124 | + |
| 125 | + variable tMarker as Integer |
| 126 | + |
| 127 | + repeat with tMarker from 1 up to mMarkerCount |
| 128 | + variable tAngle as Number |
| 129 | + variable tX as Number |
| 130 | + variable tY as Number |
| 131 | + |
| 132 | + put ((mBigMarkerOffset + tMarker)/mMarkerCount * 360) * pi / 180 into tAngle |
| 133 | + |
| 134 | + put -cos(tAngle) * (mRadius - mBigMarkerSize) into tY |
| 135 | + put sin(tAngle) * (mRadius - mBigMarkerSize) into tX |
| 136 | + |
| 137 | + variable tScale as Number |
| 138 | + put 0.3 + 0.7 * tMarker/mMarkerCount into tScale |
| 139 | + |
| 140 | + variable tSize as Number |
| 141 | + if mScaleMarkers then |
| 142 | + put mBigMarkerSize * tScale into tSize |
| 143 | + else |
| 144 | + put mBigMarkerSize * 0.8 into tSize |
| 145 | + end if |
| 146 | + |
| 147 | + set the opacity of this canvas to tScale |
| 148 | + |
| 149 | + variable tPath as Path |
| 150 | + put circle path centered at point [tX, tY] with radius tSize into tPath |
| 151 | + |
| 152 | + set the paint of this canvas to tPaint |
| 153 | + fill tPath on this canvas |
| 154 | + end repeat |
| 155 | +end handler |
| 156 | + |
| 157 | +public handler onTimer() |
| 158 | + redraw all |
| 159 | + if mBigMarkerOffset is mMarkerCount -1 then |
| 160 | + put 0 into mBigMarkerOffset |
| 161 | + else |
| 162 | + add 1 to mBigMarkerOffset |
| 163 | + end if |
| 164 | + schedule timer in kUpdate seconds |
| 165 | +end handler |
| 166 | + |
| 167 | +public handler setScaleMarkers(in pScaleMarkers as Boolean) |
| 168 | + put pScaleMarkers into mScaleMarkers |
| 169 | + redraw all |
| 170 | +end handler |
| 171 | + |
| 172 | +public handler setMarkerCount(in pMarkerCount as Integer) |
| 173 | + if pMarkerCount < 5 then |
| 174 | + throw "Invalid marker count: " & pMarkerCount |
| 175 | + return |
| 176 | + end if |
| 177 | + |
| 178 | + put pMarkerCount into mMarkerCount |
| 179 | + redraw all |
| 180 | +end handler |
| 181 | + |
| 182 | +end widget |
0 commit comments