Celestia/Celx Scripting/Q&A/Assigning Custom Key Functions with CELX
With CELX it's easy to create custom key functions, and assign them to different keys on your keyboard. Here's how:
First, you create a Lua function using CELX to implement your custom function. In this example, we'll create a new key function which zooms the active view so that the currently selected object fills the view:
zoomToFit= function()
obs = celestia:getobserver()
obsPos = obs:getposition()
sel = celestia:getselection()
if sel == nil or sel:name() == "?" then return end
selPos = sel:getposition()
dist = obsPos:distanceto(selPos)
rad = sel:radius()
appDia = 2*math.atan(rad/dist)
obs:setfov(appDia*1.20)
celestia:flash("Zoom to fit "..sel:name(), 2)
end
Next, you create a table which maps a selected key to your new function. In this example, we'll use the "z" key:
keymap = {
z = zoomToFit
}
Then, you create a key handling function to call your new Lua function when the desired key is pressed, and assign it as the Celestia keyboard callback:
celestia_keyboard_callback = function(key)
f = keymap[key]
if f then
f()
return true
end
return false
end
Note that when there's a custom key definition for the input key, the callback returns true
to indicate to Celestia that no further processing of the key is needed. Otherwise it returns false
, and Celesta will handle the key according to the built-in key function assignments.
Finally, you tell Celestia that you want the callback to be called when a key is pressed, and then you wait for input:
celestia:requestkeyboard(true)
repeat
wait(10)
until false
Note that the script has an infinite loop, so you'll need to use the escape key to terminate it.
Once you've got the basic script, you can assign other new key functions simply by defining the Lua functions to implement them, and adding them to the key map.
Give it a try!
Download the script
[edit | edit source]Below you can find the whole script (without comments) in a single text block. Copy everything in the grey box and paste it into a text file in your favourite text editor, and save that file in your scripts directory as zoomtofit.celx. Then open it (File/Open Script) from within Celestia to see the script in action.
-- Zoom To Fit function script syntaxhighlight lang="text" zoomToFit= function() obs = celestia:getobserver() obsPos = obs:getposition() sel = celestia:getselection() if sel == nil or sel:name() == "?" then return end selPos = sel:getposition() dist = obsPos:distanceto(selPos) rad = sel:radius() appDia = 2*math.atan(rad/dist) obs:setfov(appDia*1.20) celestia:flash("Zoom to fit "..sel:name(), 2) end keymap = { z = zoomToFit } celestia_keyboard_callback = function(key) f = keymap[key] if f then f() return true end return false end celestia:requestkeyboard(true) repeat wait(10) until false
</syntaxhighlight>
Distinguishing upper from lower case
[edit | edit source]Unfortunately, the example above does not distinguish between the typing of upper case (capital) letters and lower case letters.
When Celestia calls the function celestia_keyboard_callback, the function's argument ("key" in this example) contains the letter that was typed. A simple string of IF statements can distinguish among them:
celestia_keyboard_callback = function(key)
if key == "F" then
zoomToFit()
return true
end
return false
end
This form of the callback calls the function zoomToFit if an upper-case F is typed, but lets Celestia handle all other letters, including lower-case f.