Advertisement
Guest User

dialog.wx.lua from wxLua samples

a guest
Oct 24th, 2012
628
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.92 KB | None | 0 0
  1. -------------------------------------------------------------------------=---
  2. -- Name:        dialog.wx.lua
  3. -- Purpose:     Dialog wxLua sample, a temperature converter
  4. --              Based on the C++ version by Marco Ghislanzoni
  5. -- Author:      J Winwood, John Labenski
  6. -- Created:     March 2002
  7. -- Copyright:   (c) 2001 Lomtick Software. All rights reserved.
  8. -- Licence:     wxWidgets licence
  9. -------------------------------------------------------------------------=---
  10.  
  11. -- Load the wxLua module, does nothing if running from wxLua, wxLuaFreeze, or wxLuaEdit
  12. package.cpath = package.cpath..";./?.dll;./?.so;../lib/?.so;../lib/vc_dll/?.dll;../lib/bcc_dll/?.dll;../lib/mingw_dll/?.dll;"
  13. require("wx")
  14.  
  15. -- IDs of the controls in the dialog
  16. ID_CELSIUS_BUTTON      = 1  -- NOTE: We use the fact that the textctrl ids
  17. ID_CELSIUS_TEXTCTRL    = 2  --       are +1 fom the button ids.
  18. ID_KELVIN_BUTTON       = 3
  19. ID_KELVIN_TEXTCTRL     = 4
  20. ID_FAHRENHEIT_BUTTON   = 5
  21. ID_FAHRENHEIT_TEXTCTRL = 6
  22. ID_RANKINE_BUTTON      = 7
  23. ID_RANKINE_TEXTCTRL    = 8
  24. ID_ABOUT_BUTTON        = 9
  25. ID_CLOSE_BUTTON        = 10
  26.  
  27. ID__MAX                = 11 -- max of our window ids
  28.  
  29. -- Create the dialog, there's no reason why we couldn't use a wxFrame and
  30. -- a frame would probably be a better choice.
  31. dialog = wx.wxDialog(wx.NULL, wx.wxID_ANY, "wxLua Temperature Converter",
  32.                      wx.wxDefaultPosition, wx.wxDefaultSize)
  33.  
  34. -- Create a wxPanel to contain all the buttons. It's a good idea to always
  35. -- create a single child window for top level windows (frames, dialogs) since
  36. -- by default the top level window will want to expand the child to fill the
  37. -- whole client area. The wxPanel also gives us keyboard navigation with TAB key.
  38. panel = wx.wxPanel(dialog, wx.wxID_ANY)
  39.  
  40. -- Layout all the buttons using wxSizers
  41. local mainSizer = wx.wxBoxSizer(wx.wxVERTICAL)
  42.  
  43. local staticBox      = wx.wxStaticBox(panel, wx.wxID_ANY, "Enter temperature")
  44. local staticBoxSizer = wx.wxStaticBoxSizer(staticBox, wx.wxVERTICAL)
  45. local flexGridSizer  = wx.wxFlexGridSizer( 0, 3, 0, 0 )
  46. flexGridSizer:AddGrowableCol(1, 0)
  47.  
  48. -- Make a function to reduce the amount of duplicate code.
  49. function AddConverterControl(name_string, button_text, textCtrlID, buttonID)
  50.     local staticText = wx.wxStaticText( panel, wx.wxID_ANY, name_string)
  51.     local textCtrl   = wx.wxTextCtrl( panel, textCtrlID, "00000.00000", wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxTE_PROCESS_ENTER )
  52.     local text_w, text_h = textCtrl:GetTextExtent("00000.00000")
  53.     textCtrl:SetInitialSize(wx.wxSize(text_w, -1))
  54.     local button     = wx.wxButton( panel, buttonID, button_text)
  55.     flexGridSizer:Add( staticText, 0, wx.wxALIGN_CENTER_VERTICAL+wx.wxALL, 5 )
  56.     flexGridSizer:Add( textCtrl,   0, wx.wxGROW+wx.wxALIGN_CENTER+wx.wxALL, 5 )
  57.     flexGridSizer:Add( button,     0, wx.wxGROW+wx.wxALIGN_CENTER+wx.wxALL, 5 )
  58.  
  59.     return textCtrl
  60. end
  61.  
  62. celsiusTextCtrl    = AddConverterControl("Celsius",    "From &Celsius",    ID_CELSIUS_TEXTCTRL,    ID_CELSIUS_BUTTON)
  63. kelvinTextCtrl     = AddConverterControl("Kelvin",     "From &Kelvin",     ID_KELVIN_TEXTCTRL,     ID_KELVIN_BUTTON)
  64. fahrenheitTextCtrl = AddConverterControl("Fahrenheit", "From &Fahrenheit", ID_FAHRENHEIT_TEXTCTRL, ID_FAHRENHEIT_BUTTON)
  65. rankineTextCtrl    = AddConverterControl("Rankine",    "From &Rankine",    ID_RANKINE_TEXTCTRL,    ID_RANKINE_BUTTON)
  66.  
  67. --[[
  68. NOTE: We've wrapped the creation of the controls into a function, but we could
  69.       have created them all separately this way.
  70.  
  71. local celsiusStaticText = wx.wxStaticText( panel, wx.wxID_ANY, "Celsius")
  72. local celsiusTextCtrl   = wx.wxTextCtrl( panel, ID_CELSIUS_TEXTCTRL, "", wx.wxDefaultPosition, wx.wxSize(80,-1), 0 )
  73. local celsiusButton     = wx.wxButton( panel, ID_CELSIUS_BUTTON, "C -> K && F")
  74. flexGridSizer:AddWindow( celsiusStaticText, 0, wx.wxALIGN_CENTER_VERTICAL+wx.wxALL, 5 )
  75. flexGridSizer:AddWindow( celsiusTextCtrl,   0, wx.wxGROW+wx.wxALIGN_CENTER+wx.wxALL, 5 )
  76. flexGridSizer:AddWindow( celsiusButton,     0, wx.wxALIGN_CENTER+wx.wxALL, 5 )
  77. ]]
  78.  
  79. staticBoxSizer:Add( flexGridSizer,  0, wx.wxGROW+wx.wxALIGN_CENTER+wx.wxALL, 5 )
  80. mainSizer:Add(      staticBoxSizer, 1, wx.wxGROW+wx.wxALIGN_CENTER+wx.wxALL, 5 )
  81.  
  82. local buttonSizer = wx.wxBoxSizer( wx.wxHORIZONTAL )
  83. local aboutButton = wx.wxButton( panel, ID_ABOUT_BUTTON, "&About")
  84. local closeButton = wx.wxButton( panel, ID_CLOSE_BUTTON, "E&xit")
  85. buttonSizer:Add( aboutButton, 0, wx.wxALIGN_CENTER+wx.wxALL, 5 )
  86. buttonSizer:Add( closeButton, 0, wx.wxALIGN_CENTER+wx.wxALL, 5 )
  87. mainSizer:Add(    buttonSizer, 0, wx.wxALIGN_CENTER+wx.wxALL, 5 )
  88.  
  89. panel:SetSizer( mainSizer )
  90. mainSizer:SetSizeHints( dialog )
  91.  
  92. -- ---------------------------------------------------------------------------
  93. -- Calculate the temp conversions, input only one temp, set others to nil
  94. --    Shows how to handle nil inputs and return multiple ones
  95. function ConvertTemp( Tc, Tk, Tf, Tr )
  96.     if Tc or Tk then
  97.         Tc = Tc or (Tk - 273.15)
  98.         Tf = (Tc * 9/5) + 32
  99.     else -- Tf or Tr
  100.         Tf = Tf or (Tr - 459.67)
  101.         Tc = (Tf - 32) * 5/9
  102.     end
  103.  
  104.     Tk = Tc + 273.15
  105.     Tr = Tf + 459.67
  106.  
  107.     return Tc, Tk, Tf, Tr
  108. end
  109.  
  110. -- ---------------------------------------------------------------------------
  111. -- Connect a handler for pressing enter in the textctrls
  112. dialog:Connect(wx.wxID_ANY, wx.wxEVT_COMMAND_TEXT_ENTER,
  113.     function(event)
  114.         -- Send "fake" button press to do calculation.
  115.         -- Button ids have been set to be -1 from textctrl ids.
  116.         dialog:ProcessEvent(wx.wxCommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, event:GetId()-1))
  117.     end)
  118.  
  119. -- ---------------------------------------------------------------------------
  120. -- Connect a central event handler that responds to all button clicks.
  121. -- NOTE: Since we Connect() the about and close buttons after this they will be
  122. --       called first and unless we call event:Skip() in their handlers the
  123. --       events will never reach this function. Therefore we don't need to
  124. --       check that the ids are only from temp conversion buttons.
  125.  
  126. dialog:Connect(wx.wxID_ANY, wx.wxEVT_COMMAND_BUTTON_CLICKED,
  127.     function(event)
  128.         -- NOTE: A wxID_CANCEL event is sent when the close button on the
  129.         -- dialog is pressed.
  130.         if event:GetId() >= ID__MAX then
  131.             event:Skip()
  132.             return
  133.         end
  134.  
  135.         -- We know that the textctrl window ids are +1 from the button ids
  136.         local T = tonumber(dialog:FindWindow(event:GetId()+1):DynamicCast("wxTextCtrl"):GetValue())
  137.  
  138.         if T == nil then
  139.             wx.wxMessageBox("The input temperature is invalid, enter a number.",
  140.                             "Error!",
  141.                             wx.wxOK + wx.wxICON_EXCLAMATION + wx.wxCENTRE,
  142.                             dialog)
  143.         else
  144.             -- Create a "case" type statement
  145.             local TempCase = {
  146.                 [ID_CELSIUS_BUTTON]    = function() return ConvertTemp(T, nil, nil, nil) end,
  147.                 [ID_KELVIN_BUTTON]     = function() return ConvertTemp(nil, T) end, -- don't need trailing nils
  148.                 [ID_FAHRENHEIT_BUTTON] = function() return ConvertTemp(nil, nil, T) end,
  149.                 [ID_RANKINE_BUTTON]    = function() return ConvertTemp(nil, nil, nil, T) end
  150.             }
  151.  
  152.             -- call the "case" statement
  153.             local Tc, Tk, Tf, Tr = TempCase[event:GetId()]()
  154.  
  155.             celsiusTextCtrl:SetValue(   string.format("%.3f", Tc))
  156.             kelvinTextCtrl:SetValue(    string.format("%.3f", Tk))
  157.             fahrenheitTextCtrl:SetValue(string.format("%.3f", Tf))
  158.             rankineTextCtrl:SetValue(   string.format("%.3f", Tr))
  159.         end
  160.     end)
  161.  
  162. --[[
  163. -- NOTE: You can also attach single event handlers to each of the buttons and
  164. --       handle them separately.
  165.  
  166. dialog:Connect(ID_CELSIUS_BUTTON, wx.wxEVT_COMMAND_BUTTON_CLICKED,
  167.     function(event)
  168.         local T = tonumber(celsiusTextCtrl:GetValue())
  169.         if T == nil then
  170.             wx.wxMessageBox("The Celsius temperature is invalid, enter a number.",
  171.                             "Error!",
  172.                             wx.wxOK + wx.wxICON_EXCLAMATION + wx.wxCENTRE,
  173.                             dialog)
  174.         else
  175.             kelvinTextCtrl:SetValue(T + 273.15)
  176.             fahrenheitTextCtrl:SetValue((T * 9 / 5) + 32)
  177.             rankineTextCtrl:SetValue((T * 9 / 5) + 32 + 459.67)
  178.         end
  179.     end)
  180. ]]
  181.  
  182. -- ---------------------------------------------------------------------------
  183. -- Attach an event handler to the Close button
  184. dialog:Connect(ID_CLOSE_BUTTON, wx.wxEVT_COMMAND_BUTTON_CLICKED,
  185.     function(event) dialog:Destroy() end)
  186.  
  187. dialog:Connect(wx.wxEVT_CLOSE_WINDOW,
  188.     function (event)
  189.         dialog:Destroy()
  190.         event:Skip()
  191.     end)
  192.  
  193. -- ---------------------------------------------------------------------------
  194. -- Attach an event handler to the About button
  195. dialog:Connect(ID_ABOUT_BUTTON, wx.wxEVT_COMMAND_BUTTON_CLICKED,
  196.     function(event)
  197.         wx.wxMessageBox("Based on the C++ version by Marco Ghislanzoni.\n"..
  198.                         wxlua.wxLUA_VERSION_STRING.." built with "..wx.wxVERSION_STRING,
  199.                         "About wxLua Temperature Converter",
  200.                         wx.wxOK + wx.wxICON_INFORMATION,
  201.                         dialog)
  202.     end)
  203.  
  204. -- ---------------------------------------------------------------------------
  205. -- Send a "fake" event to simulate a button press to update the textctrls
  206. dialog:ProcessEvent(wx.wxCommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, ID_CELSIUS_BUTTON))
  207.  
  208. -- ---------------------------------------------------------------------------
  209. -- Centre the dialog on the screen
  210. dialog:Centre()
  211. -- Show the dialog
  212. dialog:Show(true)
  213.  
  214. -- Call wx.wxGetApp():MainLoop() last to start the wxWidgets event loop,
  215. -- otherwise the wxLua program will exit immediately.
  216. -- Does nothing if running from wxLua, wxLuaFreeze, or wxLuaEdit since the
  217. -- MainLoop is already running or will be started by the C++ program.
  218. wx.wxGetApp():MainLoop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement