161 lines
5.7 KiB
Lua
161 lines
5.7 KiB
Lua
-------------------------------------------------------------------------=---
|
|
-- Name: coroutine.wx.lua
|
|
-- Purpose: Tests coroutines and wxIDLE_EVENTS
|
|
-- Author: Leandro Motta Barros
|
|
-- Created: 2006
|
|
-- Copyright:
|
|
-- Licence: wxWidgets licence
|
|
-------------------------------------------------------------------------=---
|
|
|
|
-- Load the wxLua module, does nothing if running from wxLua, wxLuaFreeze, or wxLuaEdit
|
|
package.cpath = package.cpath..";./?.dll;./?.so;../lib/?.so;../lib/vc_dll/?.dll;../lib/bcc_dll/?.dll;../lib/mingw_dll/?.dll;"
|
|
require("wx")
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- ProgressWindow
|
|
-------------------------------------------------------------------------------
|
|
|
|
ProgressWindow = {
|
|
-- The 'wxDialog' being encapsulated by this "class".
|
|
dialog = nil,
|
|
|
|
-- The label telling what's going on ("Processing 7/10...")
|
|
label = nil,
|
|
}
|
|
|
|
-- The constructor for the progress dialog.
|
|
-- 'parent' is the parent window.
|
|
-- 'workCoroutine' is the coroutine used to process whatever is desired.
|
|
-- 'caption' is the caption to be used for this window.
|
|
-- 'initialLabel' is the string that will be initially shown in the window.
|
|
function ProgressWindow:new(parent, workCoroutine, caption, initialLabel)
|
|
|
|
-- simple little sanity test to ensure that we can call binding functions
|
|
-- fails on r:SetX if wx bindings aren't installed correctly for the coroutine
|
|
local r = wx.wxRect(1,2,3,4)
|
|
r:SetX(1)
|
|
|
|
local o = { }
|
|
setmetatable(o, self)
|
|
self.__index = self
|
|
|
|
-- Check input parameters
|
|
assert(type(workCoroutine) == "thread")
|
|
assert(type(caption) == "string")
|
|
assert(type(initialLabel) == "string")
|
|
|
|
-- Create dialog
|
|
o.dialog = wx.wxDialog(parent, wx.wxID_ANY, caption,
|
|
wx.wxDefaultPosition, wx.wxDefaultSize,
|
|
wx.wxDEFAULT_DIALOG_STYLE)
|
|
|
|
o.label = wx.wxTextCtrl(o.dialog, wx.wxID_ANY, "",
|
|
wx.wxDefaultPosition, wx.wxDefaultSize,
|
|
wx.wxTE_MULTILINE + wx.wxTE_READONLY)
|
|
local mainSizer = wx.wxBoxSizer(wx.wxVERTICAL)
|
|
mainSizer:Add(o.label, 1, wx.wxGROW)
|
|
o.dialog:SetSizer(mainSizer)
|
|
|
|
-- Handle idle events: run the coroutine's next "step"
|
|
o.dialog:Connect(wx.wxEVT_IDLE,
|
|
function (event)
|
|
if coroutine.status(workCoroutine) ~= "dead" then
|
|
local s, msg = coroutine.resume(workCoroutine)
|
|
if not msg then
|
|
o.dialog:Close()
|
|
else
|
|
o:setStatus(msg)
|
|
end
|
|
event:RequestMore()
|
|
event:Skip()
|
|
end
|
|
end)
|
|
|
|
-- Voilà
|
|
return o
|
|
end
|
|
|
|
|
|
-- Sets the ProgressWindow's "status". For now, this means "change the text"
|
|
-- being displayed in the window (usually something like "Doing this thing").
|
|
function ProgressWindow:setStatus(label)
|
|
self.label:AppendText("\n"..label)
|
|
end
|
|
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- The main frame
|
|
-------------------------------------------------------------------------------
|
|
|
|
local ID_THE_BUTTON = wx.wxID_HIGHEST + 100
|
|
|
|
frame = wx.wxFrame(wx.NULL, wx.wxID_ANY,
|
|
"wxLua Idle Events and Coroutines")
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
-- create a simple file menu
|
|
local fileMenu = wx.wxMenu()
|
|
fileMenu:Append(wx.wxID_EXIT, "E&xit", "Quit the program")
|
|
|
|
-- create a simple help menu
|
|
local helpMenu = wx.wxMenu()
|
|
helpMenu:Append(wx.wxID_ABOUT, "&About", "About the wxLua Coroutine Sample")
|
|
|
|
-- create a menu bar and append the file and help menus
|
|
local menuBar = wx.wxMenuBar()
|
|
menuBar:Append(fileMenu, "&File")
|
|
menuBar:Append(helpMenu, "&Help")
|
|
|
|
-- attach the menu bar into the frame
|
|
frame:SetMenuBar(menuBar)
|
|
|
|
-- connect the selection event of the exit menu item to an
|
|
-- event handler that closes the window
|
|
frame:Connect(wx.wxID_EXIT, wx.wxEVT_COMMAND_MENU_SELECTED,
|
|
function (event) frame:Close(true) end )
|
|
|
|
-- connect the selection event of the about menu item
|
|
frame:Connect(wx.wxID_ABOUT, wx.wxEVT_COMMAND_MENU_SELECTED,
|
|
function (event)
|
|
wx.wxMessageBox('This is the "About" dialog of the Coroutine wxLua sample.\n'..
|
|
wxlua.wxLUA_VERSION_STRING.." built with "..wx.wxVERSION_STRING,
|
|
"About wxLua",
|
|
wx.wxOK + wx.wxICON_INFORMATION,
|
|
frame)
|
|
end )
|
|
|
|
-- ----------------------------------------------------------------------------
|
|
|
|
panel = wx.wxPanel(frame, wx.wxID_ANY)
|
|
button = wx.wxButton(panel, ID_THE_BUTTON, "Perform some long operation")
|
|
|
|
frame:Connect(ID_THE_BUTTON, wx.wxEVT_COMMAND_BUTTON_CLICKED,
|
|
function (event)
|
|
local function workFunc()
|
|
for i = 1, 10 do
|
|
coroutine.yield("Performing step "..tostring(i).."/10")
|
|
wx.wxSleep(1)
|
|
end
|
|
end
|
|
|
|
local workCoroutine = coroutine.create(workFunc)
|
|
|
|
local wndProgress =
|
|
ProgressWindow:new(frame, workCoroutine,
|
|
"Performing some long operation",
|
|
"Performing step 1/many")
|
|
wndProgress.dialog:ShowModal(true)
|
|
|
|
wndProgress.dialog:Destroy()
|
|
end)
|
|
|
|
|
|
-- Show the main frame
|
|
frame:Show(true)
|
|
|
|
-- Call wx.wxGetApp():MainLoop() last to start the wxWidgets event loop,
|
|
-- otherwise the wxLua program will exit immediately.
|
|
-- Does nothing if running from wxLua, wxLuaFreeze, or wxLuaEdit since the
|
|
-- MainLoop is already running or will be started by the C++ program.
|
|
wx.wxGetApp():MainLoop()
|