Am 18.03.2014 15:42, schrieb Kouhei S.:
If I use signal_connect the widgets in the table doesn’t get drawn cause
the original :draw handler isn’t called and if I use
signal_connect_after I can’t draw on the “background” cause I would draw
over all widgets.
Could you show a sample program to start to confirm the
behavior?
Hi,
here we go! In this example the Gtk::Entry’s are drawn and then the
rectangles and the arrows are drawn in the signal_connect_after(:draw)
callback “above” it all. What I now want is, to draw in a part of the
window “under” the Gtk::Entry’s.
Thanks in advance! detlef
#!/usr/bin/env ruby
#encoding: UTF-8
require ‘gtk3’
module Etti
class PageLayout < Gtk::Box
LABELS_H = 3
LABELS_V = 3
LABEL_PADDING = 24.0
def initialize
super(:vertical)
self.border_width = 0
@entries = {}
@boxes = []
@tableData = { :borderTop =>
{:pos => [2, 3, 0, 1],
:label => ‘Rand oben’,
:tooltip => ‘Der Abstand vom oberen
Etikett zum Blattrand’},
:borderLeft =>
{:pos => [0, 1, 2, 3],
:label => ‘Rand links’,
:tooltip => ‘Der Abstand vom linken
Etikett zum Blattrand’},
:height =>
{:pos => [2, 3, 1, 2],
:label => ‘Etikett Hhe’,
:tooltip => ‘Die Hhe eines
einzelnen Etiketts’},
:width =>
{:pos => [1, 2, 2, 3],
:label => ‘Etikett Breite’,
:tooltip => ‘Die Breite eines
einzelnen Etiketts’},
:paddingH =>
{:pos => [2,3, 3, 4],
:label => ‘Abstand horizonal’,
:tooltip => “Der horizontale
Abstand zwischen den Etiketten\n”
“0, wenn es keinen
Zwischenraum gibt”},
:paddingV =>
{:pos => [3, 4, 2, 3],
:label => ‘Abstand vertikal’,
:tooltip => “Der vertikale Abstand
zwischen den Etiketten\n”
“0, wenn es keinen
Zwischenraum gibt”}
}
@sizeGroup = Gtk::SizeGroup.new :both
widget = make_entry :name, 'Name', "Name des
Etiketts\nDieser muss einmalig sein"
self.pack_start widget, :expand => false, :fill => false,
:padding => 12
@table = Gtk::Table.new 4, 4, true
self.pack_start @table, :expand => false, :fill => false
@tableData.each_pair do |key, val|
box = Gtk::Box.new :vertical
@boxes << box
@table.attach box, *val[:pos], 0, 0, LABEL_PADDING,
LABEL_PADDING
box.pack_start Gtk::Label.new(val[:label]), :expand =>
false, :fill => false
entry = Gtk::Entry.new
@entries[key] = entry
entry.name = key
box.pack_start entry, :expand => false, :fill => false
entry.set_max_length 7
entry.width_chars = 8
entry.tooltip_text = val[:tooltip]
entry.editable = true
entry.signal_connect(:changed) {|entry| on_entry_changed
entry}
end
@boxData = { :manufacture =>
{:label => 'Hersteller',
:tooltip => 'Hersteller der Etiketten'},
:orderNr =>
{:label => 'Bestellnummer',
:tooltip => 'Die
Hersteller-Bestellnummer’},
:description =>
{:label => ‘Beschreibung’,
:tooltip => ‘Eine zustzliche Beschreibung
der Etiketten’},
:pageSize =>
{:label => ‘Seitengre’,
:tooltip => ‘Die Gre eines Bogens, z.B.
“a4”’}
}
@boxData.each_pair do |key, val|
widget = make_entry key, val[:label], val[:tooltip]
self.pack_start widget, :expand => false, :fill =>
false, :padding => 4
end
# TODO hier muss ich noch wissen, wie ich den original draw
aufrufe…
# signal_connect(:draw) {draw_bg}
signal_connect(:map) {on_map}
=begin
signal_connect(:draw) do |widget|
draw_bg
widget.do_draw
on_draw
end
=end
signal_connect_after(:draw) {on_draw}
end
private
def make_entry id, label, tooltip, head=nil
hbox = Gtk::Box.new :horizontal
label = Gtk::Label.new.set_markup("<b>#{label}</b>: ")
hbox.pack_start label, :expand => false, :fill => false
@sizeGroup.add_widget label
label.xalign = 0.0
entry = Gtk::Entry.new
entry.name = id
@entries[id] = entry
hbox.pack_start entry, :expand => false, :fill => false
entry.tooltip_text = tooltip
entry.signal_connect(:changed) {|entry| on_entry_changed
entry}
hbox
end
def on_entry_changed entry
return if $pageData.nil?
key = entry.name.to_sym
text = @entries[key].text
return if text.length() < 1
case key
when :name, :manufacture, :orderNr, :description,
:pageSize
$pageData.instance_variable_set ‘@’ + key.to_s, text
when :borderLeft
$pageData.borders[0] = text.to_f
when :borderTop
$pageData.borders[1] = text.to_f
when :paddingH
$pageData.padding[0] = text.to_f
when :paddingV
$pageData.padding[1] = text.to_f
when :width
$pageData.size[0] = text.to_f
when :height
$pageData.size[1] = text.to_f
end
end
def draw_bg
box_allocation = @boxes.first.allocation
bw = box_allocation.width
bh = box_allocation.height
@cc = @table.window.create_cairo_context
@cc.set_source_rgb 0.2, 0.2, 0.4
@cc.paint
@cc.set_source_rgb 1.0, 1.0, 1.0
@cc.rectangle 8, 8,
(bw + LABEL_PADDING * 2) * (LABELS_H + 1) - 3,
(bh + LABEL_PADDING * 2) * (LABELS_V + 1) - 3
@cc.fill.stroke
end
def on_map
@boxW = 0
@boxH = 0
@boxes.each do |box|
allo = box.allocation
@boxW = allo.width if allo.width > @boxW
@boxH = allo.height if allo.height > @boxH
end
end
def on_draw
box_allocation = @boxes.first.allocation
bw = box_allocation.width
bh = box_allocation.height
bw = @boxW
bh = @boxH
@cc = @table.window.create_cairo_context
# we don't have an own window
@cc.translate(@table.allocation.x, @table.allocation.y)
@cc.antialias = :none
# border
@cc.set_source_rgb 0.5, 0.5, 0.5
@cc.line_width = 2.0
@cc.move_to (bw + LABEL_PADDING * 2.0) * (LABELS_H + 1), 8
@cc.line_to 8, 8
@cc.line_to 8, (bh + LABEL_PADDING * 2.0) * (LABELS_V + 1)
@cc.stroke
@cc.set_source_rgb 0.4, 0.4, 0.9
@cc.line_width = 1.0
1.upto(LABELS_V) do |y|
1.upto(LABELS_H) do |x|
@cc.rectangle (bw + LABEL_PADDING * 2.0) * x,
(bh + LABEL_PADDING * 2.0) * y,
bw + LABEL_PADDING * 1.5,
bh + LABEL_PADDING * 1.5
@cc.stroke
end
end
# border arrows
draw_arrow :h, 8, (bh + LABEL_PADDING * 2.0) * 2.0 + 24, bw
-
LABEL_PADDING * 2.0 - 8
draw_arrow :v, (bw + LABEL_PADDING * 2.0) * 2.0 + 24, 8, bh
-
LABEL_PADDING * 2.0 - 8
# cell arrows
draw_arrow :h, (bw + LABEL_PADDING * 2.0), (bh +
LABEL_PADDING * 2.0) * 2.0 + 24.0,
bw + LABEL_PADDING * 1.5
draw_arrow :v, (bw + LABEL_PADDING * 2.0) * 2.0 + 24, bh +
LABEL_PADDING * 2.0, bh + LABEL_PADDING * 1.5
# padding arrows
draw_arrow :h, (bw + LABEL_PADDING * 2.0) * 2.0 -
LABEL_PADDING * 0.5,
(bh + LABEL_PADDING * 2.0) * 3.0 + 24,
LABEL_PADDING * 0.5, true
draw_arrow :v, (bw + LABEL_PADDING * 2.0) * 3.0 + 24,
(bh + LABEL_PADDING * 2.0) * 2.0 -
LABEL_PADDING * 0.5, LABEL_PADDING * 0.5, true
end
ARROW_SIZE = 8.0
def draw_arrow dir, x, y, lg, out=false
@cc.set_source_rgb 0.2, 0.2, 0.2
@cc.line_width = 1.0
unless out
if dir == :h
@cc.antialias = :none
@cc.move_to x, y
@cc.line_to x + lg, y
@cc.stroke
@cc.antialias = :subpixel
@cc.move_to x, y
@cc.line_to x + ARROW_SIZE, y - (ARROW_SIZE / 4.0)
@cc.line_to x + ARROW_SIZE, y + (ARROW_SIZE / 4.0)
@cc.fill.stroke
@cc.move_to x + lg, y
@cc.line_to x + lg - ARROW_SIZE, y - (ARROW_SIZE /
4.0)
@cc.line_to x + lg - ARROW_SIZE, y + (ARROW_SIZE /
4.0)
@cc.fill.stroke
else
@cc.antialias = :none
@cc.move_to x, y
@cc.line_to x, y + lg
@cc.stroke
@cc.antialias = :subpixel
@cc.move_to x, y
@cc.line_to x - (ARROW_SIZE / 4.0), y + ARROW_SIZE
@cc.line_to x + (ARROW_SIZE / 4.0), y + ARROW_SIZE
@cc.fill.stroke
@cc.move_to x, y + lg
@cc.line_to x - (ARROW_SIZE / 4.0), y + lg -
ARROW_SIZE
@cc.line_to x + (ARROW_SIZE / 4.0), y + lg -
ARROW_SIZE
@cc.fill.stroke
end
else
if dir == :h
@cc.antialias = :none
@cc.move_to x - ARROW_SIZE * 2.0, y
@cc.line_to x + lg + ARROW_SIZE * 8.0, y
@cc.stroke
@cc.antialias = :subpixel
@cc.move_to x, y
@cc.line_to x - ARROW_SIZE, y - (ARROW_SIZE / 4.0)
@cc.line_to x - ARROW_SIZE, y + (ARROW_SIZE / 4.0)
@cc.fill.stroke
@cc.move_to x + lg, y
@cc.line_to x + lg + ARROW_SIZE, y - (ARROW_SIZE /
4.0)
@cc.line_to x + lg + ARROW_SIZE, y + (ARROW_SIZE /
4.0)
@cc.fill.stroke
else
@cc.antialias = :none
@cc.move_to x, y - ARROW_SIZE * 2.0
@cc.line_to x, y + lg + ARROW_SIZE * 8.0
@cc.stroke
@cc.antialias = :subpixel
@cc.move_to x, y
@cc.line_to x - (ARROW_SIZE / 4.0), y - ARROW_SIZE
@cc.line_to x + (ARROW_SIZE / 4.0), y - ARROW_SIZE
@cc.fill.stroke
@cc.move_to x, y + lg
@cc.line_to x - (ARROW_SIZE / 4.0), y + lg +
ARROW_SIZE
@cc.line_to x + (ARROW_SIZE / 4.0), y + lg +
ARROW_SIZE
@cc.fill.stroke
end
end
end
end
end
win = Gtk::Window.new
table = Etti::PageLayout.new
win.add table
win.show_all
Gtk.main