# Copyright (c) 2023 M.J.N. Corino, The Netherlands # # This software is released under the MIT license. # # Some parts are # Copyright 2004-2007, wxRuby development team # released under the MIT-like wxRuby2 license # Adapted for wxRuby3 ### require 'wx' module Dialogs DIALOGS_CHOOSE_COLOUR = 1 DIALOGS_CHOOSE_COLOUR_GENERIC = 2 DIALOGS_CHOOSE_FONT = 3 DIALOGS_CHOOSE_FONT_GENERIC = 4 DIALOGS_MESSAGE_BOX = 5 DIALOGS_SINGLE_CHOICE = 6 DIALOGS_MULTI_CHOICE = 7 DIALOGS_TEXT_ENTRY = 8 DIALOGS_PASSWORD_ENTRY = 9 DIALOGS_FILE_OPEN = 10 DIALOGS_FILE_OPEN2 = 11 DIALOGS_FILES_OPEN = 12 DIALOGS_FILE_SAVE = 13 DIALOGS_DIR_CHOOSE = 14 DIALOGS_GENERIC_DIR_CHOOSE = 15 DIALOGS_TIP = 16 DIALOGS_CUSTOM_TIP = 17 DIALOGS_NUM_ENTRY = 18 DIALOGS_LOG_DIALOG = 19 DIALOGS_MODAL = 20 DIALOGS_MODELESS = 21 DIALOGS_MODELESS_BTN = 22 DIALOGS_PROGRESS = 23 DIALOGS_BUSYINFO = 24 DIALOGS_STYLED_BUSYINFO = 25 DIALOGS_FIND = 26 DIALOGS_REPLACE = 27 DIALOGS_PREFS = 28 DIALOGS_PREFS_TOOLBOOK = 29 class MyTipProvider < Wx::TipProvider TIPS = [ %Q{This is the first tip.}, %Q{This is the second tip.\nWhich even has a second line.}, %Q{This is the third tip.\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.}, ] def initialize(curtip) super end def get_tip c = get_current_tip if c >= 0 && c < TIPS.size set_current_tip(c+1) TIPS[c] else set_current_tip(1) TIPS[0] end end end class MyModalDialog < Wx::Dialog def initialize(parent) super(parent, -1, "Modal dialog") sizer_top = Wx::BoxSizer.new(Wx::HORIZONTAL) @btn_focused = Wx::Button.new(self, -1, "Default button") @btn_delete = Wx::Button.new(self, -1, "&Delete button") btn_ok = Wx::Button.new(self, Wx::ID_CANCEL, "&Close") sizer_top.add(@btn_focused, 0, Wx::ALIGN_CENTER | Wx::ALL, 5) sizer_top.add(@btn_delete, 0, Wx::ALIGN_CENTER | Wx::ALL, 5) sizer_top.add(btn_ok, 0, Wx::ALIGN_CENTER | Wx::ALL, 5) set_auto_layout(true) set_sizer(sizer_top) sizer_top.set_size_hints(self) sizer_top.fit(self) @btn_focused.set_focus @btn_focused.set_default evt_button(-1) {|event| on_button(event) } end def on_button(event) id = event.get_id if id == @btn_delete.get_id @btn_focused.destroy @btn_focused = nil @btn_delete.disable elsif @btn_focused && id == @btn_focused.get_id get_text_from_user("Dummy prompt", "Modal dialog called from dialog", "", self) else event.skip end end end class MyModelessDialog < Wx::Dialog def initialize(parent) super(parent, -1, "Modeless dialog") sizer_top = Wx::BoxSizer.new(Wx::VERTICAL) btn = Wx::Button.new(self, DIALOGS_MODELESS_BTN, "Press me") check = Wx::CheckBox.new(self, -1, "Should be disabled") check.disable sizer_top.add(btn, 1, Wx::EXPAND | Wx::ALL, 5) sizer_top.add(check, 1, Wx::EXPAND | Wx::ALL, 5) set_auto_layout(true) set_sizer(sizer_top) sizer_top.set_size_hints(self) sizer_top.fit(self) evt_button(DIALOGS_MODELESS_BTN) {|event| on_button(event) } evt_close {|event| on_close(event) } end def on_button(_event) Wx.message_box("Button pressed in modeless dialog", "Info", Wx::OK | Wx::ICON_INFORMATION, self) end def on_close(event) if event.can_veto Wx.message_box("Use the menu item to close self dialog", "Modeless dialog", Wx::OK | Wx::ICON_INFORMATION, self) event.veto end end end # PropertySheetDialog is specialised for doing preferences dialogs; it # contains a BookCtrl of some sort class MyPrefsDialog < Wx::PropertySheetDialog def initialize(parent, pref_type) # Using Book type other than Notebook needs two-step construction super() img_id1 = img_id2 = -1 if pref_type == DIALOGS_PREFS_TOOLBOOK self.sheet_style = Wx::PROPSHEET_BUTTONTOOLBOOK self.sheet_outer_border = 1 self.sheet_inner_border = 2 imgs = [std_bitmap(Wx::ART_NORMAL_FILE), std_bitmap(Wx::ART_CDROM), std_bitmap(Wx::ART_REPORT_VIEW)] img_id1 = 0 img_id2 = 1 end create(parent, -1, "Preferences") create_buttons(Wx::ID_OK|Wx::ID_CANCEL) book_ctrl.set_images(imgs) book_ctrl.add_page(file_panel(book_ctrl), "File", false, img_id1) book_ctrl.add_page(cdrom_panel(book_ctrl), "CD ROM", false, img_id2) layout_dialog end # Gets one of the rather ugly standard bitmaps from ArtProvider def std_bitmap(art_id) Wx::BitmapBundle.new(Wx::ArtProvider.bitmap(art_id, Wx::ART_TOOLBAR, [32, 32])) end def file_panel(book) panel = Wx::Panel.new(book) panel.sizer = Wx::VBoxSizer.new cb1 = Wx::CheckBox.new(panel, :label => 'Show hidden files') panel.sizer.add(cb1, 0, Wx::ALL, 5) cb2 = Wx::CheckBox.new(panel, :label => 'Always show extensions') panel.sizer.add(cb2, 0, Wx::ALL, 5) cb3 = Wx::CheckBox.new(panel, :label => 'Show icons') panel.sizer.add(cb3, 0, Wx::ALL, 5) cb4 = Wx::CheckBox.new(panel, :label => 'Show owner') panel.sizer.add(cb4, 0, Wx::ALL, 5) st = Wx::StaticText.new(panel, :label => "Sort by:") panel.sizer.add(st, 0, Wx::ALL, 5) cb1 = Wx::Choice.new(panel, :choices => %w|Name Created Modified Size|) panel.sizer.add(cb1, 0, Wx::ALL, 5) panel end def cdrom_panel(book) panel = Wx::Panel.new(book) panel.sizer = Wx::VBoxSizer.new choices = [ 'Show files', 'Play media', 'Run CD', 'Do nothing' ] rb = Wx::RadioBox.new( panel, :label => 'When opening CD', :choices => choices, :major_dimension => 1) panel.sizer.add(rb, 0, Wx::GROW|Wx::ALL, 5) panel end end class MyCanvas < Wx::ScrolledWindow def initialize(parent) super(parent, -1, Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE, Wx::NO_FULL_REPAINT_ON_RESIZE) evt_paint { |event| on_paint(event) } end def clear end def on_paint(_event) paint do |dc| dc.set_text_foreground( Wx.get_app.canvas_text_colour ) dc.set_font( Wx.get_app.canvas_font ) dc.draw_text("Windows common dialogs test application", 10, 10) end end end class MyFrame < Wx::Frame def initialize(parent, title, pos, size) super(parent, -1, title, pos, size) @dialog = nil @dlg_find = nil @dlg_replace = nil @find_data = Wx::FindReplaceData.new @ext_def = "" @index = -1 @index_2 = -1 @max = 100 create_status_bar evt_menu(DIALOGS_CHOOSE_COLOUR, :on_choose_colour) evt_menu(DIALOGS_CHOOSE_FONT, :on_choose_font) evt_menu(DIALOGS_LOG_DIALOG, :on_log_dialog) evt_menu(DIALOGS_MESSAGE_BOX, :on_message_box) evt_menu(DIALOGS_TEXT_ENTRY, :on_text_entry) evt_menu(DIALOGS_PASSWORD_ENTRY, :on_password_entry) evt_menu(DIALOGS_NUM_ENTRY, :on_numeric_entry) evt_menu(DIALOGS_SINGLE_CHOICE, :on_single_choice) evt_menu(DIALOGS_MULTI_CHOICE, :on_multi_choice) evt_menu(DIALOGS_FILE_OPEN, :on_file_open) evt_menu(DIALOGS_FILE_OPEN2, :on_file_open2) evt_menu(DIALOGS_FILES_OPEN, :on_files_open) evt_menu(DIALOGS_FILE_SAVE, :on_file_save) evt_menu(DIALOGS_DIR_CHOOSE, :on_dir_choose) evt_menu(DIALOGS_MODAL, :on_modal_dlg) evt_menu(DIALOGS_MODELESS, :on_modeless_dlg) evt_menu(DIALOGS_TIP, :on_show_tip) evt_menu(DIALOGS_CUSTOM_TIP, :on_show_custom_tip) evt_menu(DIALOGS_PROGRESS, :on_show_progress) evt_menu(DIALOGS_BUSYINFO, :on_show_busy_info) evt_menu(DIALOGS_STYLED_BUSYINFO, :on_show_styled_busy_info) evt_menu(DIALOGS_PREFS, :on_show_prefs) evt_menu(DIALOGS_PREFS_TOOLBOOK,:on_show_prefs) evt_menu(DIALOGS_FIND, :on_show_find_dialog) evt_menu(DIALOGS_REPLACE, :on_show_replace_dialog) evt_find(-1, :on_find_dialog) evt_find_next(-1, :on_find_dialog) evt_find_replace(-1, :on_find_dialog) evt_find_replace_all(-1, :on_find_dialog) evt_find_close(-1, :on_find_dialog) evt_menu(Wx::ID_EXIT, :on_exit) end def on_choose_colour(_event) col = MyApp.canvas.get_background_colour data = Wx::ColourData.new data.set_colour(col) data.set_choose_full(true) 16.times do |i| colour = Wx::Colour.new(i*16, i*16, i*16) data.set_custom_colour(i, colour) end Wx.ColourDialog(self, data) do |dialog| dialog.set_title("Choose the background colour (not OS X)") if dialog.show_modal == Wx::ID_OK retData = dialog.get_colour_data col = retData.get_colour MyApp.canvas.set_background_colour(col) #$my_canvas.clear MyApp.canvas.refresh end end end def on_choose_font(_event) data = Wx::FontData.new data.set_initial_font(Wx::get_app.canvas_font) data.set_colour(Wx::get_app.canvas_text_colour) Wx::FontDialog(self, data) do |dialog| if dialog.show_modal == Wx::ID_OK ret_data = dialog.get_font_data Wx::get_app.canvas_font = ret_data.get_chosen_font Wx::get_app.canvas_text_colour = ret_data.get_colour font = ret_data.get_chosen_font msg = "Font = %s, %i pt" % [ font.get_face_name, font.get_point_size ] # Using functors is not mandatory but to prevent memory leaks # you MUST destroy the dialog yourself than at some point dialog2 = Wx::MessageDialog.new(self, msg, "Got font") dialog2.show_modal dialog2.destroy end #else: cancelled by the user, don't change the font end end def on_log_dialog(_event) # calling yield (as ~BusyCursor does) shouldn't result in messages # being flushed -- test it Wx::BusyCursor.busy do Wx.log_message("This is some message - everything is ok so far.") Wx.log_message("Another message...\n... self one is on multiple lines") Wx.log_warning("And then something went wrong!") # and if ~BusyCursor doesn't do it, then call it manually Wx::get_app.yield Wx.log_error("Intermediary error handler decided to abort.") Wx.log_error("DEMO: The top level caller detected an unrecoverable error.") Wx::Log.flush_active Wx.log_message("And this is the same dialog but with only one message.") end end def on_message_box(_event) Wx.MessageDialog(nil, "This is a message box\nA long, long string to test out the message box properly", "Message box text", Wx::NO_DEFAULT|Wx::YES_NO|Wx::CANCEL|Wx::ICON_INFORMATION) do |dialog| case dialog.show_modal when Wx::ID_YES Wx.log_status("You pressed \"Yes\"") when Wx::ID_NO Wx.log_status("You pressed \"No\"") when Wx::ID_CANCEL Wx.log_status("You pressed \"Cancel\"") else Wx.log_error("Unexpected MessageDialog return code!") end end end def on_numeric_entry(_event) res = Wx.get_number_from_user( "This is some text, actually a lot of text.\n" + "Even two rows of text.", "Enter a number:", "Numeric input test", 50, 0, 100, self ) if res == -1 msg = "Invalid number entered or dialog cancelled." icon = Wx::ICON_HAND else msg = sprintf("You've entered %d", res ) icon = Wx::ICON_INFORMATION end Wx.message_box(msg, "Numeric test result", Wx::OK | icon, self) end def on_password_entry(_event) pwd = Wx.get_password_from_user("Enter password:", "Password entry dialog", "", self) if pwd Wx.message_box(sprintf("Your password is '%s'", pwd), "Got password", Wx::OK | Wx::ICON_INFORMATION, self) end end def on_text_entry(_event) Wx.TextEntryDialog(self, "This is a small sample\n" + "A long, long string to test out the text entrybox", "Please enter a string", "Default value", Wx::OK | Wx::CANCEL) do |dialog| if dialog.show_modal == Wx::ID_OK dialog2 = Wx::MessageDialog.new(self, dialog.get_value, "Got string") dialog2.show_modal dialog2.destroy end end end def on_single_choice(_event) choices = %w[One Two Three Four Five] Wx.SingleChoiceDialog(self, "This is a small sample\n" + "A single-choice convenience dialog", "Please select a value", choices, Wx::OK | Wx::CANCEL) do |dialog| dialog.set_selection(2) if dialog.show_modal == Wx::ID_OK Wx.MessageDialog(self, dialog.get_string_selection, "Got string") end end end def on_multi_choice(_event) choices = %w[One Two Three Four Five Six Seven Eight Nine Ten Eleven Twelve Seventeen] Wx.MultiChoiceDialog(self, "This is a small sample\n" + "A multi-choice convenience dialog", "Please select a value", choices, Wx::OK | Wx::CANCEL) do |dialog| if dialog.show_modal == Wx::ID_OK selections = dialog.get_selections if selections msg = ("You selected %d items:\n" % selections.length) + selections.length.times.collect { |n| "\t%d: %d (%s)\n" % [n, selections[n], choices[selections[n]]] }.join Wx.log_message(msg) end end end end def on_file_open(_event) Wx.FileDialog(self, "Testing open file dialog", "", "", "C++ files (*.h;*.cpp)|*.h;*.cpp") do |dialog| dialog.set_directory(Wx.get_home_dir) if dialog.show_modal == Wx::ID_OK info = sprintf("Full file name: %s\n" + "Path: %s\n" + "Name: %s", dialog.get_path, dialog.get_directory, dialog.get_filename) Wx.MessageDialog(self, info, "Selected file") end end end # this shows how to take advantage of specifying a default extension in the # call to FileSelector: it is remembered after each new call and the next # one will use it by default def on_file_open2(_event) path = Wx.file_selector( "Select the file to load", "", "", @ext_def, "Waveform (*.wav)|*.wav|Plain text (*.txt)|*.txt|All files (*.*)|*.*", Wx::FD_CHANGE_DIR, self) if path == nil return nil end # it is just a sample, would use SplitPath in real program @ext_def = path[/[^.]*$/] Wx.log_message("You selected the file '%s', remembered extension '%s'", path, @ext_def) end def on_files_open(_event) Wx.FileDialog(self, "Testing open multiple file dialog", "", "", Wx::FILE_SELECTOR_DEFAULT_WILDCARD_STR, Wx::FD_MULTIPLE) do |dialog| if dialog.show_modal == Wx::ID_OK paths = dialog.get_paths filenames = dialog.get_filenames count = paths.length msg = count.times.collect { |n| "File %d: %s (%s)\n" % [n, paths[n], filenames[n]] }.join Wx.MessageDialog(self, msg, "Selected files") end end end def on_file_save(_event) Wx.FileDialog(self, "Testing save file dialog", "", "myletter.doc", "Text files (*.txt)|*.txt|Document files (*.doc)|*.doc", Wx::FD_SAVE | Wx::FD_OVERWRITE_PROMPT) do |dialog| dialog.set_filter_index(1) if dialog.show_modal == Wx::ID_OK Wx.log_message("%s, filter %d", dialog.get_path, dialog.get_filter_index) end end end def on_dir_choose(_event) # pass some initial dir to DirDialog dir_home = Wx.get_home_dir Wx.DirDialog(self, "Testing directory picker", dir_home) do |dialog| if dialog.show_modal == Wx::ID_OK Wx.log_message("Selected path: %s", dialog.get_path) end end end def on_modal_dlg(_event) Dialogs.MyModalDialog(self) end def on_modeless_dlg(event) show = get_menu_bar.is_checked(event.get_id) if show @dialog ||= Dialogs::MyModelessDialog.new(self) @dialog.show(true) else # hide @dialog.destroy @dialog = nil end end def on_show_tip(_event) if @index == -1 @index = rand(5) end tip_src = File.join( File.dirname(__FILE__), 'tips.txt') tip_provider = Wx.create_file_tip_provider(tip_src, @index) show_at_startup = Wx.show_tip(self, tip_provider) if show_at_startup Wx.message_box("Will show tips on startup", "Tips dialog", Wx::OK | Wx::ICON_INFORMATION, self) end @index = tip_provider.get_current_tip end def on_show_custom_tip(_event) if @index_2 == -1 @index_2 = rand(3) end tip_provider = MyTipProvider.new(@index_2) show_at_startup = Wx.show_tip(self, tip_provider) if show_at_startup Wx.message_box("Will show tips on startup", "Tips dialog", Wx::OK | Wx::ICON_INFORMATION, self) end @index_2 = tip_provider.get_current_tip end def on_exit(_event) close(true) end def on_show_prefs(event) Dialogs.MyPrefsDialog(self, event.id) end def on_show_progress(_event) cont = false Wx.ProgressDialog("Progress dialog example", "An informative message\n"+"#{' '*100}\n\n\n\n", @max, # range self, # parent Wx::PD_CAN_ABORT | Wx::PD_CAN_SKIP | Wx::PD_APP_MODAL | Wx::PD_ELAPSED_TIME | Wx::PD_ESTIMATED_TIME | Wx::PD_REMAINING_TIME) do |dialog| cont = true i = 0 while i <= @max if i == 0 cont = dialog.update(i) elsif i == @max cont = dialog.update(i, "That's all, folks!\n\nNothing more to see here any more.") elsif i <= (@max / 2) cont = dialog.pulse("Testing indeterminate mode\n" + "\n" + "This mode allows you to show to the user\n" + "that something is going on even if you don't know\n" + "when exactly will you finish.") else cont = dialog.update(i, "Now in standard determinate mode\n" + "\n" + "This is the standard usage mode in which you\n" + "update the dialog after performing each new step of work.\n" + "It requires knowing the total number of steps in advance.") end if !cont if Wx.message_box("Do you really want to cancel?", "Progress dialog question", # caption Wx::YES_NO | Wx::ICON_QUESTION) == Wx::YES dialog.show(false) break end dialog.resume elsif cont == :skipped i += (@max / 4) i = @max-1 if i >= @max end sleep(i == 0 ? 1 : 0.15) i += 1 end end if !cont Wx.log_status("Progress dialog aborted!") else Wx.log_status("Countdown from %d finished", @max) end end def on_show_busy_info(_event) result = nil Wx::WindowDisabler.disable(self) do result = Wx::BusyInfo.busy("Working, please wait...", self) do |bi| 18.times { Wx.get_app.yield } sleep(1) bi.update_text('Working some more...') 18.times { Wx.get_app.yield } sleep(1) 'Finished work!' end end Wx.log_status(result) end def on_show_styled_busy_info(_event) result = nil icon_file = File.join( File.dirname(__FILE__)+"/../art", "wxruby.png") Wx::WindowDisabler.disable(self) do bif = Wx::BusyInfoFlags.new.parent(self).icon(Wx::Icon.new(icon_file)).title("Busy window").text("Working, please wait...") result = Wx::BusyInfo.busy(bif) do |bi| 18.times { Wx.get_app.yield } sleep(1) bi.update_text('Working some more...') 18.times { Wx.get_app.yield } sleep(1) 'Finished work!' end end Wx.log_status(result) end def on_show_replace_dialog(_event) if @dlg_replace @dlg_replace.destroy @dlg_replace = nil else @dlg_replace = Wx::FindReplaceDialog.new( self, @find_data, "Find and replace dialog", Wx::FR_REPLACEDIALOG) @dlg_replace.show(true) end end def on_show_find_dialog(_event) if @dlg_find @dlg_find.destroy @dlg_find = nil else @dlg_find = Wx::FindReplaceDialog.new( self, @find_data, "Find dialog", # just for testing Wx::FR_NOWHOLEWORD) @dlg_find.show(true) end end def decode_find_dialog_event_flags(flags) str = "" str << ((flags & Wx::FR_DOWN) != 0 ? "down" : "up") << ", " \ << ((flags & Wx::FR_WHOLEWORD) != 0 ? "whole words only, " : "") \ << ((flags & Wx::FR_MATCHCASE) != 0 ? "" : "not ") \ << "case sensitive" str end def on_find_dialog(event) type = event.get_event_type if type == Wx::EVT_FIND || type == Wx::EVT_FIND_NEXT Wx.log_message("Find %s'%s' (flags: %s)", type == Wx::EVT_FIND_NEXT ? "next " : "", event.get_find_string, decode_find_dialog_event_flags(event.get_flags)) elsif type == Wx::EVT_FIND_REPLACE || type == Wx::EVT_FIND_REPLACE_ALL Wx.log_message("Replace %s'%s' with '%s' (flags: %s)", type == Wx::EVT_FIND_REPLACE_ALL ? "all " : "", event.get_find_string, event.get_replace_string, decode_find_dialog_event_flags(event.get_flags)) elsif type == Wx::EVT_FIND_CLOSE dlg = event.get_dialog if dlg == @dlg_find txt = "Find" id_menu = DIALOGS_FIND @dlg_find = nil elsif dlg == @dlg_replace txt = "Replace" id_menu = DIALOGS_REPLACE @dlg_replace = nil else txt = "Unknown" id_menu = -1 Wx.log_error("unexpected event") end Wx.log_message("%s dialog is being closed.", txt) if id_menu != -1 get_menu_bar.check(id_menu, false) end dlg.destroy else Wx.log_error("Unknown find dialog event!") end end end class MyApp < Wx::App class << self attr_accessor :canvas end attr_accessor :canvas_text_colour, :canvas_font def on_init self.canvas_text_colour = Wx::Colour.new("BLACK") self.canvas_font = Wx::NORMAL_FONT # Create the main frame window frame = MyFrame.new(nil, "Windows dialogs example", [20, 20], [400, 300]) gc_stress # Make a menubar file_menu = Wx::Menu.new file_menu.append(DIALOGS_CHOOSE_COLOUR, "&Choose colour") file_menu.append_separator file_menu.append(DIALOGS_CHOOSE_FONT, "Choose &font") file_menu.append_separator file_menu.append(DIALOGS_LOG_DIALOG, "&Log dialog\tCtrl-L") file_menu.append(DIALOGS_MESSAGE_BOX, "&Message box\tCtrl-M") file_menu.append(DIALOGS_TEXT_ENTRY, "Text &entry\tCtrl-E") file_menu.append(DIALOGS_PASSWORD_ENTRY, "&Password entry\tCtrl-P") file_menu.append(DIALOGS_NUM_ENTRY, "&Numeric entry\tCtrl-N") file_menu.append(DIALOGS_SINGLE_CHOICE, "&Single choice\tCtrl-C") file_menu.append(DIALOGS_MULTI_CHOICE, "M&ultiple choice\tCtrl-U") file_menu.append_separator file_menu.append(DIALOGS_TIP, "&Tip of the day\tCtrl-T") file_menu.append(DIALOGS_CUSTOM_TIP, "Custom tip of the day") file_menu.append_separator file_menu.append(DIALOGS_FILE_OPEN, "&Open file\tCtrl-O") file_menu.append(DIALOGS_FILE_OPEN2, "&Second open file\tCtrl-2") file_menu.append(DIALOGS_FILES_OPEN, "Open &files\tShift-Ctrl-O") file_menu.append(DIALOGS_FILE_SAVE, "Sa&ve file\tCtrl-S") file_menu.append(DIALOGS_DIR_CHOOSE, "Choose a &directory\tCtrl-D") file_menu.append(DIALOGS_PROGRESS, "Pro&gress dialog\tCtrl-G") file_menu.append(DIALOGS_BUSYINFO, "&Busy info dialog\tCtrl-B") file_menu.append(DIALOGS_STYLED_BUSYINFO, "Styled BusyInfo dialog") file_menu.append(DIALOGS_PREFS, "Standard propert&y sheet dialog\tCtrl-Y") file_menu.append(DIALOGS_PREFS_TOOLBOOK, "&Toolbook property sheet dialog\tShift-Ctrl-Y") file_menu.append(DIALOGS_FIND, "&Find dialog\tCtrl-F", "", Wx::ITEM_CHECK) file_menu.append(DIALOGS_REPLACE, "Find and &replace dialog\tShift-Ctrl-F", "", Wx::ITEM_CHECK) file_menu.append_separator file_menu.append(DIALOGS_MODAL, "Mo&dal dialog\tCtrl-W") file_menu.append(DIALOGS_MODELESS, "Modeless &dialog\tCtrl-Z", "", Wx::ITEM_CHECK) file_menu.append_separator file_menu.append(Wx::ID_EXIT, "E&xit\tAlt-X") menu_bar = Wx::MenuBar.new menu_bar.append(file_menu, "&File") frame.set_menu_bar(menu_bar) MyApp.canvas = MyCanvas.new(frame) MyApp.canvas.set_background_colour(Wx::WHITE) frame.centre(Wx::BOTH) # Show the frame frame.show end def on_exit MyApp.canvas = nil end end end module DialogsSample include WxRuby::Sample if defined? WxRuby::Sample def self.describe { file: __FILE__, summary: 'wxRuby dialogs example.', description: 'wxRuby example demonstrating various common dialogs.' } end def self.run execute(__FILE__) end if $0 == __FILE__ Dialogs::MyApp.run end end