Call signal handler or parent class

Hi,

I have a Gtk::Table, where I on the :draw signal first want to draw on
the background of the table, than call the tables original draw handler,
so that the widgets packed into the table are drawn, and then call
another own program part, that draws over it all. How can I achieve
this?

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.

Cheers, detlef

Hi,

In [email protected]
“[ruby-gnome2-devel-en] call signal handler or parent class” on Mon,
17 Mar 2014 17:35:37 +0100,
Detlef R. [email protected] wrote:

I have a Gtk::Table, where I on the :draw signal first want to draw on
the background of the table, than call the tables original draw handler,
so that the widgets packed into the table are drawn, and then call
another own program part, that draws over it all. How can I achieve this?

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?

Thanks,

kou

On Tue, 2014-03-18 at 17:31 +0100, Detlef R. wrote:

Hi,

here we go! In this example the Gtk::Entry’s are drawn

Sorry for polluting this list – I really guess it is more for serious
developer discussion…

For the code of Detlef R. it is obvious that he did not care much
about the return value of signal handlers.

See GTK+ original documentation or
http://ruby-gnome2.sourceforge.jp/hiki.cgi?tut-gtk-events

Depending of the return value of the block code, GTK will decide if the
event should be spread or not:

  * if true, GTK will stop the event processing here;
  * if false, GTK will continue to propagate the event

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

Am 18.03.2014 18:26, schrieb Stefan S.:

On Tue, 2014-03-18 at 17:31 +0100, Detlef R. wrote:

Hi,

here we go! In this example the Gtk::Entry’s are drawn
Sorry for polluting this list – I really guess it is more for serious
developer discussion…

For the code of Detlef R. it is obvious that he did not care much
about the return value of signal handlers.

Hi,

that was it. Thanks allot! Long time ago I knew this :slight_smile:

Cheers, detlef