#!/usr/bin/env ruby # wxRuby2 Sample Code. Copyright (c) 2004-2008 wxRuby development team # Freely reusable code: see SAMPLES-LICENSE.TXT for details begin require 'rubygems' rescue LoadError end require 'wx' include Wx Calendar_Cal_Monday = 200 Calendar_Cal_Holidays = 201 Calendar_Cal_Special = 202 Calendar_Cal_Month = 203 Calendar_Cal_Year = 204 Calendar_Cal_SeqMonth = 205 Calendar_Cal_SurroundWeeks = 206 Calendar_DatePicker_AskDate = 300 Calendar_DatePicker_ShowCentury = 301 Calendar_DatePicker_DropDown = 302 Calendar_DatePicker_AllowNone = 303 Calendar_DatePicker_StartWithNone = 304 class MyCalendar < CalendarCtrl def initialize(parent, display_frame, initial_date, calendar_flags) super( parent, :date => initial_date, :style => calendar_flags | RAISED_BORDER) @display = display_frame @date = initial_date @weekday_names = %w|Sun Mon Tue Wed Thu Fri Sat| evt_calendar self, :on_calendar evt_calendar_month self, :on_cal_month_change evt_calendar_year self, :on_cal_year_change evt_calendar_sel_changed self, :on_calendar_change evt_calendar_weekday_clicked self, :on_calendar_weekday_click end def on_calendar(event) @display.date = event.date end def on_calendar_change(event) @date = event.date log_status("Selected date: #{@date.strftime('%A %d %B %Y')}") end def on_cal_month_change log_status("Calendar month changed") end def on_cal_year_change log_status("Calendar year changed") end def on_calendar_weekday_click(event) wday = event.week_day log_status("Clicked on #{@weekday_names[wday]}") end attr_reader :date end class MyFrame < Frame def initialize(title) super(nil, -1, title) @panel = Wx::Panel.new(self) add_menu_bar add_status_bar @calendar_flags = CAL_MONDAY_FIRST | CAL_SHOW_HOLIDAYS @calendar = MyCalendar.new(@panel, self, Time.now, @calendar_flags) @sizer = BoxSizer.new(VERTICAL) configure_window evt_menu Wx::ID_EXIT, :on_quit evt_menu Wx::ID_ABOUT, :on_about evt_menu Calendar_DatePicker_AskDate, :on_ask_date evt_update_ui Calendar_DatePicker_StartWithNone, :on_update_ui_start_with_none evt_menu Calendar_Cal_Monday, :on_cal_monday evt_menu Calendar_Cal_Holidays, :on_cal_holidays evt_menu Calendar_Cal_Special, :on_cal_special evt_menu Calendar_Cal_Month, :on_cal_allow_month evt_menu Calendar_Cal_Year, :on_cal_allow_year evt_menu Calendar_Cal_SeqMonth, :on_cal_seq_month evt_menu Calendar_Cal_SurroundWeeks, :on_cal_show_surrounding_weeks evt_update_ui Calendar_Cal_Year, :on_allow_year_update end def add_menu_bar # create a menu bar menu_file = Menu.new menu_file.append(Wx::ID_ABOUT, "&About...\tCtrl-A", "Show about dialog") menu_file.append_separator menu_file.append(Wx::ID_EXIT, "E&xit\tAlt-X", "Quit self program") menu_cal = Menu.new menu_cal.append(Calendar_Cal_Monday, "Monday &first weekday\tCtrl-F", "Toggle between Mon and Sun as the first week day", ITEM_CHECK) menu_cal.append(Calendar_Cal_Holidays, "Show &holidays\tCtrl-H", "Toggle highlighting the holidays", ITEM_CHECK) menu_cal.append(Calendar_Cal_Special, "Highlight &special dates\tCtrl-S", "Test custom highlighting", ITEM_CHECK) menu_cal.append(Calendar_Cal_SurroundWeeks, "Show s&urrounding weeks\tCtrl-W", "Show the neighbouring weeks in the prev/next month", ITEM_CHECK) menu_cal.append_separator menu_cal.append(Calendar_Cal_SeqMonth, "To&ggle month selector style\tCtrl-G", "Use another style for the calendar controls", ITEM_CHECK) menu_cal.append(Calendar_Cal_Month, "&Month can be changed\tCtrl-M", "Allow changing the month in the calendar", ITEM_CHECK) menu_cal.append(Calendar_Cal_Year, "&Year can be changed\tCtrl-Y", "Allow changing the year in the calendar", ITEM_CHECK) menu_date = Menu.new menu_date.append_check_item(Calendar_DatePicker_ShowCentury, "Al&ways show century") menu_date.append_check_item(Calendar_DatePicker_DropDown, "Use &drop down control") menu_date.append_check_item(Calendar_DatePicker_AllowNone, "Allow &no date") menu_date.append_check_item(Calendar_DatePicker_StartWithNone, "Start &with no date") menu_date.append_separator menu_date.append(Calendar_DatePicker_AskDate, "&Choose date...\tCtrl-D", "Show dialog with DatePickerCtrl") # now append the freshly created menu to the menu bar... menu_bar = MenuBar.new menu_bar.append(menu_file, "&File") menu_bar.append(menu_cal, "&Calendar") menu_bar.append(menu_date, "&Date picker") menu_bar.check(Calendar_Cal_Monday, TRUE) menu_bar.check(Calendar_Cal_Holidays, TRUE) menu_bar.check(Calendar_Cal_Month, TRUE) menu_bar.check(Calendar_Cal_Year, TRUE) menu_bar.check(Calendar_DatePicker_ShowCentury, TRUE) # ... and attach self menu bar to the frame self.menu_bar = menu_bar end def add_status_bar # create a status bar just for fun (by default with 1 pane only) create_status_bar set_status_text("Welcome to Windows!") end def configure_window @sizer.add(@calendar, 0, Wx::ALIGN_CENTRE|Wx::ALL, 5) @sizer.size_hints = @panel layout @panel.sizer = @sizer end def on_quit # true is to force the frame to close close(true) end def on_about message_box("wxRuby CalendarCtrl sample\nby Kevin Smith\n" + "based on the wxWidgets version by Vadim Zeitlin", "About Calendar", OK | ICON_INFORMATION, self) end def on_cal_monday(event) enable = get_menu_bar().is_checked(event.get_id()) toggle_cal_style(enable, CAL_MONDAY_FIRST) end def on_cal_holidays(event) enable = get_menu_bar().is_checked(event.get_id()) @calendar.enable_holiday_display(enable) end def on_cal_special(event) highlight_special(get_menu_bar().is_checked(event.get_id())) end def on_cal_allow_month(event) allow = get_menu_bar().is_checked(event.get_id()) @calendar.enable_month_change(allow) end def on_cal_allow_year(event) allow = get_menu_bar().is_checked(event.get_id()) @calendar.enable_year_change(allow) end def on_cal_seq_month(event) allow = get_menu_bar().is_checked(event.get_id()) toggle_cal_style(allow, CAL_SEQUENTIAL_MONTH_SELECTION) end def on_cal_show_surrounding_weeks(event) allow = get_menu_bar().is_checked(event.get_id()) toggle_cal_style(allow, CAL_SHOW_SURROUNDING_WEEKS) end def on_allow_year_update(event) event.enable( get_menu_bar().is_checked(Calendar_Cal_Month)) end def on_update_ui_start_with_none(event) event.enable( get_menu_bar().is_checked(Calendar_DatePicker_AllowNone)) end def on_ask_date(event) dt = @calendar.get_date style = DP_DEFAULT style |= DP_SHOWCENTURY if get_menu_bar.is_checked(Calendar_DatePicker_ShowCentury) style |= DP_DROPDOWN if get_menu_bar.is_checked(Calendar_DatePicker_DropDown) if get_menu_bar.is_checked(Calendar_DatePicker_AllowNone) style |= DP_ALLOWNONE dt = nil if get_menu_bar.is_checked(Calendar_DatePicker_StartWithNone) end dlg = MyDialog.new(self, dt, style) if dlg.show_modal == ID_OK if dt = dlg.get_date today = Time.now if dt.day == today.day && dt.month == today.month message_box("Happy birthday", "Calendar Sample") end @calendar.set_date(dt) log_status("Changed the date to your input") else log_status("No date entered") end end end def toggle_cal_style(on,flag) style = @calendar.get_window_style_flag date = @calendar.date @sizer.detach(@calendar) @calendar.destroy if on style |= flag else style &= ~flag end @calendar = MyCalendar.new(@panel, self, date, style) @sizer.add(@calendar, 0, Wx::ALIGN_CENTRE|Wx::ALL, 5) @panel.layout end def highlight_special(on) if on attr_red_circle = CalendarDateAttr.new(CAL_BORDER_ROUND, RED) attr_green_square = CalendarDateAttr.new(CAL_BORDER_SQUARE, GREEN) # This wraps correctly, but causes problems because the colour is freed # when the attribute is reset. # # attr_header_like = CalendarDateAttr.new(BLUE, LIGHT_GREY) @calendar.set_attr(17, attr_red_circle) @calendar.set_attr(29, attr_green_square) # @calendar.set_attr(13, attr_header_like) else @calendar.reset_attr(17) @calendar.reset_attr(29) # @calendar.reset_attr(13) end @calendar.refresh() end def set_date(d) str = "%s-%s-%s" % [ d.year, d.mon, d.day ] Wx::MessageDialog.new( self, "The selected date is #{str}", "Date chosen" ).show_modal end end class MyDialog < Dialog def initialize(parent, dt, picker_style) super(parent, :style => DEFAULT_DIALOG_STYLE|RESIZE_BORDER) sizer_buttons = StdDialogButtonSizer.new sizer_buttons.add_button(Button.new(self, ID_OK)) sizer_buttons.add_button(Button.new(self, ID_CANCEL)) sizer_buttons.realize sizer_text = BoxSizer.new(HORIZONTAL) sizer_text.add(StaticText.new(self, ID_ANY, "Date in ISO format:"), 0, ALL|ALIGN_CENTRE_VERTICAL, 10) @text = TextCtrl.new(self) sizer_text.add(@text, 1, ALL|ALIGN_CENTRE_VERTICAL|EXPAND, 10) sizer_top = BoxSizer.new(VERTICAL) sizer_top.add(StaticText.new(self, ID_ANY, "Enter your birthday date (not before 20th century):"), 0, ALL, 10) @picker = DatePickerCtrl.new(self, ID_ANY, dt, DEFAULT_POSITION, DEFAULT_SIZE, picker_style) @picker.set_range(DateTime.new(1900, 1, 1), nil) sizer_top.add(@picker, 0, ALL|EXPAND, 10) sizer_top.add_stretch_spacer(1) sizer_top.add(sizer_text, 0, EXPAND) sizer_top.add(sizer_buttons, 0, ALL|ALIGN_CENTER, 10) set_sizer_and_fit(sizer_top) layout evt_date_changed(@picker, :on_date_changed) end def get_date @picker.get_value end def on_date_changed(event) if dt = event.get_date @text.set_value(dt.to_s) else @text.set_value("") end end end class RbApp < App def on_init() frame = MyFrame.new("Calendar Windows sample") frame.show(true) end end a = RbApp.new a.main_loop()