Application with Popup - WIN
Dialog windows are commonly used for specific actions and/or getting
information from the user. The popupFrame window is a modal state
window. The frame window it is created from (the owner frame) is
disabled and the threads code halts, so the user must respond to the
popup before continuing. The following introduces a popupFrame
window to our program defined as a class derived from popupFrame. It
takes a string from the user and sets it as the application's title
text.
-- collect any program arguments
local app_args = { ... }
-- create the application's main frame
local appFrame = win.create_app_frame ()
local APP_TITLE = "Popup"
-- ids should be between 1 - 65535
-- control ids
local ID_MENUBTN = 101
local ID_SETTITLEBTN = 102
-- popup ids
local ID_TITLETEXT = 201
local ID_OK = 202
-- command ids
local IDM_ONE = 1001
local IDM_TWO = 1002
local IDM_THREE = 1003
local IDM_QUITAPP = 1004
-- unique id for app frame
local ID_MYAPP_FRAME = 32174
-- myPopup class -------------------------------------------------------
local myPopup = win.popupFrame:base ()
-- return false on failure
function myPopup:on_create ()
self:dress ("Set Title")
local inputWnd = win.inputWindow:new (self, ID_TITLETEXT, 1, 2, 14,
self:get_owner ():get_text (), "Title")
inputWnd:set_sel (0, -1)
inputWnd:set_focus ()
win.buttonWindow:new (self, ID_OK, 11, 4, " Ok ")
self:move (nil, nil, 16, 6)
return true
end
-- handles events for myPopup
function myPopup:on_event (event, p1, p2, p3, p4, p5, ...)
if event == "btn_click" then
if p1:get_id () == ID_OK then
local titleText = APP_TITLE
local titleWnd = self:get_wnd_by_id (ID_TITLETEXT)
if titleWnd then
if string.len (titleWnd:get_text ()) > 0 then
titleText = titleWnd:get_text ()
end
end
self:get_owner ():set_title (titleText)
self:close (ID_OK)
return true
end
end
return false
end
-- end myPopup class ---------------------------------------------------
-- handle control, wanted and custom events
function appFrame:on_event (event, p1, p2, p3, p4, p5, ...)
-- handle events and return true
if event == "btn_click" then
if p1:get_id () == ID_MENUBTN then
self:on_menu ()
return true
end
-- run popup on btn click
if p1:get_id () == ID_SETTITLEBTN then
myPopup:new (self):do_modal ()
return true
end
elseif event == "menu_cmd" then
return self:on_command (p1)
end
return false
end
-- if needed, low priority, called about every 1/3 second
-- when nothing happening - but keep it brief
function appFrame:on_idle (idle_count)
return false
end
-- if needed
function appFrame:on_alarm (alarm_id)
return false
end
-- if needed
function appFrame:on_timer (timer_id)
return false
end
-- to reposition control windows, app frames should only
-- move if monitor device changes size/resolution or
-- fullscreen mode changes
function appFrame:on_move ()
return false
end
-- for clean up, if needed
function appFrame:on_destroy_wnd ()
end
-- to implement accelerator keys. best to use with combo keys
-- to try and avoid char event following to child
function appFrame:on_child_key (wnd, key, ctrl, alt, shift)
-- base implements tab key navigation
if win.applicationFrame.on_child_key (self, wnd, key, ctrl, alt, shift) then
return true
end
-- return true if handled so child does not receive key event
-- accelerators to menu commands
if ctrl and not alt and not shift then
if key == keys.KEY_1 then
return self:on_command (IDM_ONE)
end
if key == keys.KEY_2 then
return self:on_command (IDM_TWO)
end
if key == keys.KEY_3 then
return self:on_command (IDM_THREE)
end
end
return false
end
-- called when app becomes and stops being the active app
function appFrame:on_frame_activate (active)
end
-- called when app is quitting
function appFrame:on_quit ()
-- return true to stop app from quitting
return false
end
-- method to create and display menu
function appFrame:on_menu ()
local menu = win.menuWindow:new (self)
menu:add_string ("One Ctrl+1", IDM_ONE)
menu:add_string ("Two Ctrl+2", IDM_TWO)
menu:add_string ("Three Ctrl+3", IDM_THREE)
menu:add_string ("------------")
menu:add_string ("Quit App", IDM_QUITAPP)
menu:track (0, 1)
end
-- command handler
function appFrame:on_command (cmd_id)
if cmd_id == IDM_ONE then
self:msgbox ("Menu Command", "Application message box.")
return true
end
if cmd_id == IDM_TWO then
self:msgbox ("Menu Command",
"Application message box with custom color.",
term.colors.sky)
return true
end
if cmd_id == IDM_THREE then
self:get_desktop ():msgbox ("Menu Command",
"System message box with custom color.",
term.colors.red)
return true
end
if cmd_id == IDM_QUITAPP then
self:quit_app ()
return true
end
return false
end
function appFrame:on_create ()
-- single instance, look for existing frame
local instance = self:get_desktop ():get_wnd_by_id (ID_MYAPP_FRAME, false)
-- if found
if instance then
-- bring running instance to top
instance:set_active_top_frame ()
-- and drop out
return false
end
-- not found, change frame id to ID_MYAPP_FRAME
self:set_id (ID_MYAPP_FRAME)
-- add title bar and close btn, close btn will have focus
-- frame wnd text displays in running app list
self:dress (APP_TITLE)
-- create menu button on title bar
local menu_btn = win.buttonWindow:new (self, ID_MENUBTN, 0, 0, "Menu")
-- customise to blend into title bar
menu_btn:set_colors (menu_btn:get_colors ().frame_text,
menu_btn:get_colors ().title_back,
menu_btn:get_colors ().frame_back)
-- move on top of title bar text so wont get obscured
menu_btn:move (nil, nil, nil, nil, win.WND_TOP)
-- create controls, usually setting focus to first
win.buttonWindow:new (self, ID_SETTITLEBTN, 2, 3, " Set Title "):set_focus ()
-- app is constructed, bring it to top
self:set_active_top_frame ()
return true
end
-- run the application's loop
appFrame:run_app ()
See Application
Writing, WIN.