« 時計をつくる5 | トップページ | PC壊れた »

2009年6月 7日 (日)

時計をつくる6

実装していなかったオプションダイアログを作製してみました。それに伴って設定格納用のクラスRTC_configもつくりました。設定の保存にはYAMLを使用しました。
その他幾つか変更も加えています。

最初は単純にWxRubyのクラスをそのままYAML.dumpで保存しようと思っていたのですが、予想通り値が保存されませんでした。仕方ないのでStructなどを使って保存するようにしました。RTC_configを参照するようにメソッドにいろいろ変更を加えていく内にちょっとソースコードが汚くなってしまった。

今回は全般的にあまりテストしていないのでおかしな動きをするところがあるかもしれません。

  1. <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
  2. <resource xmlns="http://www.wxwindows.org/wxxrc" version="2.3.0.1">
  3.   <object class="wxFrame" name="MyFrame1" subclass="RTC">
  4.     <style>wxFRAME_NO_TASKBAR|wxFRAME_SHAPED|wxSTAY_ON_TOP|wxTAB_TRAVERSAL</style>
  5.     <size>500,300</size>
  6.     <title></title>
  7.     <object class="wxBoxSizer">
  8.       <orient>wxHORIZONTAL</orient>
  9.     </object>
  10.   </object>
  11.   <object class="wxDialog" name="MyDialog1" subclass="RTC_Option">
  12.     <style>wxDEFAULT_DIALOG_STYLE</style>
  13.     <size>350,250</size>
  14.     <title>Option</title>
  15.     <object class="wxBoxSizer">
  16.       <orient>wxVERTICAL</orient>
  17.       <object class="sizeritem">
  18.         <option>1</option>
  19.         <flag>wxEXPAND | wxALL</flag>
  20.         <border>5</border>
  21.         <object class="wxNotebook" name="m_notebook1">
  22.           <object class="notebookpage">
  23.             <label>Test</label>
  24.             <selected>1</selected>
  25.             <object class="wxPanel" name="m_panel1">
  26.               <style>wxTAB_TRAVERSAL</style>
  27.               <object class="wxBoxSizer">
  28.                 <orient>wxVERTICAL</orient>
  29.                 <object class="sizeritem">
  30.                   <option>1</option>
  31.                   <flag>wxEXPAND</flag>
  32.                   <border>5</border>
  33.                   <object class="wxBoxSizer">
  34.                     <orient>wxHORIZONTAL</orient>
  35.                     <object class="sizeritem">
  36.                       <option>0</option>
  37.                       <flag>wxALL</flag>
  38.                       <border>5</border>
  39.                       <object class="wxStaticText" name="m_staticText1">
  40.                         <label>Hour</label>
  41.                       </object>
  42.                     </object>
  43.                     <object class="spacer">
  44.                       <option>1</option>
  45.                       <flag>wxEXPAND</flag>
  46.                       <border>5</border>
  47.                       <size>0,0</size>
  48.                     </object>
  49.                     <object class="sizeritem">
  50.                       <option>0</option>
  51.                       <flag>wxALL</flag>
  52.                       <border>5</border>
  53.                       <object class="wxSpinCtrl" name="m_spinCtrl1">
  54.                         <style>wxSP_ARROW_KEYS</style>
  55.                         <value>0</value>
  56.                         <min>0</min>
  57.                         <max>23</max>
  58.                       </object>
  59.                     </object>
  60.                   </object>
  61.                 </object>
  62.                 <object class="sizeritem">
  63.                   <option>1</option>
  64.                   <flag>wxEXPAND</flag>
  65.                   <border>5</border>
  66.                   <object class="wxBoxSizer">
  67.                     <orient>wxHORIZONTAL</orient>
  68.                     <object class="sizeritem">
  69.                       <option>0</option>
  70.                       <flag>wxALL</flag>
  71.                       <border>5</border>
  72.                       <object class="wxStaticText" name="m_staticText2">
  73.                         <label>Minute</label>
  74.                       </object>
  75.                     </object>
  76.                     <object class="spacer">
  77.                       <option>1</option>
  78.                       <flag>wxEXPAND</flag>
  79.                       <border>5</border>
  80.                       <size>0,0</size>
  81.                     </object>
  82.                     <object class="sizeritem">
  83.                       <option>0</option>
  84.                       <flag>wxALL</flag>
  85.                       <border>5</border>
  86.                       <object class="wxSpinCtrl" name="m_spinCtrl2">
  87.                         <style>wxSP_ARROW_KEYS</style>
  88.                         <value>0</value>
  89.                         <min>0</min>
  90.                         <max>59</max>
  91.                       </object>
  92.                     </object>
  93.                   </object>
  94.                 </object>
  95.               </object>
  96.             </object>
  97.           </object>
  98.           <object class="notebookpage">
  99.             <label>Position</label>
  100.             <selected>0</selected>
  101.             <object class="wxPanel" name="m_panel2">
  102.               <style>wxTAB_TRAVERSAL</style>
  103.               <object class="wxBoxSizer">
  104.                 <orient>wxVERTICAL</orient>
  105.                 <object class="sizeritem">
  106.                   <option>1</option>
  107.                   <flag>wxEXPAND</flag>
  108.                   <border>0</border>
  109.                   <object class="wxGridSizer">
  110.                     <rows>2</rows>
  111.                     <cols>2</cols>
  112.                     <vgap>0</vgap>
  113.                     <hgap>0</hgap>
  114.                     <object class="sizeritem">
  115.                       <option>0</option>
  116.                       <flag>wxALL|wxEXPAND</flag>
  117.                       <border>0</border>
  118.                       <object class="wxButton" name="pos_lu">
  119.                         <label>Left _ Top</label>
  120.                         <default>0</default>
  121.                       </object>
  122.                     </object>
  123.                     <object class="sizeritem">
  124.                       <option>0</option>
  125.                       <flag>wxALL|wxEXPAND</flag>
  126.                       <border>0</border>
  127.                       <object class="wxButton" name="pos_ru">
  128.                         <label>Right _ Top</label>
  129.                         <default>0</default>
  130.                       </object>
  131.                     </object>
  132.                     <object class="sizeritem">
  133.                       <option>0</option>
  134.                       <flag>wxALL|wxEXPAND</flag>
  135.                       <border>0</border>
  136.                       <object class="wxButton" name="pos_lb">
  137.                         <label>Left _ Bottom</label>
  138.                         <default>0</default>
  139.                       </object>
  140.                     </object>
  141.                     <object class="sizeritem">
  142.                       <option>0</option>
  143.                       <flag>wxALL|wxEXPAND</flag>
  144.                       <border>0</border>
  145.                       <object class="wxButton" name="pos_rb">
  146.                         <label>Right _ Bottom</label>
  147.                         <default>0</default>
  148.                       </object>
  149.                     </object>
  150.                   </object>
  151.                 </object>
  152.                 <object class="sizeritem">
  153.                   <option>0</option>
  154.                   <flag>wxALL</flag>
  155.                   <border>5</border>
  156.                   <object class="wxCheckBox" name="stayontop">
  157.                     <label>Stay on Top</label>
  158.                     <checked>0</checked>
  159.                   </object>
  160.                 </object>
  161.               </object>
  162.             </object>
  163.           </object>
  164.           <object class="notebookpage">
  165.             <label>Size</label>
  166.             <selected>0</selected>
  167.             <object class="wxPanel" name="m_panel3">
  168.               <style>wxTAB_TRAVERSAL</style>
  169.               <object class="wxBoxSizer">
  170.                 <orient>wxVERTICAL</orient>
  171.                 <object class="sizeritem">
  172.                   <option>1</option>
  173.                   <flag>wxEXPAND</flag>
  174.                   <border>5</border>
  175.                   <object class="wxBoxSizer">
  176.                     <orient>wxHORIZONTAL</orient>
  177.                     <object class="sizeritem">
  178.                       <option>0</option>
  179.                       <flag>wxALL</flag>
  180.                       <border>5</border>
  181.                       <object class="wxStaticText" name="m_staticText3">
  182.                         <label>clock size</label>
  183.                       </object>
  184.                     </object>
  185.                     <object class="spacer">
  186.                       <option>1</option>
  187.                       <flag>wxEXPAND</flag>
  188.                       <border>5</border>
  189.                       <size>0,0</size>
  190.                     </object>
  191.                     <object class="sizeritem">
  192.                       <option>0</option>
  193.                       <flag>wxALL</flag>
  194.                       <border>5</border>
  195.                       <object class="wxSlider" name="clock_size_sldr">
  196.                         <style>wxSL_AUTOTICKS|wxSL_HORIZONTAL|wxSL_LABELS</style>
  197.                         <value>100</value>
  198.                         <min>50</min>
  199.                         <max>500</max>
  200.                       </object>
  201.                     </object>
  202.                   </object>
  203.                 </object>
  204.                 <object class="sizeritem">
  205.                   <option>1</option>
  206.                   <flag>wxEXPAND</flag>
  207.                   <border>5</border>
  208.                   <object class="wxBoxSizer">
  209.                     <orient>wxHORIZONTAL</orient>
  210.                     <object class="sizeritem">
  211.                       <option>0</option>
  212.                       <flag>wxALL</flag>
  213.                       <border>5</border>
  214.                       <object class="wxStaticText" name="m_staticText31">
  215.                         <label>circle offset</label>
  216.                       </object>
  217.                     </object>
  218.                     <object class="spacer">
  219.                       <option>1</option>
  220.                       <flag>wxEXPAND</flag>
  221.                       <border>5</border>
  222.                       <size>0,0</size>
  223.                     </object>
  224.                     <object class="sizeritem">
  225.                       <option>0</option>
  226.                       <flag>wxALL</flag>
  227.                       <border>5</border>
  228.                       <object class="wxSlider" name="circle_offset_sldr">
  229.                         <style>wxSL_AUTOTICKS|wxSL_HORIZONTAL|wxSL_LABELS</style>
  230.                         <value>100</value>
  231.                         <min>50</min>
  232.                         <max>500</max>
  233.                       </object>
  234.                     </object>
  235.                   </object>
  236.                 </object>
  237.                 <object class="sizeritem">
  238.                   <option>1</option>
  239.                   <flag>wxEXPAND</flag>
  240.                   <border>5</border>
  241.                   <object class="wxBoxSizer">
  242.                     <orient>wxHORIZONTAL</orient>
  243.                     <object class="sizeritem">
  244.                       <option>0</option>
  245.                       <flag>wxALL</flag>
  246.                       <border>5</border>
  247.                       <object class="wxStaticText" name="m_staticText4">
  248.                         <label>tick mark size</label>
  249.                       </object>
  250.                     </object>
  251.                     <object class="spacer">
  252.                       <option>1</option>
  253.                       <flag>wxEXPAND</flag>
  254.                       <border>5</border>
  255.                       <size>0,0</size>
  256.                     </object>
  257.                     <object class="sizeritem">
  258.                       <option>0</option>
  259.                       <flag>wxALL</flag>
  260.                       <border>5</border>
  261.                       <object class="wxSlider" name="tick_sldr">
  262.                         <style>wxSL_AUTOTICKS|wxSL_HORIZONTAL|wxSL_LABELS</style>
  263.                         <value>10</value>
  264.                         <min>1</min>
  265.                         <max>50</max>
  266.                       </object>
  267.                     </object>
  268.                   </object>
  269.                 </object>
  270.               </object>
  271.             </object>
  272.           </object>
  273.           <object class="notebookpage">
  274.             <label>Font</label>
  275.             <selected>0</selected>
  276.             <object class="wxPanel" name="m_panel4">
  277.               <style>wxTAB_TRAVERSAL</style>
  278.               <object class="wxBoxSizer">
  279.                 <orient>wxVERTICAL</orient>
  280.                 <object class="sizeritem">
  281.                   <option>0</option>
  282.                   <flag>wxEXPAND</flag>
  283.                   <border>5</border>
  284.                   <object class="wxBoxSizer">
  285.                     <orient>wxHORIZONTAL</orient>
  286.                     <object class="sizeritem">
  287.                       <option>0</option>
  288.                       <flag>wxALL</flag>
  289.                       <border>5</border>
  290.                       <object class="wxStaticText" name="m_staticText5">
  291.                         <label>Font</label>
  292.                       </object>
  293.                     </object>
  294.                     <object class="sizeritem">
  295.                       <option>1</option>
  296.                       <flag>wxALL</flag>
  297.                       <border>5</border>
  298.                       <object class="wxTextCtrl" name="fontname">
  299.                         <style>wxTE_READONLY</style>
  300.                         <value></value>
  301.                         <maxlength>0</maxlength>
  302.                       </object>
  303.                     </object>
  304.                     <object class="sizeritem">
  305.                       <option>0</option>
  306.                       <flag>wxALL</flag>
  307.                       <border>5</border>
  308.                       <object class="wxButton" name="font_browse">
  309.                         <label>Browse</label>
  310.                         <default>0</default>
  311.                       </object>
  312.                     </object>
  313.                   </object>
  314.                 </object>
  315.                 <object class="sizeritem">
  316.                   <option>1</option>
  317.                   <flag>wxEXPAND</flag>
  318.                   <border>5</border>
  319.                   <object class="wxBoxSizer">
  320.                     <orient>wxHORIZONTAL</orient>
  321.                     <object class="sizeritem">
  322.                       <option>1</option>
  323.                       <flag>wxALL</flag>
  324.                       <border>5</border>
  325.                       <object class="wxStaticText" name="m_staticText6">
  326.                         <label>Font Size</label>
  327.                       </object>
  328.                     </object>
  329.                     <object class="sizeritem">
  330.                       <option>0</option>
  331.                       <flag>wxALL</flag>
  332.                       <border>5</border>
  333.                       <object class="wxSpinCtrl" name="font_size">
  334.                         <style>wxSP_ARROW_KEYS</style>
  335.                         <value>0</value>
  336.                         <min>1</min>
  337.                         <max>30</max>
  338.                       </object>
  339.                     </object>
  340.                   </object>
  341.                 </object>
  342.               </object>
  343.             </object>
  344.           </object>
  345.         </object>
  346.       </object>
  347.       <object class="sizeritem">
  348.         <option>0</option>
  349.         <flag>wxEXPAND</flag>
  350.         <border>5</border>
  351.         <object class="wxStdDialogButtonSizer">
  352.           <object class="button">
  353.             <flag>wxALIGN_CENTER_HORIZONTAL|wxALL</flag>
  354.             <border>5</border>
  355.             <object class="wxButton" name="wxID_OK">
  356.               <label>&amp;OK</label>
  357.             </object>
  358.           </object>
  359.           <object class="button">
  360.             <flag>wxALIGN_CENTER_HORIZONTAL|wxALL</flag>
  361.             <border>5</border>
  362.             <object class="wxButton" name="wxID_APPLY">
  363.               <label>&amp;Apply</label>
  364.             </object>
  365.           </object>
  366.           <object class="button">
  367.             <flag>wxALIGN_CENTER_HORIZONTAL|wxALL</flag>
  368.             <border>5</border>
  369.             <object class="wxButton" name="wxID_CANCEL">
  370.               <label>&amp;Cancel</label>
  371.             </object>
  372.           </object>
  373.         </object>
  374.       </object>
  375.     </object>
  376.   </object>
  377. </resource>
  378.  

