Forum: Ruby-Gnome 2 call signal handler or parent class

4913bcb685792f601ae9813b4713abb9?d=identicon&s=25 Detlef Reichl (Guest)
on 2014-03-17 17:50
(Received via mailing list)
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
Ee6ffca720cc428d70247dcd7377dd48?d=identicon&s=25 Kouhei Sutou (Guest)
on 2014-03-18 15:43
(Received via mailing list)
Hi,

In <53272459.7060702@gmx.org>
  "[ruby-gnome2-devel-en] call signal handler or parent class" on Mon,
17 Mar 2014 17:35:37 +0100,
  Detlef Reichl <detlef.reichl@gmx.org> 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
4913bcb685792f601ae9813b4713abb9?d=identicon&s=25 Detlef Reichl (Guest)
on 2014-03-18 17:33
(Received via mailing list)
Am 18.03.2014 15:42, schrieb Kouhei Sutou:
>>
>> 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
8e16f7669af5b4ecfa4f2b89f32b21b6?d=identicon&s=25 Stefan Salewski (Guest)
on 2014-03-18 18:51
(Received via mailing list)
On Tue, 2014-03-18 at 17:31 +0100, Detlef Reichl 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 Reichl 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
4913bcb685792f601ae9813b4713abb9?d=identicon&s=25 Detlef Reichl (Guest)
on 2014-03-18 19:48
(Received via mailing list)
Am 18.03.2014 18:26, schrieb Stefan Salewski:
> On Tue, 2014-03-18 at 17:31 +0100, Detlef Reichl 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 Reichl 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 :-)

Cheers, detlef
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.