Skip to content
Snippets Groups Projects
dctest.rb 27.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • require 'fox16'
    
    include Fox
    
    $bitmap_bits = [
       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0xc0, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
       0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x11, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x88, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84,
       0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x81, 0x00, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x81, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
       0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x01, 0x04, 0x00, 0x00,
       0x00, 0x00, 0x20, 0x80, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80,
       0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0x01, 0x20, 0x00, 0x00,
       0x00, 0x00, 0x04, 0x80, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x02, 0x80,
       0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x01, 0x00,
       0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0x00, 0x80,
       0x01, 0x00, 0x04, 0x00, 0x00, 0x20, 0x00, 0x80, 0x01, 0x00, 0x08, 0x00,
       0x00, 0x10, 0x00, 0x80, 0x01, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00, 0x80,
       0x01, 0x00, 0x20, 0x00, 0x00, 0x04, 0x00, 0x80, 0x01, 0x00, 0x40, 0x00,
       0x00, 0x02, 0x00, 0x80, 0x01, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x80,
       0x01, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x02,
       0x40, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x80,
       0x01, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x10,
       0x08, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x80,
       0x01, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,
       0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,
       0x01, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x20,
       0x04, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x80,
       0x01, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x04,
       0x20, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x80,
       0x01, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x80, 0x01, 0x00, 0x80, 0x00,
       0x00, 0x01, 0x00, 0x80, 0x01, 0x00, 0x40, 0x00, 0x00, 0x02, 0x00, 0x80,
       0x01, 0x00, 0x20, 0x00, 0x00, 0x04, 0x00, 0x80, 0x01, 0x00, 0x10, 0x00,
       0x00, 0x08, 0x00, 0x80, 0x01, 0x00, 0x08, 0x00, 0x00, 0x10, 0x00, 0x80,
       0x01, 0x00, 0x04, 0x00, 0x00, 0x20, 0x00, 0x80, 0x01, 0x00, 0x02, 0x00,
       0x00, 0x40, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x80,
       0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xff, 0xff, 0x00, 0x00,
       0x00, 0x00, 0x02, 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80,
       0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0xff, 0xff, 0x00, 0x00,
       0x00, 0x00, 0x10, 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x20, 0x80,
       0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0xff, 0xff, 0x00, 0x00,
       0x00, 0x00, 0x80, 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
       0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0xff, 0xff, 0x00, 0x00,
       0x00, 0x00, 0x00, 0x84, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
       0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xff, 0xff, 0x00, 0x00,
       0x00, 0x00, 0x00, 0xa0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
    
    $bitmap_bits = $bitmap_bits.pack("c*")
    
    $blit_modes = {
      BLT_CLR => "Clear\tBLT_CLR",
      BLT_SRC_AND_DST => "And\tBLT_SRC_AND_DST",
      BLT_SRC_AND_NOT_DST => "AndRev\tBLT_SRC_AND_NOT_DST",
      BLT_SRC => "Copy\tBLT_SRC",
      BLT_NOT_SRC_AND_DST => "AndInv\tBLT_NOT_SRC_AND_DST",
      BLT_DST=> "NoOp\tBLT_DST",
      BLT_SRC_XOR_DST => "Xor\tBLT_SRC_XOR_DST",
      BLT_SRC_OR_DST => "Or\tBLT_SRC_OR_DST",
      BLT_NOT_SRC_AND_NOT_DST => "Nor\tBLT_NOT_SRC_AND_NOT_DST",
      BLT_NOT_SRC_XOR_DST => "Equiv\tBLT_NOT_SRC_XOR_DST",
      BLT_NOT_DST => "Invert\tBLT_NOT_DST",
      BLT_SRC_OR_NOT_DST => "OrRev\tBLT_SRC_OR_NOT_DST",
      BLT_NOT_SRC => "CopyInv\tBLT_NOT_SRC",
      BLT_NOT_SRC_OR_DST => "OrInv\tBLT_NOT_SRC_OR_DST",
      BLT_NOT_SRC_OR_NOT_DST => "Nand\tBLT_NOT_SRC_OR_NOT_DST",
      BLT_SET => "Set\tBLT_SET"
    }
    
    $fill_styles = {
      FILL_SOLID => "FILL_SOLID",
      FILL_TILED => "FILL_TILED",
      FILL_STIPPLED => "FILL_STIPPLED",
      FILL_OPAQUESTIPPLED => "FILL_OPAQUESTIPPLED"
    }
    
    $stipples = {
      STIPPLE_NONE => "NONE\tSTIPPLE_NONE",
      STIPPLE_BLACK => "BLACK\tSTIPPLE_BLACK",
      STIPPLE_WHITE => "WHITE\tSTIPPLE_WHITE",
      STIPPLE_0 => "0\tSTIPPLE_0",
      STIPPLE_1 => "1\tSTIPPLE_1",
      STIPPLE_2 => "2\tSTIPPLE_2",
      STIPPLE_3 => "3\tSTIPPLE_3",
      STIPPLE_4 => "4\tSTIPPLE_4",
      STIPPLE_5 => "5\tSTIPPLE_5",
      STIPPLE_6 => "6\tSTIPPLE_6",
      STIPPLE_7 => "7\tSTIPPLE_7",
      STIPPLE_8 => "8\tSTIPPLE_8",
      STIPPLE_9 => "9\tSTIPPLE_9",
      STIPPLE_10 => "10\tSTIPPLE_10",
      STIPPLE_11 => "11\tSTIPPLE_11",
      STIPPLE_12 => "12\tSTIPPLE_12",
      STIPPLE_13 => "13\tSTIPPLE_13",
      STIPPLE_14 => "14\tSTIPPLE_14",
      STIPPLE_15 => "15\tSTIPPLE_15",
      STIPPLE_16 => "16\tSTIPPLE_16",
      STIPPLE_HORZ => "HORZ\tSTIPPLE_HORZ",
      STIPPLE_VERT => "VERT\tSTIPPLE_VERT",
      STIPPLE_CROSS => "CROSS\tSTIPPLE_CROSS",
      STIPPLE_DIAG => "DIAG\tSTIPPLE_DIAG",
      STIPPLE_REVDIAG => "REVDIAG\tSTIPPLE_REVDIAG",
      STIPPLE_CROSSDIAG => "CROSSDIAG\tSTIPPLE_CROSSDIAG",
    }
    
    class DCTestWindow < FXMainWindow
      def initialize(app)
        # Initialize base class first
        super(app, "Device Context Test", :opts => DECOR_ALL, :width => 850, :height => 740)
    
        opts = FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y
    
        # Preferred line attributes
        @lineStyle = LINE_SOLID
        @capStyle = CAP_BUTT
        @joinStyle = JOIN_MITER
    
        # Create a tooltip
        tooltip = FXToolTip.new(getApp())
    
        # Menu bar
        menubar = FXMenuBar.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X)
    
        # Separator
        FXHorizontalSeparator.new(self, LAYOUT_SIDE_TOP|LAYOUT_FILL_X|SEPARATOR_GROOVE)
    
        # Contents
        contents = FXHorizontalFrame.new(self, LAYOUT_SIDE_TOP|FRAME_NONE|LAYOUT_FILL_X|LAYOUT_FILL_Y|PACK_UNIFORM_WIDTH)
    
        # Controls on right
        controls = FXVerticalFrame.new(contents, LAYOUT_RIGHT|LAYOUT_FILL_Y)
    
        # Block for BLIT modes
        FXLabel.new(controls, "BLIT Function:", nil, LAYOUT_LEFT)
        blitgrid = FXMatrix.new(controls, 4, FRAME_RIDGE|MATRIX_BY_COLUMNS|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH,
          :padLeft => 2, :padRight => 2, :padTop => 2, :padBottom => 2)
    
        # One button for each mode
        $blit_modes.each do |blit_mode, desc|
          btn = FXButton.new(blitgrid, desc, :opts => BUTTON_TOOLBAR|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FILL_COLUMN)
          btn.userData = blit_mode
          btn.connect(SEL_COMMAND) do |sender, sel, ptr|
            @function = sender.userData
            @linesCanvas.update(0, 0, @linesCanvas.width, @linesCanvas.height)
          end
          btn.connect(SEL_UPDATE) do |sender, sel, ptr|
            if sender.userData == @function
              sender.handle(self, MKUINT(ID_CHECK, SEL_COMMAND), nil)
            else
              sender.handle(self, MKUINT(ID_UNCHECK, SEL_COMMAND), nil)
            end
          end
        end
    
        # Line dash style
        FXLabel.new(controls, "Line Style:", nil, LAYOUT_LEFT)
        linestyle = FXMatrix.new(controls, 3, FRAME_RIDGE|MATRIX_BY_COLUMNS|LAYOUT_FILL_X,
          :padLeft => 2, :padRight => 2, :padTop => 2, :padBottom => 2)
        lineSolidBtn = FXButton.new(linestyle, "\tLINE_SOLID", loadIcon("solid_line.png", 0, IMAGE_OPAQUE), :opts => BUTTON_TOOLBAR|JUSTIFY_CENTER_X|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FILL_COLUMN)
        lineSolidBtn.connect(SEL_COMMAND) do |sender, sel, ptr|
          @lineStyle = LINE_SOLID
          @linesCanvas.update(0, 0, @linesCanvas.width, @linesCanvas.height)
        end
        lineSolidBtn.connect(SEL_UPDATE) do |sender, sel, ptr|
          if @lineStyle == LINE_SOLID
            sender.handle(self, MKUINT(ID_CHECK, SEL_COMMAND), nil)
          else
            sender.handle(self, MKUINT(ID_UNCHECK, SEL_COMMAND), nil)
          end
        end
        lineOnOffDashBtn = FXButton.new(linestyle, "\tLINE_ONOFF_DASH", loadIcon("onoff_dash.png"), nil, 0, BUTTON_TOOLBAR|JUSTIFY_CENTER_X|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FILL_COLUMN)
        lineOnOffDashBtn.connect(SEL_COMMAND) do |sender, sel, ptr|
          @lineStyle = LINE_ONOFF_DASH
          @linesCanvas.update(0, 0, @linesCanvas.width, @linesCanvas.height)
        end
        lineOnOffDashBtn.connect(SEL_UPDATE) do |sender, sel, ptr|
          if @lineStyle == LINE_ONOFF_DASH
            sender.handle(self, MKUINT(ID_CHECK, SEL_COMMAND), nil)
          else
            sender.handle(self, MKUINT(ID_UNCHECK, SEL_COMMAND), nil)
          end
        end
        lineDoubleDashBtn = FXButton.new(linestyle, "\tLINE_DOUBLE_DASH", loadIcon("double_dash.png", 0,  IMAGE_OPAQUE), nil, 0, BUTTON_TOOLBAR|JUSTIFY_CENTER_X|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FILL_COLUMN)
        lineDoubleDashBtn.connect(SEL_COMMAND) do |sender, sel, ptr|
          @lineStyle = LINE_DOUBLE_DASH
          @linesCanvas.update(0, 0, @linesCanvas.width, @linesCanvas.height)
        end
        lineDoubleDashBtn.connect(SEL_UPDATE) do |sender, sel, ptr|
          if @lineStyle == LINE_DOUBLE_DASH
            sender.handle(self, MKUINT(ID_CHECK, SEL_COMMAND), nil)
          else
            sender.handle(self, MKUINT(ID_UNCHECK, SEL_COMMAND), nil)
          end
        end
    
        # Line cap style
        FXLabel.new(controls, "Cap Style:", nil, LAYOUT_LEFT)
        capstyle = FXMatrix.new(controls, 4, FRAME_RIDGE|MATRIX_BY_COLUMNS|LAYOUT_FILL_X)
        capstyle.padLeft = 2
        capstyle.padRight = 2
        capstyle.padTop = 2
        capstyle.padBottom = 2
        btn = FXButton.new(capstyle, "\tCAP_NOT_LAST", loadIcon("capnotlast.png"), nil, 0, BUTTON_TOOLBAR|JUSTIFY_CENTER_X|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FILL_COLUMN)
        btn.connect(SEL_COMMAND) do |sender, sel, ptr|
          @capStyle = CAP_NOT_LAST
          @linesCanvas.update(0, 0, @linesCanvas.width, @linesCanvas.height)
        end
        btn.connect(SEL_UPDATE) do |sender, sel, ptr|
          if @capStyle == CAP_NOT_LAST
            sender.handle(self, MKUINT(ID_CHECK, SEL_COMMAND), nil)
          else
            sender.handle(self, MKUINT(ID_UNCHECK, SEL_COMMAND), nil)
          end
        end
        btn = FXButton.new(capstyle, "\tCAP_BUTT", loadIcon("capbutt.png"), nil, 0, BUTTON_TOOLBAR|JUSTIFY_CENTER_X|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FILL_COLUMN)
        btn.connect(SEL_COMMAND) do |sender, sel, ptr|
          @capStyle = CAP_BUTT
          @linesCanvas.update(0, 0, @linesCanvas.width, @linesCanvas.height)
        end
        btn.connect(SEL_UPDATE) do |sender, sel, ptr|
          if @capStyle == CAP_BUTT
            sender.handle(self, MKUINT(ID_CHECK, SEL_COMMAND), nil)
          else
            sender.handle(self, MKUINT(ID_UNCHECK, SEL_COMMAND), nil)
          end
        end
        btn = FXButton.new(capstyle, "\tCAP_ROUND", loadIcon("capround.png"), nil, 0, BUTTON_TOOLBAR|JUSTIFY_CENTER_X|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FILL_COLUMN)
        btn.connect(SEL_COMMAND) do |sender, sel, ptr|
          @capStyle = CAP_ROUND
          @linesCanvas.update(0, 0, @linesCanvas.width, @linesCanvas.height)
        end
        btn.connect(SEL_UPDATE) do |sender, sel, ptr|
          if @capStyle == CAP_ROUND
            sender.handle(self, MKUINT(ID_CHECK, SEL_COMMAND), nil)
          else
            sender.handle(self, MKUINT(ID_UNCHECK, SEL_COMMAND), nil)
          end
        end
        btn = FXButton.new(capstyle, "\tCAP_PROJECTING", loadIcon("capproj.png"), nil, 0, BUTTON_TOOLBAR|JUSTIFY_CENTER_X|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FILL_COLUMN)
        btn.connect(SEL_COMMAND) do |sender, sel, ptr|
          @capStyle = CAP_PROJECTING
          @linesCanvas.update(0, 0, @linesCanvas.width, @linesCanvas.height)
        end
        btn.connect(SEL_UPDATE) do |sender, sel, ptr|
          if @capStyle == CAP_PROJECTING
            sender.handle(self, MKUINT(ID_CHECK, SEL_COMMAND), nil)
          else
            sender.handle(self, MKUINT(ID_UNCHECK, SEL_COMMAND), nil)
          end
        end
    
        # Line join style
        FXLabel.new(controls, "Join Style:", nil, LAYOUT_LEFT)
        joinstyle = FXMatrix.new(controls, 3, FRAME_RIDGE|MATRIX_BY_COLUMNS|LAYOUT_FILL_X)
        joinstyle.padLeft = 2
        joinstyle.padRight = 2
        joinstyle.padTop = 2
        joinstyle.padBottom = 2
        btn = FXButton.new(joinstyle, "\tJOIN_MITER", loadIcon("jmiter.png"), nil, 0, BUTTON_TOOLBAR|JUSTIFY_CENTER_X|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FILL_COLUMN)
        btn.connect(SEL_COMMAND) do |sender, sel, ptr|
          @joinStyle = JOIN_MITER
          @linesCanvas.update(0, 0, @linesCanvas.width, @linesCanvas.height)
        end
        btn.connect(SEL_UPDATE) do |sender, sel, ptr|
          if @joinStyle == JOIN_MITER
            sender.handle(self, MKUINT(ID_CHECK, SEL_COMMAND), nil)
          else
            sender.handle(self, MKUINT(ID_UNCHECK, SEL_COMMAND), nil)
          end
        end
        btn = FXButton.new(joinstyle, "\tJOIN_ROUND", loadIcon("jround.png"), nil, 0, BUTTON_TOOLBAR|JUSTIFY_CENTER_X|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FILL_COLUMN)
        btn.connect(SEL_COMMAND) do |sender, sel, ptr|
          @joinStyle = JOIN_ROUND
          @linesCanvas.update(0, 0, @linesCanvas.width, @linesCanvas.height)
        end
        btn.connect(SEL_UPDATE) do |sender, sel, ptr|
          if @joinStyle == JOIN_ROUND
            sender.handle(self, MKUINT(ID_CHECK, SEL_COMMAND), nil)
          else
            sender.handle(self, MKUINT(ID_UNCHECK, SEL_COMMAND), nil)
          end
        end
        btn = FXButton.new(joinstyle, "\tJOIN_BEVEL", loadIcon("jbevel.png"), nil, 0, BUTTON_TOOLBAR|JUSTIFY_CENTER_X|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FILL_COLUMN)
        btn.connect(SEL_COMMAND) do |sender, sel, ptr|
          @joinStyle = JOIN_BEVEL
          @linesCanvas.update(0, 0, @linesCanvas.width, @linesCanvas.height)
        end
        btn.connect(SEL_UPDATE) do |sender, sel, ptr|
          if @joinStyle == JOIN_BEVEL
            sender.handle(self, MKUINT(ID_CHECK, SEL_COMMAND), nil)
          else
            sender.handle(self, MKUINT(ID_UNCHECK, SEL_COMMAND), nil)
          end
        end
    
        # Colors
        FXLabel.new(controls, "Colors:", nil, LAYOUT_LEFT)
        pairs = FXMatrix.new(controls, 2, FRAME_RIDGE|MATRIX_BY_COLUMNS|LAYOUT_FILL_X)
        pairs.padLeft = 2
        pairs.padRight = 2
        pairs.padTop = 2
        pairs.padBottom = 2
        pairs.hSpacing = 5
        pairs.vSpacing = 5
    
        # Back Color
        FXLabel.new(pairs, "Back Color:")
        @backWell = FXColorWell.new(pairs, FXRGB(0, 0, 255), nil, 0, FRAME_SUNKEN|FRAME_THICK|ICON_AFTER_TEXT|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN)
        @backWell.connect(SEL_COMMAND) do |sender, sel, clr|
          @backcolor = clr
          @linesCanvas.update
          @shapesCanvas.update
          @imagesCanvas.update
        end
        @backWell.connect(SEL_CHANGED) do |sender, sel, clr|
          @backcolor = clr
          @linesCanvas.update
          @shapesCanvas.update
          @imagesCanvas.update
        end
        @backWell.connect(SEL_UPDATE) do |sender, sel, ptr|
          sender.handle(self, MKUINT(ID_SETVALUE, SEL_COMMAND), @backcolor)
        end
    
        # Fore Color
        FXLabel.new(pairs, "Fore Color:")
        @foreWell = FXColorWell.new(pairs, FXRGB(255, 0, 0), nil, 0, FRAME_SUNKEN|FRAME_THICK|ICON_AFTER_TEXT|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN)
        @foreWell.connect(SEL_COMMAND) do |sender, sel, clr|
          @forecolor = clr
          @linesCanvas.update
          @shapesCanvas.update
          @imagesCanvas.update
        end
        @foreWell.connect(SEL_CHANGED) do |sender, sel, clr|
          @forecolor = clr
          @linesCanvas.update
          @shapesCanvas.update
          @imagesCanvas.update
        end
        @foreWell.connect(SEL_UPDATE) do |sender, sel, ptr|
          sender.handle(self, MKUINT(ID_SETVALUE, SEL_COMMAND), @forecolor)
        end
    
        # Erase Color
        FXLabel.new(pairs, "Erase Color:")
        @eraseWell = FXColorWell.new(pairs, FXRGB(255, 255, 255), nil, 0, FRAME_SUNKEN|FRAME_THICK|ICON_AFTER_TEXT|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN)
        @eraseWell.connect(SEL_COMMAND) do |sender, sel, clr|
          @erasecolor = clr
          @linesCanvas.update
          @shapesCanvas.update
          @imagesCanvas.update
        end
        @eraseWell.connect(SEL_CHANGED) do |sender, sel, clr|
          @erasecolor = clr
          @linesCanvas.update
          @shapesCanvas.update
          @imagesCanvas.update
        end
        @eraseWell.connect(SEL_UPDATE) do |sender, sel, ptr|
          sender.handle(self, MKUINT(ID_SETVALUE, SEL_COMMAND), @erasecolor)
        end
    
        # Line width
        linew = FXMatrix.new(controls, 2, FRAME_RIDGE|MATRIX_BY_COLUMNS|LAYOUT_FILL_X)
        linew.padLeft = 2
        linew.padRight = 2
        linew.padTop = 2
    
        linew.padBottom = 2
    
        FXLabel.new(linew, "Line Width:")
        @lineWidthSpinner = FXSpinner.new(linew, 4, nil, 0, SPIN_NORMAL|FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_COLUMN)
        @lineWidthSpinner.connect(SEL_COMMAND) { @linesCanvas.update(0, 0, @linesCanvas.width, @linesCanvas.height) }
        @lineWidthSpinner.range = 1..255
        @lineWidthSpinner.value = 1
    
        # Stipple
        stip = FXMatrix.new(controls, 2, FRAME_RIDGE|MATRIX_BY_COLUMNS|LAYOUT_FILL_X)
        stip.padLeft = 2
        stip.padRight = 2
        stip.padTop = 2
        stip.padBottom = 2
        FXLabel.new(stip, "Stipples:")
        pop = FXPopup.new(self)
    
        $stipples.each do |pat, desc|
          opt = FXOption.new(pop, desc, nil, nil, 0, JUSTIFY_HZ_APART|ICON_AFTER_TEXT)
          opt.userData = pat
          opt.connect(SEL_COMMAND) do |sender, sel, ptr|
            @stipple = sender.userData
            @linesCanvas.update(0, 0, @linesCanvas.width, @linesCanvas.height)
          end
        end
        FXOptionMenu.new(stip, pop, LAYOUT_TOP|FRAME_RAISED|FRAME_THICK|JUSTIFY_HZ_APART|ICON_AFTER_TEXT)
    
        # Fill Style
        FXLabel.new(controls, "Fill Style:", nil, LAYOUT_LEFT)
        fillstyle = FXMatrix.new(controls, 2, FRAME_RIDGE|MATRIX_BY_COLUMNS|LAYOUT_FILL_X)
        fillstyle.padLeft = 2
        fillstyle.padRight = 2
        fillstyle.padTop = 2
        fillstyle.padBottom = 2
        $fill_styles.each do |fs, desc|
          btn = FXButton.new(fillstyle, desc, nil, nil, 0, BUTTON_TOOLBAR|JUSTIFY_CENTER_X|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_FILL_COLUMN)
          btn.userData = fs
          btn.connect(SEL_COMMAND) do |sender, sel, ptr|
            @fillStyle = sender.userData
            @linesCanvas.update(0, 0, @linesCanvas.width, @linesCanvas.height)
          end
          btn.connect(SEL_UPDATE) do |sender, sel, ptr|
            if sender.userData == @fillStyle
              sender.handle(self, MKUINT(ID_CHECK, SEL_COMMAND), nil)
            else
              sender.handle(self, MKUINT(ID_UNCHECK, SEL_COMMAND), nil)
            end
          end
        end
    
        # Angles for arcs
        FXLabel.new(controls, "Arc angles:", nil, LAYOUT_LEFT)
        arcangles = FXMatrix.new(controls, 3, FRAME_RIDGE|MATRIX_BY_COLUMNS|LAYOUT_FILL_X)
        arcangles.padLeft = 2
        arcangles.padRight = 2
        arcangles.padTop = 2
        arcangles.padBottom = 2
        arcangles.hSpacing = 4
        arcangles.vSpacing = 4
    
        @ang1 = FXDataTarget.new(0)
        FXLabel.new(arcangles, "Ang1:", nil, LAYOUT_LEFT)
        FXTextField.new(arcangles, 4, @ang1, FXDataTarget::ID_VALUE, TEXTFIELD_INTEGER|JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK)
        sang1 = FXSlider.new(arcangles, @ang1, FXDataTarget::ID_VALUE, LAYOUT_CENTER_Y|LAYOUT_FILL_X|SLIDER_INSIDE_BAR|LAYOUT_FILL_COLUMN)
        sang1.range = -360..360
    
        @ang2 = FXDataTarget.new(90)
        FXLabel.new(arcangles, "Ang2:", nil, LAYOUT_LEFT)
        FXTextField.new(arcangles, 4, @ang2, FXDataTarget::ID_VALUE, TEXTFIELD_INTEGER|JUSTIFY_RIGHT|FRAME_SUNKEN|FRAME_THICK)
        sang2 = FXSlider.new(arcangles, @ang2, FXDataTarget::ID_VALUE, LAYOUT_CENTER_Y|LAYOUT_FILL_X|SLIDER_INSIDE_BAR|LAYOUT_FILL_COLUMN)
        sang2.range = -360..360
    
        # Font
        fonts = FXHorizontalFrame.new(controls, FRAME_RIDGE|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH)
        fonts.padLeft = 2
        fonts.padRight = 2
        fonts.padTop = 2
        fonts.padBottom = 2
        btn = FXButton.new(fonts, "Font Dialog...\tChange the text font", nil, nil, 0, BUTTON_TOOLBAR|JUSTIFY_CENTER_X|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
        btn.connect(SEL_COMMAND, method(:onCmdFont))
    
        # Printing
        printer = FXHorizontalFrame.new(controls, FRAME_RIDGE|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH)
        printer.padLeft = 2
        printer.padRight = 2
        printer.padTop = 2
        printer.padBottom = 2
        btn = FXButton.new(printer, "Print Dialog...\tPrint it out", nil, nil, 0, BUTTON_TOOLBAR|JUSTIFY_CENTER_X|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
        btn.connect(SEL_COMMAND, method(:onCmdPrint))
    
        # Quit
        quitter = FXHorizontalFrame.new(controls, FRAME_RIDGE|LAYOUT_FILL_X|PACK_UNIFORM_WIDTH)
        quitter.padLeft = 2
        quitter.padRight = 2
        quitter.padTop = 2
        quitter.padBottom = 2
        FXButton.new(quitter, "Bye Bye!\tHasta la vista, baby!", nil, getApp(), FXApp::ID_QUIT, BUTTON_TOOLBAR|JUSTIFY_CENTER_X|FRAME_RAISED|LAYOUT_FILL_X|LAYOUT_FILL_Y)
    
        # Switcher
        tabbook = FXTabBook.new(contents, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_RIGHT)
    
        # First page shows various line styles
        linesTab = FXTabItem.new(tabbook, "&Lines", nil)
        linesPage = FXPacker.new(tabbook, FRAME_THICK|FRAME_RAISED)
        frame = FXHorizontalFrame.new(linesPage, FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y)
        frame.padLeft = 0
        frame.padRight = 0
        frame.padTop = 0
        frame.padBottom = 0
        @linesCanvas = FXCanvas.new(frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y)
        @linesCanvas.connect(SEL_PAINT) do |canvas, sel, ev|
          dc = FXDCWindow.new(canvas, ev)
          drawPage(dc, canvas.width, canvas.height)
        end
    
        # Second page shows various shapes
        shapesTab = FXTabItem.new(tabbook, "&Shapes", nil)
        shapesPage = FXPacker.new(tabbook, FRAME_THICK|FRAME_RAISED)
        frame = FXHorizontalFrame.new(shapesPage, FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y)
        frame.padLeft = 0
        frame.padRight = 0
        frame.padTop = 0
        frame.padBottom = 0
        @shapesCanvas = FXCanvas.new(frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y)
        @shapesCanvas.connect(SEL_PAINT) do |canvas, sel, ev|
          dc = FXDCWindow.new(canvas, ev)
          dc.foreground = @eraseWell.rgba
          dc.fillRectangle(0, 0, canvas.width, canvas.height)
    
          dc.foreground = @foreWell.rgba
          dc.background = @backWell.rgba
          dc.drawRectangle(5, 5, 50, 50)
          dc.fillRectangle(60, 5, 50, 50)
    
          dc.foreground = @foreWell.rgba
          dc.background = @backWell.rgba
          dc.drawArc(5, 60, 50, 50, 0, 64*90)
          dc.fillArc(60, 60, 50, 50, 64*90, 64*180)
    
          dc.foreground = @foreWell.rgba
          dc.background = @backWell.rgba
          dc.drawBitmap(@bitmap, 115, 5)
        end
    
        # Third page shows images
        imagesTab = FXTabItem.new(tabbook, "&Images", nil)
        imagesPage = FXPacker.new(tabbook, FRAME_THICK|FRAME_RAISED)
        frame = FXHorizontalFrame.new(imagesPage, FRAME_SUNKEN|FRAME_THICK|LAYOUT_FILL_X|LAYOUT_FILL_Y)
        frame.padLeft = 0
        frame.padRight = 0
        frame.padTop = 0
        frame.padBottom = 0
        @imagesCanvas = FXCanvas.new(frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y)
        @imagesCanvas.connect(SEL_PAINT) do |canvas, sel, ev|
          dc = FXDCWindow.new(canvas, ev)
          dc.foreground = @eraseWell.rgba
          dc.fillRectangle(0, 0, canvas.width, canvas.height)
          dc.drawImage(@birdImage, 0, 0)
        end
    
        # File menu
        @filemenu = FXMenuPane.new(self)
        FXMenuCommand.new(@filemenu, "&Print...\tCtl-P").connect(SEL_COMMAND, method(:onCmdPrint))
        FXMenuCommand.new(@filemenu, "&Font...\tCtl-F").connect(SEL_COMMAND, method(:onCmdFont))
        FXMenuCommand.new(@filemenu, "&Quit\tCtl-Q", nil, getApp(), FXApp::ID_QUIT)
        FXMenuTitle.new(menubar, "&File", nil, @filemenu)
    
    Lars Kanis's avatar
    Lars Kanis committed
        @birdImage = FXPNGImage.new(getApp(), File.open(File.expand_path("../icons/dippy.png", __FILE__), "rb").read)
    
        @bitmap = FXBitmap.new(getApp(), $bitmap_bits, 0, 64, 64)
    
        @function = BLT_SRC
        @lineStyle = LINE_SOLID
        @capStyle = CAP_BUTT
        @joinStyle = JOIN_MITER
        @fillStyle = FILL_SOLID
        @fillRule = RULE_EVEN_ODD
        @stipple = STIPPLE_NONE
        @forecolor = FXRGB(255, 0, 0) # red
        @backcolor = FXRGB(0, 0, 255) # blue
        @erasecolor = FXRGB(255, 255, 255) # white
        @testFont = FXFont.new(getApp(), "helvetica", 20)
      end
    
      def create
        super
        @birdImage.create
        @testFont.create
        @bitmap.create
        show(PLACEMENT_SCREEN)
      end
    
      def detach
        super
        @birdImage.detach
        @testFont.detach
        @bitmap.detach
      end
    
      def drawPage(dc, w, h)
        dc.foreground = @erasecolor
        dc.fillRectangle(0, 0, w, h)
    
        dc.foreground = @forecolor
        dc.background = @backcolor
    
        dc.lineStyle = @lineStyle
        dc.lineCap = @capStyle
        dc.lineJoin = @joinStyle
        dc.function = @function
    
        dc.stipple = @stipple
        dc.fillStyle = @fillStyle
        dc.lineWidth = @lineWidthSpinner.value
    
        # Here's a single line
        dc.drawLine(20, 200, w - 20, 200)
    
        # Here are some connected lines (to show join styles)
        points = []
        points << FXPoint.new(10, 3*h/4)
        points << FXPoint.new(points[0].x+w/6, h/2)
        points << FXPoint.new(points[1].x+w/6, points[0].y)
        points << FXPoint.new(points[2].x+w/6, points[1].y)
        points << FXPoint.new(points[3].x+w/6, points[0].y)
        points << FXPoint.new(points[4].x+w/6, points[1].y)
        dc.drawLines(points)
    
        dc.font = @testFont
        dc.foreground = @forecolor
        dc.background = @backcolor
        s = "Font: #{@testFont.name}  Size: #{@testFont.size/10}"
        dc.drawText(30, h-70, s)
        dc.drawImageText(30, h-30, s)
    
        dc.foreground = @forecolor
        dc.background = @backcolor
        dc.drawRectangle(20, 20, 200, 100)
        dc.fillRectangle(300, 20, 200, 100)
    
        dc.drawArc(20, 120, 100, 100, 64*@ang1.value, 64*@ang2.value)
        dc.fillArc(300, 120, 100, 100, 64*@ang1.value, 64*@ang2.value)
    
        poly = []
        poly << FXPoint.new(200, 230)
        poly << FXPoint.new(poly[0].x+40, poly[0].y+20)
        poly << FXPoint.new(poly[0].x+30, poly[0].y+60)
        poly << FXPoint.new(poly[0].x-30, poly[0].y+60)
        poly << FXPoint.new(poly[0].x-40, poly[0].y+20)
        dc.fillPolygon(poly)
    
        poly = []
        poly << FXPoint.new(300, 230)
        poly << FXPoint.new(poly[0].x+30, poly[0].y+60)
        poly << FXPoint.new(poly[0].x-40, poly[0].y+20)
        poly << FXPoint.new(poly[0].x+40, poly[0].y+20)
        poly << FXPoint.new(poly[0].x-30, poly[0].y+60)
        dc.fillComplexPolygon(poly)
    
        poly = []
        poly << FXPoint.new(400, 230)
        poly << FXPoint.new(poly[0].x+30, poly[0].y+60)
        poly << FXPoint.new(poly[0].x-40, poly[0].y+20)
        poly << FXPoint.new(poly[0].x+40, poly[0].y+20)
        poly << FXPoint.new(poly[0].x-30, poly[0].y+60)
        dc.fillRule = RULE_WINDING
        dc.fillComplexPolygon(poly)
    
        concave = []
        concave << FXPoint.new(w-100, h-100)
        concave << FXPoint.new(concave[0].x+40, concave[0].y-20)
        concave << FXPoint.new(concave[0].x   , concave[0].y+40)
        concave << FXPoint.new(concave[0].x-40, concave[0].y-20)
        dc.fillConcavePolygon(concave)
    
        # Draw a pale blue dot ;)
        dc.foreground = FXRGB(128, 128, 255)
        dc.drawPoint(w-20, h-20)
      end
    
      def onCmdFont(sender, sel, ptr)
        fontdlg = FXFontDialog.new(self, "Change Font", DECOR_BORDER|DECOR_TITLE)
        fontdlg.fontSelection = @testFont.fontDesc
        if fontdlg.execute != 0
          @testFont = FXFont.new(getApp(), fontdlg.fontSelection)
          @testFont.create
          @linesCanvas.update(0, 0, @linesCanvas.width, @linesCanvas.height)
        end
        return 1
      end
    
      def onCmdPrint(sender, sel, ptr)
        dlg = FXPrintDialog.new(self, "Print Graphics")
        if dlg.execute != 0
          p = dlg.printer
          pdc = FXDCPrint.new(getApp())
          unless pdc.beginPrint(p)
            FXMessageBox.error(self, MBOX_OK, "Printer Error", "Unable to print")
            return 1
          end
          pdc.beginPage(1)
          drawPage(pdc, 500, 500)
          pdc.endPage
          pdc.endPrint
        end
        return 1
      end
    
      # Load the named icon from a file
      def loadIcon(filename, clr = FXRGB(192, 192, 192), opts = 0)
    
    Lars Kanis's avatar
    Lars Kanis committed
        filename = File.expand_path("../icons/#{filename}", __FILE__)
        File.open(filename, "rb") do |f|
          FXPNGIcon.new(getApp(), f.read)
    
        end
      end
    end
    
    if __FILE__ == $0
      application = FXApp.new("DCTest", "FoxTest")
      DCTestWindow.new(application)
      application.create
      application.run
    end