Luce
Luce - a GUI module for Lua based on JUCE
Install / Use
/learn @peersuasive/LuceREADME
==== Luce
A GUI Module for Lua (based on JUCE)
.. image:: http://peersuasive.github.io/images/lua-inside.png
Luce 0.3.4 sometimes, it won't fail released ! <https://github.com/peersuasive/luce/releases/tag/v0.3.4>__
Downloads_ for Linux, Windows, OS X, iOS and Android are available.
What is Luce ?
Luce is a Lua <http://lua.org>_ module for GUI programming based
on the portable, embeddable, remarkable C++ library JUCE <http://www.juce.com>_.
It can be used as an ordinary module for pure lua 5.1/lua 5.2/luajit 2.X scripts or as a library for C++/Lua projects.
Although based on JUCE, Luce isn't aiming at becoming a binding for JUCE, though the low level API free of Luce features could be used as such.
Luce has Lua in mind and will be developped for lua developpers.
Lua essence is to be "a powerfull, fast, lightweight embeddable scripting language." And so would Luce be too.
Luce is light, fast and easily portable <https://github.com/peersuasive/luce_embeddable>_, thanks to Lua and JUCE
itself.
As of now, it's supported on Linux, Windows and Mac OS X, with partial support for iOS and Android.
Getting started
-
download_ the lua module for your environment -
put it somewhere in your lua modules path (ex:
/usr/local/share/lua/5.1)
-
if you're on Linux, you can also use the provided luarock:
Check the
requirements_, then:for lua 5.1::
~$ luarocks install https://github.com/peersuasive/luce/raw/master/luce-scm-0.rockspec
for lua 5.2::
~$ luarocks install https://github.com/peersuasive/luce/raw/master/luce-scm52-0.rockspec
for lua 5.3::
~$ luarocks install https://github.com/peersuasive/luce/raw/master/luce-scm53-0.rockspec
-
if you don't know JUCE, you should consider having a look at its
documentation <https://www.juce.com/api/annotated.html>__ as Luce low level API matches for the most part JUCE's own API.For more explanations, see
Differences with JUCE_ andLuce design_
A first app: say hello
.. code:: lua
local title = "Hello World!"
local app, luce = require"luce.LApplication"(title, ...) -- create a basic Application
-- with command line parameters
local timer = luce:Timer() -- a timer for the animation
local function MainWindow(args) -- our main component class
-- will receive command line arguments or starting events
local app, luce = app, luce -- just to put these in the local environment
local Colours = luce.Colours -- id.
local wsize = {800,600} -- the size of our window
local isPaused = false -- holds the animation state
local mc = luce:MainComponent("MainComponent") -- our main component
local documentWindow = luce:Document(title) -- create a document window to hold the main component
local button = luce:TextButton("quit") -- a button to close the app
button.buttonText = "Quit" -- visible text of the button
button:setLookAndFeel(4) -- change look-and-feel
button.bounds = { 10, 10, 100, 20 } -- and position it (x,y,w,h)
---
-- set some action on button click
---
button:buttonClicked(function()
app:quit()
end)
---
-- say hello to the world with a simple animation
---
-- just a dumb function to increase font size and pick a predefined colour
local currentSize, baseSize, maxSize = 12.0, 12.0, 32.0
local colours = { Colours.black, Colours.red, Colours.yellow, Colours.green, Colours.blue }
local currentCol = 1
local function changeSize()
currentSize = (currentSize<maxSize) and currentSize+0.5 or baseSize
currentCol = (currentCol>=#colours) and 1 or currentCol+1
return currentSize, colours[currentCol]
end
-- draw the message
mc:paint(function(g)
-- draw a background
g:fillCheckerBoard( luce:Rectangle(mc:getBounds()), 48, 48, Colours.lightgrey, Colours.white)
-- get new font size and colour
local size, colour = changeSize()
-- draw text
g:setFont(size)
g:setColour(luce:Colour(colour))
g:drawText("Hello World!", mc:getLocalBounds(), luce.JustificationType.centred, true);
end)
-- animate it a bit via the timer callback
timer:timerCallback(function()
if(mc:isShowing() and not(isPaused))then
mc:repaint()
end
end)
timer:startTimer (1000/60)
---
-- add some key shortcuts
---
local K = string.byte
local kc = setmetatable(
luce.KeyPress.KeyCodes, { __index = function()return 0 end } ) -- just a little trick to always get a valid keycode
-- see https://www.juce.com/api/classKeyPress.html for
-- available key-codes
documentWindow:keyPressed(function(k)
local k, m = k:getKeyCode(), k:getModifiers() -- get current key-code and modifiers status
if (k==K"Q" or k==K"q")
and (m:isCommandDown() or not(app.os.osx)) then -- if Q is pressed or, on OS X, cmd+Q
app:exit(0) -- close the application with an normal exit state (0 by default)
elseif (k==K"w" or k==K"W") and (m:isCommandDown() ) then -- if cmd/ctrl + W is pressed
documentWindow:closeWindow() -- close the window
-- on Linux and Windows, this has the effect of closing the application too,
-- but on OS X, only the active window is closed by default
-- however, if true is passed to closeWindow()
-- and this is the last remaining Document
-- the app will close the window and quit the application
elseif (k==kc.spaceKey) then
-- toggle rendering pause
isPaused = not(isPaused)
else
return false -- don't consume key
-- returning false, nil or not returning anything
-- has the same effect
end
return true -- tell the OS we have consumed this key
end)
---
-- add all components and display
---
mc:setSize(wsize)
mc:addAndMakeVisible(button) -- add the component to our main component
documentWindow:setContentOwned( mc, true ) -- add the main component to the document window
---
documentWindow:closeButtonPressed(function() -- the user asked to close the current window...
documentWindow:closeWindow() -- so let's close it our way
-- if this action's not taken, it'll close the app by default
end)
documentWindow:setSize(wsize) -- set dimensions for the window
-- on iOS and Android, it'll just set a fullscreen
documentWindow:setVisible(true) -- display the document
return documentWindow -- return it for the application to actually display it
end
local manual = false -- set true if you want to add your own process running along with the main loop
local osx_delayed = false -- set true if you don't want your app to display a window immediatly on OS X
-- but wait for user input before, like providing a file,...
local poller = function() -- the callback you want to run in manual mode
print "I'm in a loop!"
end
return app:start( MainWindow, manual and {poller,100}, osx_delayed ) -- returns the exit state
A more complete example using only the low level API
.. code:: lua
local luce = require"luce"()
---
--- create a default JUCEApplication
---
local mainWindow = luce:JUCEApplication("My App")
---
--- create a DocumentWindow with name "Document Window"
---
local dw = luce:DocumentWindow("Document Window")
-- rename it
dw.name = "Luce Example Application"
---
--- create a MainComponent, to be hosted by the Document Window
---
local mc = luce:MainComponent("The Main Component")
---
--- create a button named "TheButton" with text "a button"
---
local button = luce:TextButton("TheButton")
button:setButtonText( "a button" ) -- or button.buttonText = "a button", like button2 below
--- add a callback for when button is clicked
button:buttonClicked(function(...)
print("button clicked !!")
end)
--- change component look and feel
local button2 = luce:TextButton("TheButton2")
button2.buttonText = "button with a different look and feel"
--- add a callback for when button is clicked
button2:buttonClicked(function(...)
print("button 2 clicked !!")
end)
--- set a different look and feel for button2
button2:setLookAndFeel(3)
---
--- create a Label
---
local label = luce:Label("A Label")
--- Label's setText has an optional parameter to send a notification when its content's changed
--- by default, it sends nothing:
label.text = "a bit of content" -- default to dontSendNotification
--- set a callback for label text ch
Related Skills
node-connect
343.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
90.0kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
343.1kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
343.1kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
