lua
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revision | |||
lua [2025/04/12 07:47] – removed - external edit (Unknown date) 127.0.0.1 | lua [2025/04/12 07:47] (current) – old revision restored (2024/10/20 20:29) splitbrain | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Lua Scripting Introduction ====== | ||
+ | Just like their physical counterparts on non-smartwatches, | ||
+ | |||
+ | Luckily, WatchMaker allows us to customize not only the visual aspects of these parts, but also what they' | ||
+ | |||
+ | What is included, are the following three aspects: | ||
+ | |||
+ | - **Conditionals** -- This is your basic "IF this THEN that ELSE the other thing" statement. | ||
+ | - **Math Functions** -- This can be as basic as 1+1, or as complex as SIN/COS, and can be used for anything from adding/ | ||
+ | - **String Functions** -- Sometimes you're not dealing with numbers, but with words or other characters. | ||
+ | |||
+ | In addition, WatchMaker does a lot of the tedious work for you of gathering information, | ||
+ | |||
+ | Lua makes all of this possible, and this section' | ||
+ | |||
+ | (Note: | ||
+ | |||
+ | |||
+ | ===== Conditional Statements ===== | ||
+ | |||
+ | Conditional statements (IF-THEN-ELSE) work in much the same as most languages and also supports " | ||
+ | |||
+ | |||
+ | ===== Conditional Value Assignment ===== | ||
+ | These allow you to conditionally set a value to a property based on some conditions, the syntax uses (IF-AND-OR). | ||
+ | |||
+ | It's easy once you know this: | ||
+ | |||
+ | ^ IF < | ||
+ | |||
+ | A simple Example: | ||
+ | |||
+ | ({dm} % 2 == 0) and ' | ||
+ | |||
+ | A more complex example: | ||
+ | |||
+ | ({dh} < 11) and ' | ||
+ | | ||
+ | Note the parentheses. | ||
+ | |||
+ | Here's another example of why it's a good idea to add parentheses: | ||
+ | |||
+ | ({dh} > 23 or {dh} < 1) and ' | ||
+ | |||
+ | ===== Math ===== | ||
+ | |||
+ | The [[http:// | ||
+ | |||
+ | ==== Functions ==== | ||
+ | |||
+ | For example, to rotate something depending on the current time on a radius of 100px around the center by setting the x and y [[position]]: | ||
+ | |||
+ | x: math.sin(math.rad({drh})) * 100 | ||
+ | y: math.cos(math.rad({drh})) * -100 | ||
+ | | ||
+ | ===== Strings ===== | ||
+ | |||
+ | Text [[http:// | ||
+ | |||
+ | You can quote strings with double or single quotes so 'some text' is also a string. | ||
+ | |||
+ | ==== Methods ==== | ||
+ | |||
+ | Upper/ | ||
+ | |||
+ | string.upper(' | ||
+ | string.lower(' | ||
+ | |||
+ | Reverse a string: | ||
+ | |||
+ | string.reverse(' | ||
+ | |||
+ | Shorten a string (use only first 20 chars): | ||
+ | |||
+ | string.sub(' | ||
+ | | ||
+ | ==== Concatenation ==== | ||
+ | |||
+ | Say you want to add strings together. The " | ||
+ | |||
+ | " | ||
+ | | ||
+ | We can also include strings that have been manipulated by methods: | ||
+ | |||
+ | " | ||
+ | |||
+ | If you're going to start a text field with a conditional formula, then plan to concatenate a string to it, you **must** encapsulate the entire formula part in a single set of parentheses. | ||
+ | |||
+ | | ||
+ | |||
+ | In that example, the concatenation will occur regardless of the conditional outcome. | ||
+ | |||
+ | | ||
+ | |||
+ | |||
+ | ===== Lua Script Files ===== | ||
+ | From WatchMaker 3.4.0 onwards, you can now create Lua script files within your watch! | ||
+ | |||
+ | The script file is saved in your BeautifulWatches/ | ||
+ | |||
+ | You can edit the script file with any code editor on your phone, PC or Mac. You can see Lua errors and use print() statements for debugging using a Lua text editor like [[http:// | ||
+ | |||
+ | Or edit direct in WatchMaker: click on watch properties (icon opposite Undo), then click Script. This will also show Lua errors. | ||
+ | |||
+ | Your script file is executed each time your watch is initialized. You can also restart your script by hitting the back button when you are in edit mode. | ||
+ | |||
+ | The script files can include any of the following : | ||
+ | * **Custom variables** - e.g. below for number, string or color examples : | ||
+ | |||
+ | var_mynumber = 123 | ||
+ | var_mystring = 'hello world' | ||
+ | var_mycolor = ' | ||
+ | | ||
+ | Whilst there is no strict naming convention for variables, please **prefix all variables that you wish to expose to WatchMaker layers with var_** so that WatchMaker knows to interpret these using Lua, e.g. var_mynumber | ||
+ | |||
+ | * **Custom Functions** - e.g. below for a calculator watch : | ||
+ | |||
+ | function click_button (digit) | ||
+ | if digit == ' | ||
+ | formula_temp = calc_formula | ||
+ | formula_temp = string.gsub(formula_temp, | ||
+ | formula_temp = string.gsub(formula_temp, | ||
+ | calc_formula = load(' | ||
+ | elseif digit == ' | ||
+ | calc_formula = '' | ||
+ | else | ||
+ | calc_formula=calc_formula..digit | ||
+ | end | ||
+ | var_calc_display = string.len(calc_formula) >= 1 and calc_formula or ' | ||
+ | end | ||
+ | |||
+ | * **Code to run at startup** - e.g. below for a calculator watch : | ||
+ | |||
+ | click_button (0) | ||
+ | | ||
+ | ===== Run Lua from Tap Actions ===== | ||
+ | |||
+ | From WatchMaker 4.4 onwards, you can execute Lua scripts by tapping any watch layer! Just click a layer, hit Tap Action -> Run Script and enter the script required. | ||
+ | |||
+ | You are recommended to keep Tap Action scripts shorter e.g. by running functions in the main script file, as Tap Action scripts are stored in the XML file and not the separate script file. | ||
+ | |||
+ | ===== Run Lua Function Every Hour, Minute, Second or Millisecond ===== | ||
+ | |||
+ | function on_hour(h) | ||
+ | function on_minute(h, | ||
+ | function on_second(h, | ||
+ | function on_millisecond(dt) | ||
+ | |||
+ | If you have some custom variables that update every millisecond, | ||
+ | |||
+ | angle = 0.0 | ||
+ | radius = 175.0 | ||
+ | var_ms_posx = 0.0 | ||
+ | var_ms_posy = 0.0 | ||
+ | function on_millisecond(dt) | ||
+ | angle = angle + 20.0 * dt | ||
+ | var_ms_posx = radius * math.sin(math.rad(angle)) | ||
+ | var_ms_posy = radius * math.cos(math.rad(angle)) | ||
+ | end | ||
+ | |||
+ | So that WatchMaker updates the layers that use these custom variables each millisecond, | ||
+ | |||
+ | If you only need second updates instead of millisecond updates, please use // | ||
+ | |||
+ | ===== Run Lua Function When Watch Turns Bright / Dim ===== | ||
+ | |||
+ | The following example will animate a tweens.radius property to change when the watch turns bright / dim - this code goes in your script file : | ||
+ | |||
+ | function on_display_bright() | ||
+ | | ||
+ | end | ||
+ | |||
+ | function on_display_not_bright() | ||
+ | | ||
+ | end | ||
+ | |||
+ | ===== Scheduling Animations / Functions ===== | ||
+ | |||
+ | You can schedule animations or functions from WatchMaker events, e.g. watch turning bright/dim or tap actions. An example animation is below : | ||
+ | wm_schedule { action=' | ||
+ | This will start an animation on the tweens.rotate_sec property from 0 to 90. The animation will take 1s and will have an easing function of outQuad. | ||
+ | |||
+ | Any properties that you animate should be used by a watch layer using the tweens table, e.g. create a second hand in WatchMaker and set the rotation formula to tweens.rotate_sec | ||
+ | |||
+ | If you are animating scale, you are strongly recommended to **use the Anim Scale X and Anim Scale Y properties** instead of text size or radius. This will ensure much smoother animations. | ||
+ | |||
+ | The full options for WatchMaker scheduling is shown below : | ||
+ | tween -- name of tween variable, e.g. ' | ||
+ | from -- starting property value (numeric) | ||
+ | to -- ending property value (numeric) | ||
+ | duration | ||
+ | easing | ||
+ | start_offset | ||
+ | Schedule a sleep delay of e.g. 1s, which is useful for chaining animations : | ||
+ | wm_schedule | ||
+ | Schedule a Lua function to run (don't use quotes on your function name) : | ||
+ | wm_schedule | ||
+ | Chain animations together like this : | ||
+ | wm_schedule | ||
+ | { | ||
+ | { action=' | ||
+ | { action=' | ||
+ | { action=' | ||
+ | { action=' | ||
+ | } | ||
+ | ===== WatchMaker Lua API ===== | ||
+ | |||
+ | WatchMaker extends the Lua commandset. Just use the wm_action() or other functions anywhere in your script or tap actions: | ||
+ | |||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | wm_action(' | ||
+ | | ||
+ | wm_schedule(' | ||
+ | wm_unschedule_all() | ||
+ | wm_vibrate(d, | ||
+ | wm_sfx(' | ||
+ | wm_transition(' | ||
+ | wm_anim_set(' | ||
+ | wm_anim_set(' | ||
+ | wm_anim_start(' | ||
+ | wm_tag(' | ||
+ | return a value of a WatchMaker tag, e.g. wm_tag(" | ||
+ | is_bright | ||
+ | |||
+ | *About wm_action w_app | ||
+ | |||
+ | The delimiter for the app link is a backtick '' | ||
+ | |||
+ | * App name (may be empty) | ||
+ | * Package name | ||
+ | * Activity name (optional) | ||
+ | |||
+ | The app name is optional. If it is empty, the app main activity is launched. Example: '' | ||
+ | |||
+ | The easiest way to find the package name (example '' | ||
+ | |||
+ | Available activities of apps can be obtained by downloading the APK file and uploading it to https:// | ||
+ | |||
+ | ===== Tweening Functions ===== | ||
+ | |||
+ | Bring your animations to life using one of 45 tweening functions or even write your own function if needed. Remember not to use quotes in the {... easing=outQuad } | ||
+ | {{: | ||
+ | |||
+ | The full list is as follows : | ||
+ | linear | ||
+ | inQuad, outQuad, inOutQuad, outInQuad, | ||
+ | inCubic, outCubic, inOutCubic, outInCubic, | ||
+ | inQuart, outQuart, inOutQuart, outInQuart, | ||
+ | inQuint, outQuint, inOutQuint, outInQuint, | ||
+ | inSine, outSine, inOutSine, outInSine, | ||
+ | inExpo, outExpo, inOutExpo, outInExpo, | ||
+ | inCirc, outCirc, inOutCirc, outInCirc, | ||
+ | inElastic, outElastic, inOutElastic, | ||
+ | inBack, outBack, inOutBack, outInBack, | ||
+ | inBounce, outBounce, inOutBounce, | ||
+ | |||
+ | You can write your own tweening function like this : | ||
+ | |||
+ | function linear_myversion(d, | ||
+ | return c * t / d + b | ||
+ | end | ||
+ | | ||
+ | function inQuad_myversion(d, | ||
+ | t = t / d | ||
+ | return c * math.pow(t, 2) + b | ||
+ | end | ||
+ | | ||
+ | -- t = time == running time. How much time has passed *right now* | ||
+ | -- b = begin == starting property value | ||
+ | -- c = change == ending - beginning | ||
+ | -- d = duration == how much time has to pass for the tweening to complete | ||
+ | |||
+ | ===== Transitions ===== | ||
+ | |||
+ | From WatchMaker 3.6, you can run over 45 transitions when switching between screens on a watchface. | ||
+ | |||
+ | wm_transition(' | ||
+ | This will start a transition to the next screen. | ||
+ | |||
+ | Free Transitions Watch: http:// | ||
+ | |||
+ | See video of all transitions here: http:// | ||
+ | |||
+ | You should not use wm_transition for bright / dim animations - instead set the transition directly in WatchMaker watch editor. | ||
+ | |||
+ | The full list of transitions is shown below (you can add spaces if needed or use lower-case) : | ||
+ | None, Random, | ||
+ | FlipFromLeft, | ||
+ | ScrollFromLeft, | ||
+ | SlideFromLeft, | ||
+ | CrossHatch, CrossZoom, CubeFromLeft, | ||
+ | Dreamy, DreamyZoom, Fade, | ||
+ | FoldFromLeft, | ||
+ | GlitchDisplace, | ||
+ | SquareSwipe, | ||
+ | HSVFade, LinearBlur, RandomSquares, | ||
+ | PageCurl, Radial, PowerDisformation, | ||
+ | FadeBlack, FadeWhite, CircleOpen, | ||
+ | |||
+ | |||
+ | ===== Learn More ===== | ||
+ | |||
+ | You can learn more about how to use Lua from the many use cases listed on our [[tips: |
lua.txt · Last modified: 2025/04/12 07:47 by splitbrain