XRCファイルから生成されたソースコード

  1.  
  2. # This class was automatically generated from XRC source. It is not
  3. # recommended that this file is edited directly; instead, inherit from
  4. # this class and extend its behaviour there. 
  5. #
  6. # Source file: noname.xrc
  7. # Generated at: Sun Jun 07 00:29:47 &#26481;&#20140; (&#27161;&#28310;&#26178;) 2009
  8.  
  9. class RTC < Wx::Frame
  10.  
  11.   def initialize(parent = nil)
  12.     super()
  13.     xml = Wx::XmlResource.get
  14.     xml.flags = 2 # Wx::XRC_NO_SUBCLASSING
  15.     xml.init_all_handlers
  16.     xml.load("noname.xrc")
  17.     xml.load_frame_subclass(self, parent, "MyFrame1")
  18.  
  19.     finder = lambda do | x |
  20.       int_id = Wx::xrcid(x)
  21.       begin
  22.         Wx::Window.find_window_by_id(int_id, self) || int_id
  23.       # Temporary hack to work around regression in 1.9.2; remove
  24.       # begin/rescue clause in later versions
  25.       rescue RuntimeError
  26.         int_id
  27.       end
  28.     end
  29.  
  30.     if self.class.method_defined? "on_init"
  31.       self.on_init()
  32.     end
  33.   end
  34. end
  35.  
  36.  
  37.  
  38. # This class was automatically generated from XRC source. It is not
  39. # recommended that this file is edited directly; instead, inherit from
  40. # this class and extend its behaviour there. 
  41. #
  42. # Source file: noname.xrc
  43. # Generated at: Sun Jun 07 00:29:47 &#26481;&#20140; (&#27161;&#28310;&#26178;) 2009
  44.  
  45. class RTC_Option < Wx::Dialog
  46.  
  47.   attr_reader :m_notebook1, :m_panel1, :m_statictext1, :m_spinctrl1,
  48.               :m_statictext2, :m_spinctrl2, :m_panel2, :pos_lu,
  49.               :pos_ru, :pos_lb, :pos_rb, :stayontop, :m_panel3,
  50.               :m_statictext3, :clock_size_sldr, :m_statictext31,
  51.               :circle_offset_sldr, :m_statictext4, :tick_sldr,
  52.               :m_panel4, :m_statictext5, :fontname, :font_browse,
  53.               :m_statictext6, :font_size
  54.  
  55.   def initialize(parent = nil)
  56.     super()
  57.     xml = Wx::XmlResource.get
  58.     xml.flags = 2 # Wx::XRC_NO_SUBCLASSING
  59.     xml.init_all_handlers
  60.     xml.load("noname.xrc")
  61.     xml.load_dialog_subclass(self, parent, "MyDialog1")
  62.  
  63.     finder = lambda do | x |
  64.       int_id = Wx::xrcid(x)
  65.       begin
  66.         Wx::Window.find_window_by_id(int_id, self) || int_id
  67.       # Temporary hack to work around regression in 1.9.2; remove
  68.       # begin/rescue clause in later versions
  69.       rescue RuntimeError
  70.         int_id
  71.       end
  72.     end
  73.  
  74.     @m_notebook1 = finder.call("m_notebook1")
  75.     @m_panel1 = finder.call("m_panel1")
  76.     @m_statictext1 = finder.call("m_staticText1")
  77.     @m_spinctrl1 = finder.call("m_spinCtrl1")
  78.     @m_statictext2 = finder.call("m_staticText2")
  79.     @m_spinctrl2 = finder.call("m_spinCtrl2")
  80.     @m_panel2 = finder.call("m_panel2")
  81.     @pos_lu = finder.call("pos_lu")
  82.     @pos_ru = finder.call("pos_ru")
  83.     @pos_lb = finder.call("pos_lb")
  84.     @pos_rb = finder.call("pos_rb")
  85.     @stayontop = finder.call("stayontop")
  86.     @m_panel3 = finder.call("m_panel3")
  87.     @m_statictext3 = finder.call("m_staticText3")
  88.     @clock_size_sldr = finder.call("clock_size_sldr")
  89.     @m_statictext31 = finder.call("m_staticText31")
  90.     @circle_offset_sldr = finder.call("circle_offset_sldr")
  91.     @m_statictext4 = finder.call("m_staticText4")
  92.     @tick_sldr = finder.call("tick_sldr")
  93.     @m_panel4 = finder.call("m_panel4")
  94.     @m_statictext5 = finder.call("m_staticText5")
  95.     @fontname = finder.call("fontname")
  96.     @font_browse = finder.call("font_browse")
  97.     @m_statictext6 = finder.call("m_staticText6")
  98.     @font_size = finder.call("font_size")
  99.     if self.class.method_defined? "on_init"
  100.       self.on_init()
  101.     end
  102.   end
  103. end

