Skip to content
Snippets Groups Projects
datatarget.rb 9.03 KiB
Newer Older
  • Learn to ignore specific revisions
  • #!/usr/bin/env ruby
    
    require 'fox16'
    require 'fox16/colors'
    
    include Fox
    
    BLURB = <<END
    FXDataTarget can be used to connect a widget to an application variable without any of the
    tradional "glue" programming code.
    
    The widgets below are connected (via FXDataTarget) to an integer, real, string, option, and
    color variable, respectively.
    
    Changing one of them will cause all widgets connected to the same FXDataTarget to
    update so as to reflect the value of the application variable.
    
    The progress bar below shows a time-varying variable, demonstrating that widgets
    can be updated via FXDataTarget's regardless how the variables are changed.
    
    Note that the "Option" pulldown menu is also connected to the option variable!
    END
    
    class DataTargetWindow < FXMainWindow
      def initialize(app)
        # Initialize base class
        super(app, "Data Targets Test", :opts => DECOR_ALL, :x => 20, :y => 20, :width => 700, :height => 460)
    
        # Create a data target with an integer value
        @intTarget = FXDataTarget.new(10)
    
        # Create a data target with a floating point value
        @floatTarget = FXDataTarget.new(3.1415927)
    
        # Create a data target with a string value
        @stringTarget = FXDataTarget.new("FOX")
    
        # Create a data target with a color value
        @colorTarget = FXDataTarget.new(FXColor::Red)
    
        # Create an integer data target to track the selected option
        @optionTarget = FXDataTarget.new(1)
    
        # Create another integer data target to track the "progress"
        @progressTarget = FXDataTarget.new(0)
    
        # Menubar
        menubar = FXMenuBar.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
        
        # File menu
        filemenu = FXMenuPane.new(self)
        FXMenuCommand.new(filemenu, "Progress dialog...").connect(SEL_COMMAND) do
          @progressdialog.show(PLACEMENT_OWNER)
        end
        FXMenuCommand.new(filemenu, "&Quit\tCtl-Q", nil, getApp(), FXApp::ID_QUIT)
        FXMenuTitle.new(menubar, "&File", nil, filemenu)
    
        # Create a progress dialog that's also tied into the integer data target's value
        @progressdialog = FXProgressDialog.new(self, "Progress", "Incoming...", PROGRESSDIALOG_CANCEL|DECOR_BORDER|DECOR_RESIZE)
        @progressdialog.target = @intTarget
        @progressdialog.selector = FXDataTarget::ID_VALUE
    
        # Option menu
        optionmenu = FXMenuPane.new(self)
        FXMenuCheck.new(optionmenu, "Option 1", @optionTarget, FXDataTarget::ID_OPTION+1)
        FXMenuCheck.new(optionmenu, "Option 2", @optionTarget, FXDataTarget::ID_OPTION+2)
        FXMenuCheck.new(optionmenu, "Option 3", @optionTarget, FXDataTarget::ID_OPTION+3)
        FXMenuCheck.new(optionmenu, "Option 4", @optionTarget, FXDataTarget::ID_OPTION+4)
        FXMenuTitle.new(menubar, "&Option", nil, optionmenu)
    
        # Lone progress bar at the bottom
        FXProgressBar.new(self, @progressTarget, FXDataTarget::ID_VALUE,
          LAYOUT_SIDE_BOTTOM|LAYOUT_FILL_X|FRAME_SUNKEN|FRAME_THICK)
    
        FXHorizontalSeparator.new(self,
          LAYOUT_SIDE_TOP|SEPARATOR_GROOVE|LAYOUT_FILL_X)
    
        horframe = FXHorizontalFrame.new(self, LAYOUT_SIDE_TOP | LAYOUT_FILL_X)
        FXLabel.new(horframe, BLURB, nil, LAYOUT_SIDE_TOP | JUSTIFY_LEFT)
    
        FXProgressBar.new(horframe, @intTarget, FXDataTarget::ID_VALUE,
          PROGRESSBAR_PERCENTAGE | PROGRESSBAR_DIAL | LAYOUT_SIDE_TOP |
          LAYOUT_SIDE_RIGHT | LAYOUT_RIGHT | LAYOUT_FILL_Y | LAYOUT_FILL_X)
    
        FXHorizontalSeparator.new(self,
          LAYOUT_SIDE_TOP|SEPARATOR_GROOVE|LAYOUT_FILL_X)
        FXSlider.new(self, @intTarget, FXDataTarget::ID_VALUE, (SLIDER_VERTICAL|
          SLIDER_INSIDE_BAR|LAYOUT_SIDE_RIGHT|LAYOUT_FILL_Y|LAYOUT_FIX_WIDTH),
          :width => 20)
    
        # Arrange nicely
        matrix = FXMatrix.new(self, 7,
          MATRIX_BY_COLUMNS|LAYOUT_SIDE_TOP|LAYOUT_FILL_X|LAYOUT_FILL_Y)
    
        # First row
        FXLabel.new(matrix, "&Integer", nil,
          LAYOUT_CENTER_Y|LAYOUT_CENTER_X|JUSTIFY_RIGHT|LAYOUT_FILL_ROW)
        FXTextField.new(matrix, 10, @intTarget, FXDataTarget::ID_VALUE,
          LAYOUT_CENTER_Y|LAYOUT_CENTER_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_ROW)
        FXTextField.new(matrix, 10, @intTarget, FXDataTarget::ID_VALUE,
          LAYOUT_CENTER_Y|LAYOUT_CENTER_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_ROW)
        FXSlider.new(matrix, @intTarget, FXDataTarget::ID_VALUE,
          LAYOUT_CENTER_Y|LAYOUT_FILL_ROW|LAYOUT_FIX_WIDTH, :width => 100)
        FXDial.new(matrix, @intTarget, FXDataTarget::ID_VALUE, (LAYOUT_CENTER_Y|
          LAYOUT_FILL_ROW|LAYOUT_FIX_WIDTH|DIAL_HORIZONTAL|DIAL_HAS_NOTCH),
          :width => 100)
        FXSpinner.new(matrix, 5, @intTarget, FXDataTarget::ID_VALUE,
          SPIN_CYCLIC|FRAME_SUNKEN|FRAME_THICK|LAYOUT_CENTER_Y|LAYOUT_FILL_ROW)
        FXProgressBar.new(matrix, @intTarget, FXDataTarget::ID_VALUE,
          (LAYOUT_CENTER_Y|LAYOUT_FILL_X|FRAME_SUNKEN|FRAME_THICK|
          PROGRESSBAR_PERCENTAGE|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW))
    
        # Second row
        FXLabel.new(matrix, "&Real", nil,
          LAYOUT_CENTER_Y|LAYOUT_CENTER_X|JUSTIFY_RIGHT|LAYOUT_FILL_ROW)
        FXTextField.new(matrix, 10, @floatTarget, FXDataTarget::ID_VALUE,
          (TEXTFIELD_REAL|LAYOUT_CENTER_Y|LAYOUT_CENTER_X|
          FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_ROW))
        FXTextField.new(matrix, 10, @floatTarget, FXDataTarget::ID_VALUE,
          (TEXTFIELD_REAL|LAYOUT_CENTER_Y|LAYOUT_CENTER_X|
          FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_ROW))
        FXSlider.new(matrix, @floatTarget, FXDataTarget::ID_VALUE,
          LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW|LAYOUT_FIX_WIDTH, :width => 100)
        FXDial.new(matrix, @floatTarget, FXDataTarget::ID_VALUE,
          (LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW|LAYOUT_FIX_WIDTH|
          DIAL_HORIZONTAL|DIAL_HAS_NOTCH), :width => 100)
    
        FXFrame.new(matrix, LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW)
        FXFrame.new(matrix, LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW)
    
        # Third row
        FXLabel.new(matrix, "&String", nil,
          LAYOUT_CENTER_Y|LAYOUT_CENTER_X|JUSTIFY_RIGHT|LAYOUT_FILL_ROW)
        FXTextField.new(matrix, 10, @stringTarget, FXDataTarget::ID_VALUE,
          LAYOUT_CENTER_Y|LAYOUT_CENTER_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_ROW)
        FXTextField.new(matrix, 10, @stringTarget, FXDataTarget::ID_VALUE,
          LAYOUT_CENTER_Y|LAYOUT_CENTER_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_ROW)
        FXFrame.new(matrix, LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW)
        FXFrame.new(matrix, LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW)
        FXFrame.new(matrix, LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW)
        FXFrame.new(matrix, LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW)
    
        # Fourth row
        FXLabel.new(matrix, "&Option", nil,
          LAYOUT_CENTER_Y|LAYOUT_CENTER_X|JUSTIFY_RIGHT|LAYOUT_FILL_ROW)
        FXTextField.new(matrix, 10, @optionTarget, FXDataTarget::ID_VALUE,
          (TEXTFIELD_INTEGER|LAYOUT_CENTER_Y|LAYOUT_CENTER_X|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_ROW))
        FXRadioButton.new(matrix, "Option &1",
          @optionTarget, FXDataTarget::ID_OPTION + 1,
          LAYOUT_CENTER_Y|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW|ICON_BEFORE_TEXT)
        FXRadioButton.new(matrix, "Option &2",
          @optionTarget, FXDataTarget::ID_OPTION + 2,
          LAYOUT_CENTER_Y|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW|ICON_BEFORE_TEXT)
        FXRadioButton.new(matrix, "Option &3",
          @optionTarget, FXDataTarget::ID_OPTION + 3,
          LAYOUT_CENTER_Y|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW|ICON_BEFORE_TEXT)
        FXRadioButton.new(matrix, "Option &4",
          @optionTarget, FXDataTarget::ID_OPTION + 4,
          LAYOUT_CENTER_Y|LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW|ICON_BEFORE_TEXT)
        FXFrame.new(matrix, LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW)
    
        # Fifth
        FXLabel.new(matrix, "&Color", nil,
          LAYOUT_CENTER_Y|LAYOUT_CENTER_X|JUSTIFY_RIGHT|LAYOUT_FILL_ROW)
        FXColorWell.new(matrix, 0, @colorTarget, FXDataTarget::ID_VALUE,
          LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW, :padLeft => 0, :padRight => 0, :padTop => 0, :padBottom => 0)
        FXColorWell.new(matrix, 0, @colorTarget, FXDataTarget::ID_VALUE,
          LAYOUT_CENTER_Y|LAYOUT_FILL_X|LAYOUT_FILL_ROW, :padLeft => 0, :padRight => 0, :padTop => 0, :padBottom => 0)
        FXFrame.new(matrix, LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW)
        FXFrame.new(matrix, LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW)
        FXFrame.new(matrix, LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW)
        FXFrame.new(matrix, LAYOUT_FILL_COLUMN|LAYOUT_FILL_ROW)
    
        # Install an accelerator
        self.accelTable.addAccel(fxparseAccel("Ctl-Q"), getApp(), FXSEL(SEL_COMMAND, FXApp::ID_QUIT))
      end
    
      # Timer expired; update the progress
      def onTimeout(sender, sel, ptr)
        # Increment the progress modulo 100
        @progressTarget.value = (@progressTarget.value + 1) % 100
      
        # Reset the timer for next time
        getApp().addTimeout(80, method(:onTimeout))
      end
    
        # Quit
        def onCmdQuit(sender, sel, ptr)
          getApp.exit(0)
        end
    
      # Start
      def create
        # Create window
        super
    
        # Kick off the timer
        getApp().addTimeout(80, method(:onTimeout))
    
        # Show the main window
        show(PLACEMENT_SCREEN)
      end
    end
    
    if __FILE__ == $0
      # Make an application
      application = FXApp.new("DataTarget", "FoxTest")
    
      # Current threads implementation causes problems for this example, so disable
      application.threadsEnabled = false
    
      # Create main window
      window = DataTargetWindow.new(application)
    
      # Handle interrupts to quit application gracefully
      application.addSignal("SIGINT", window.method(:onCmdQuit))
    
      # Create the application
      application.create
    
      # Run
      application.run
    end