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)
@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)
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