オプションダイアログを実装したコード。

  1. begin
  2.   require 'rubygems'
  3. rescue LoadError
  4. end
  5. require 'yaml'
  6. require 'wx'
  7. require 'RTC.rb'
  8.  
  9. CONFIG_FILENAME = 'rtc_config'
  10.  
  11. class RubyThroughClock < RTC
  12.   attr_accessor :rtc_config
  13.  
  14.   def initialize(parent = nil)
  15.     super()
  16.     # Load configuration file
  17.     begin
  18.       File.open(CONFIG_FILENAME,'r') do |f|
  19.         @rtc_config = YAML.load(f)
  20.         @rtc_config.init
  21.       end
  22.     rescue => e
  23.       puts 'config err: ', e
  24.       @rtc_config = RTC_config.new
  25.     end
  26.     set_background_colour(Wx::BLACK)
  27.     # Create taskbar icon
  28.     @tbicon = RTC_TaskBarIcon.new(self)
  29.     # structure for testing
  30.     @time = Struct.new('Time', :hour, :min).new
  31.     @time.hour = 0
  32.     @time.min = 0
  33.     @prev_time = @time.dup
  34.     # Create Buffer Bitmap
  35.     createBuffer()
  36.     # Event handler
  37.     evt_paint(){|event| drawClock()}
  38.     evt_size(){|event| onSize(event)}
  39.     evt_close(){|event| onClose(event)}
  40.     #m_spinctrl1.evt_spinctrl(m_spinctrl1.get_id()){|event| updateHour(event)}
  41.     #m_spinctrl2.evt_spinctrl(m_spinctrl2.get_id()){|event| updateMin(event)}
  42.     @m_timer = Wx::Timer.new(self)
  43.     evt_timer(@m_timer.get_id()) { |event| onTimer(event)}
  44.     #@m_timer.start(500)
  45.     # Frame size
  46.     set_size(Wx::Size.new(@rtc_config.clock_size, @rtc_config.clock_size))
  47.     move(@rtc_config.position.x, @rtc_config.position.y)
  48.   end
  49.  
  50.   def createBuffer()
  51.     size = get_client_size()
  52.     @img = Wx::Image.new(size.get_width, size.get_height)
  53.     @img.init_alpha
  54.   end
  55.  
  56.   def drawClock()
  57.     @buffer = @img.convert_to_bitmap
  58.     @buffer.draw do |dc|
  59.       # Create Graphics Context from Memory DC
  60.       gc = Wx::GraphicsContext.create(dc)
  61.       dc.set_background(Wx::TRANSPARENT_BRUSH)
  62.       #dc.set_background_mode(Wx::TRANSPARENT)
  63.       # Clear DC
  64.       dc.clear
  65.       # Get current time
  66.       #time = Time.now
  67.       time = @time
  68.       # Draw the current time
  69.       time_str = "%02d" % time.hour.to_s + ':' + "%02d" % time.min.to_s
  70.       colour = @rtc_config.getColour(@rtc_config.time_text_color)
  71.       dc.set_text_foreground(colour)
  72.       dc.draw_text(time_str, @rtc_config.time_text_pos_offset.x, @rtc_config.time_text_pos_offset.y)
  73.       # Offset X Y position
  74.       gc.translate(@rtc_config.clock_size / 2, @rtc_config.clock_size / 2)
  75.       # Draw Circle
  76.       drawCircle(gc, @rtc_config)
  77.       # Draw Hour hand
  78.       hour_offset =  Math::PI * 6 * (time.min / 12) / 180
  79.       drawHand(gc, @rtc_config.hour_hand, Math::PI * ( 30 * (time.hour % 12)) / 180 + hour_offset)
  80.       # Draw Min hand
  81.       drawHand(gc, @rtc_config.min_hand, Math::PI * ( 6 * time.min ) / 180)
  82.     end
  83.     r = Wx::Region.new(@buffer)
  84.     set_shape(r)
  85.     paint do |dc|
  86.       dc.draw_bitmap(@buffer, 0, 0, true)
  87.     end
  88.   end
  89.  
  90.   def drawHand(gc, hand, radians)
  91.     path = gc.create_path
  92.     mt   = gc.get_transform
  93.     # Set Hand Polygon
  94.     hand.polygon.each do |xy|
  95.       path.add_line_to_point(xy[0], xy[1])
  96.     end
  97.     path.close_subpath
  98.     # Move Hand
  99.     gc.rotate(radians)
  100.     # Pen Setting
  101.     color = hand.pen_color
  102.     colour = Wx::Colour.new(color.r, color.g, color.b)
  103.     gc.set_pen(Wx::Pen.new(colour, hand.pen_width))
  104.     # Brush Setting
  105.     color = hand.brush_color
  106.     colour = Wx::Colour.new(color.r, color.g, color.b)
  107.     gc.set_brush(Wx::Brush.new(colour))
  108.     gc.fill_path(path)
  109.     #gc.fill_path(path, Wx::WINDING_RULE)
  110.     #gc.stroke_path(path)
  111.     #gc.draw_path(path)
  112.     gc.set_transform(mt)
  113.   end
  114.  
  115.   def drawCircle(gc, cfg)
  116.     path = gc.create_path
  117.     mt   = gc.get_transform
  118.     # Font setting
  119.     font = cfg.fontdata.get_chosen_font()
  120.     colour = cfg.getColour(cfg.font.color)
  121.     gc.set_font(font,colour)
  122.     # Calculate Radius
  123.     radius = cfg.clock_size - cfg.circle_offset
  124.     # Set Path
  125.     path.add_circle(0, 0, radius * 4 / 5 - font.get_point_size)
  126.     # Pen Setting
  127.     colour = cfg.getColour(cfg.circle_color)
  128.     pen = (Wx::Pen.new(colour, cfg.circle_pen_width))
  129.     gc.set_pen(pen)
  130.     # Draw Circle
  131.     gc.draw_path(path)
  132.     # Offset X Y position
  133.     gc.translate(-font.get_point_size / 2, -font.get_point_size / 2 - 5)
  134.     # Set the number of hour
  135.     gc.rotate(Math::PI)
  136.     for hour in 1..12
  137.       gc.rotate(Math::PI * 30  / 180)
  138.       gc.draw_text(hour.to_s, 0, radius * 4 / 5, Math::PI * (30 * hour + 180)  / 180)
  139.     end
  140.     gc.set_transform(mt)
  141.   end
  142.   #
  143.   # Event processing
  144.   #
  145.   def onTimer(event)
  146.     unless @prev_time.min == Time.now.min
  147.       @prev_time = Time.now
  148.       onSize(event)
  149.     end
  150.   end
  151.  
  152.   def onSize(event)
  153.     createBuffer()
  154.     refresh
  155.   end
  156.  
  157.   def onClose(event)
  158.     File.open(CONFIG_FILENAME,'w') do |f|
  159.       YAML.dump(@rtc_config,f)
  160.     end
  161.     @tbicon.remove_icon
  162.     @tbicon.destroy
  163.     event.skip
  164.   end
  165.  
  166.   def updateHour(event)
  167.     @time.hour = event.get_position
  168.     refresh
  169.   end
  170.  
  171.   def updateMin(event)
  172.     @time.min = event.get_position
  173.     refresh
  174.   end
  175.  
  176.   def showOption(event)
  177.     opt = RTC_OptionDiag.new(self)
  178.     case opt.show_modal
  179.     when Wx::ID_OK # user clicked ok
  180.  
  181.     when Wx::ID_APPLY # user clicked apply
  182.  
  183.     when Wx::ID_CANCEL # user clicked cancel or closed the dialog
  184.  
  185.     end
  186.   end
  187.  
  188.   def onStay_on_top(event)
  189.     flag = get_window_style_flag
  190.     if event.is_checked
  191.       flag = flag | Wx::STAY_ON_TOP
  192.     else
  193.       flag = flag ^ Wx::STAY_ON_TOP
  194.     end
  195.     set_window_style_flag(flag)
  196.     @rtc_config.stayontop = event.is_checked
  197.     refresh
  198.   end
  199.  
  200.   def moveRU(event)
  201.     rect = Wx::Display.new.get_client_area
  202.     width = get_screen_rect.get_width
  203.     point = rect.get_top_right
  204.     @rtc_config.position.x = point.x - width
  205.     @rtc_config.position.y = point.y
  206.     move(@rtc_config.position.x, @rtc_config.position.y)
  207.   end
  208.  
  209.   def moveRB(event)
  210.     rect = Wx::Display.new.get_client_area
  211.     width = get_screen_rect.get_width
  212.     height = get_screen_rect.get_height
  213.     point = rect.get_bottom_right
  214.     @rtc_config.position.x = point.x - width
  215.     @rtc_config.position.y = point.y - height
  216.     move(@rtc_config.position.x, @rtc_config.position.y)
  217.   end
  218.  
  219.   def moveLU(event)
  220.     rect = Wx::Display.new.get_client_area
  221.     point = rect.get_top_left
  222.     @rtc_config.position.x = point.x
  223.     @rtc_config.position.y = point.y
  224.     move(@rtc_config.position.x, @rtc_config.position.y)
  225.   end
  226.  
  227.   def moveLB(event)
  228.     rect = Wx::Display.new.get_client_area
  229.     height = get_screen_rect.get_height
  230.     point = rect.get_bottom_left
  231.     @rtc_config.position.x = point.x
  232.     @rtc_config.position.y = point.y - height
  233.     move(@rtc_config.position.x, @rtc_config.position.y)
  234.   end
  235.  
  236. end
  237.  
  238. class RTC_config
  239.   attr_accessor :clock_size, :time_text_color, :time_text_pos_offset,
  240.   :circle_offset, :circle_color, :circle_pen_width,
  241.   :hour_hand, :min_hand, :tick_mark_size,
  242.   :stayontop, :position, :fontdata, :font
  243.  
  244.   def initialize
  245.     super()
  246.     @clock_size ||= 300
  247.     @time_text_color ||= getColor(Wx::GREEN)
  248.     @time_text_pos_offset ||= Struct.new('Point', :x, :y).new(5, @clock_size -30)
  249.     @tick_mark_size ||= 10
  250.     @circle_offset ||= @clock_size / 2
  251.     @circle_color ||= getColor(Wx::RED)
  252.     @circle_pen_width ||= 3
  253.     @hour_hand ||= Struct.new('Hand', :polygon, :pen_color, :pen_width, :brush_color).new
  254.     @hour_hand.polygon ||= [ [0, @clock_size / 30], [-5, 0], [0, - @clock_size / 4], [5, 0] ]
  255.     @hour_hand.pen_color ||= getColor(Wx::BLACK)
  256.     @hour_hand.pen_width ||= 1
  257.     @hour_hand.brush_color ||= getColor(Wx::CYAN)
  258.     @min_hand ||= Struct::Hand.new
  259.     @min_hand.polygon ||= [ [0, @clock_size / 30], [-5, 0], [0, - @clock_size * 2 / 5], [5, 0] ]
  260.     @min_hand.pen_color ||= getColor(Wx::BLACK)
  261.     @min_hand.pen_width ||= 1
  262.     @min_hand.brush_color ||= getColor(Wx::BLUE)
  263.     @stayontop ||= true
  264.     @position ||= Struct::Point.new(0,0)
  265.     @font ||= Struct.new('Font', :color, :size, :name, :style, :weight).new
  266.     @font.color ||= getColor(Wx::GREEN)
  267.     @font.size ||= 18
  268.     @font.name ||= ''
  269.     @font.style ||= Wx::FONTSTYLE_NORMAL
  270.     @font.weight ||= Wx::FONTWEIGHT_NORMAL
  271.     init()
  272.   end
  273.  
  274.   def init
  275.     font = Wx::Font.new
  276.     font.set_point_size(@font.size)
  277.     font.set_face_name(@font.name)
  278.     font.set_style(@font.style)
  279.     font.set_weight(@font.weight)
  280.     @fontdata ||= Wx::FontData.new
  281.     @fontdata.set_initial_font(font)
  282.     @fontdata.set_chosen_font(font)
  283.     @fontdata.set_colour(getColour(@font.color))
  284.   end
  285.  
  286.   def getColor(obj)
  287.     return Struct.new('Color', :r, :g, :b).new(obj.red, obj.green, obj.blue)
  288.   end
  289.  
  290.   def getColour(obj)
  291.     return Wx::Colour.new(obj.r, obj.g, obj.b)
  292.   end
  293.  
  294.   def to_yaml_properties
  295.     arr = self.instance_variables
  296.     arr.delete('@fontdata')
  297.     return arr
  298.   end
  299.  
  300. end
  301.  
  302. class RTC_OptionDiag < RTC_Option
  303.   def initialize(frame)
  304.     super()
  305.     @frame = frame
  306.     @fontdata = @frame.rtc_config.fontdata
  307.  
  308.     stayontop.set_value(@frame.rtc_config.stayontop)
  309.     clock_size_sldr.set_value(@frame.rtc_config.clock_size)
  310.     circle_offset_sldr.set_value(@frame.rtc_config.circle_offset)
  311.     circle_offset_sldr.set_range(clock_size_sldr.get_min, clock_size_sldr.get_value)
  312.     tick_sldr.set_value(@frame.rtc_config.tick_mark_size)
  313.     clock_size_sldr.set_tick_freq(clock_size_sldr.get_max / 10,1)
  314.     circle_offset_sldr.set_tick_freq(circle_offset_sldr.get_max / 10,1)
  315.     tick_sldr.set_tick_freq(tick_sldr.get_max / 10,1)
  316.     font = @fontdata.get_chosen_font
  317.     fontname.set_value(font.get_face_name)
  318.     font_size.set_value(font.get_point_size)
  319.     # Event handler
  320.     stayontop.evt_checkbox(stayontop.get_id()){|event| onStay_on_top(event)}
  321.     m_spinctrl1.evt_spinctrl(m_spinctrl1.get_id()){|event| @frame.updateHour(event)}
  322.     m_spinctrl2.evt_spinctrl(m_spinctrl2.get_id()){|event| @frame.updateMin(event)}
  323.     pos_ru.evt_button(pos_ru.get_id()){|event| @frame.moveRU(event)}
  324.     pos_lu.evt_button(pos_lu.get_id()){|event| @frame.moveLU(event)}
  325.     pos_rb.evt_button(pos_rb.get_id()){|event| @frame.moveRB(event)}
  326.     pos_lb.evt_button(pos_lb.get_id()){|event| @frame.moveLB(event)}
  327.     clock_size_sldr.evt_slider(clock_size_sldr.get_id()){|event| onSlider_clock_size()}
  328.     circle_offset_sldr.evt_slider(circle_offset_sldr.get_id()){|event| @frame.rtc_config.circle_offset = circle_offset_sldr.get_value; @frame.refresh}
  329.     #tick_sldr.evt_scroll(tick_sldr.get_id()){|event| size = event.get_value; set_size(Wx::Size.new(size,size))}
  330.     font_browse.evt_button(font_browse.get_id()){|event| chooseFont(event)}
  331.     font_size.evt_spinctrl(font_size.get_id()){|event| changeFontsize(event)}
  332.   end
  333.  
  334.   def onSlider_clock_size()
  335.     size = clock_size_sldr.get_value;
  336.     circle_offset_sldr.set_range(clock_size_sldr.get_min, size);
  337.     if circle_offset_sldr.get_max <= circle_offset_sldr.get_value
  338.       circle_offset_sldr.set_value(circle_offset_sldr.get_max)
  339.     end
  340.     @frame.set_size(Wx::Size.new(size,size));
  341.     @frame.rtc_config.clock_size = size
  342.   end
  343.  
  344.   def onStay_on_top(event)
  345.     @frame.onStay_on_top(event)
  346.   end
  347.  
  348.   def chooseFont(event)
  349.     fontdiag = Wx::FontDialog.new(self, @fontdata);
  350.     case fontdiag.show_modal
  351.     when Wx::ID_OK # user clicked ok
  352.       @fontdata = fontdiag.get_font_data
  353.       font = @fontdata.get_chosen_font
  354.       fontname.set_value(font.get_face_name)
  355.       font_size.set_value(font.get_point_size)
  356.       # Store FontData to config
  357.       @frame.rtc_config.fontdata@fontdata
  358.       color =  @frame.rtc_config.getColor(@fontdata.get_colour)
  359.       @frame.rtc_config.font.color =  color
  360.       @frame.rtc_config.font.size =  font.get_point_size
  361.       @frame.rtc_config.font.name =  font.get_face_name
  362.       @frame.rtc_config.font.style =  font.get_style
  363.       @frame.rtc_config.font.weight = font.get_weight
  364.       @frame.refresh
  365.     when Wx::ID_CANCEL # user clicked cancel or closed the dialog
  366.     end
  367.   end
  368.  
  369.   def changeFontsize(event)
  370.     font = @fontdata.get_chosen_font
  371.     font.set_point_size(event.get_position)
  372.     @fontdata.set_chosen_font(font)
  373.     @frame.rtc_config.font.size = font.get_point_size
  374.   end
  375. end
  376.  
  377. class RTC_TaskBarIcon < Wx::TaskBarIcon
  378.   # Event ID
  379.   TBMENU_OPTION      = Wx::ID_HIGHEST + 1
  380.   TBMENU_STAY_ON_TOP = Wx::ID_HIGHEST + 2
  381.   TBMENU_MOVE_RU     = Wx::ID_HIGHEST + 3
  382.   TBMENU_MOVE_RB     = Wx::ID_HIGHEST + 4
  383.   TBMENU_MOVE_LU     = Wx::ID_HIGHEST + 5
  384.   TBMENU_MOVE_LB     = Wx::ID_HIGHEST + 6
  385.   TBMENU_EXIT        = Wx::ID_HIGHEST + 7
  386.  
  387.   def initialize(frame)
  388.     super()
  389.     @frame = frame
  390.     @stay_on_top = @frame.rtc_config.stayontop
  391.     # starting image
  392.     icon = make_icon('ruby.png')
  393.     set_icon(icon, 'RubyThroughClock')
  394.     # Menu Event
  395.     evt_menu(TBMENU_OPTION)      {|event| @frame.showOption(event) }
  396.     evt_menu(TBMENU_STAY_ON_TOP) {|event| onTB_stay_on_top(event) }
  397.     evt_menu(TBMENU_MOVE_RU)     {|event| @frame.moveRU(event) }
  398.     evt_menu(TBMENU_MOVE_RB)     {|event| @frame.moveRB(event) }
  399.     evt_menu(TBMENU_MOVE_LU)     {|event| @frame.moveLU(event) }
  400.     evt_menu(TBMENU_MOVE_LB)     {|event| @frame.moveLB(event) }
  401.     evt_menu(TBMENU_EXIT)        {|event| @frame.close }
  402.   end
  403.  
  404.   def onTB_stay_on_top(event)
  405.     @stay_on_top = event.is_checked
  406.     @frame.onStay_on_top(event)
  407.   end
  408.  
  409.   def make_icon(imgname)
  410.     # Different platforms have different requirements for the
  411.     #  taskbar icon size
  412.     filename = File.join( File.dirname(__FILE__), imgname )
  413.     img = Wx::Image.new(filename, Wx::BITMAP_TYPE_PNG)
  414.     img.set_mask
  415.     if Wx::PLATFORM == "WXMSW"
  416.       img = img.scale(16, 16)
  417.     elsif Wx::PLATFORM == "WXGTK"
  418.       img = img.scale(22, 22)
  419.     end
  420.     # WXMAC can be any size up to 128x128, so don't scale
  421.     icon = Wx::Icon.new
  422.     icon.copy_from_bitmap(Wx::Bitmap.new(img))
  423.     return icon
  424.   end
  425.  
  426.   def create_popup_menu
  427.     # Called by the base class when it needs to popup the menu
  428.     #  (the default evt_right_down event).  Create and return
  429.     #  the menu to display.
  430.     @stay_on_top = @frame.rtc_config.stayontop
  431.     menu = Wx::Menu.new
  432.     menu.append(TBMENU_OPTION,     "Option")
  433.     menu.append_check_item(TBMENU_STAY_ON_TOP,"Stay On Top")
  434.     menu.check(TBMENU_STAY_ON_TOP, @stay_on_top)
  435.     submenu = Wx::Menu.new
  436.     submenu.append(TBMENU_MOVE_RU, "Right Upper")
  437.     submenu.append(TBMENU_MOVE_RB, "Right Bottom")
  438.     submenu.append(TBMENU_MOVE_LU, "Left Upper")
  439.     submenu.append(TBMENU_MOVE_LB, "Left Bottom")
  440.     menu.append_menu(Wx::ID_ANY,   "Move",submenu)
  441.     menu.append(TBMENU_EXIT,       "Exit")
  442.     return menu
  443.   end
  444. end
  445.  
  446. class App < Wx::App
  447.   def on_init
  448.     f =  ::RubyThroughClock.new
  449.     f.show
  450.   end
  451. end
  452. App.new.main_loop
  453.  

オプションダイアログの画面です。大きく分けて4種類作っています。

01

02

03

04_2


|

« 時計をつくる5 | トップページ | PC壊れた »

時計をつくる」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.f.cocolog-nifty.com/t/trackback/1201593/29985045

この記事へのトラックバック一覧です: 時計をつくる6:

« 時計をつくる5 | トップページ | PC壊れた »