Forum: Ruby-Gnome 2 Ruby-Gtk question

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
74f7b4679cfe88d76faedf5ee3aa7c6e?d=identicon&s=25 Torli Birnbauer (rubinx)
on 2008-12-31 21:42
Hi,

Is there an equivalent to the g_signal_connect_swapped() gtk+ call
in Ruby. Following is the c code that allows a button to destroy
an including window:

  +------------------------------------------------------------+
  | g_signal_connect_swapped (G_OBJECT (button), "clicked",    |

  |                           G_CALLBACK (gtk_widget_destroy), |

  |                           (gpointer) window);              |
  +------------------------------------------------------------+

The following seems to be the Ruby way to do the above:

  +-----------------------------------------------------+
  |  button = Gtk::Button.new("_Hello World")           |
  |  button.signal_connect("clicked") { Gtk.main_quit } |
  +-----------------------------------------------------+

However, it is sometimes necessary to destroy a certain widget,
and I believe it should be made available to the callback in
some other way than via a global variable! Which brings me back
to my original question.
Ee6ffca720cc428d70247dcd7377dd48?d=identicon&s=25 Kouhei Sutou (Guest)
on 2009-01-01 00:36
(Received via mailing list)
Hi,

In <24a83def151af22df6e9997bee2581cc@ruby-forum.com>
  "[ruby-gnome2-devel-en] Ruby-Gtk question" on Wed, 31 Dec 2008
21:42:15 +0100,
  Torli Birnbauer <ruby-forum-incoming@andreas-s.net> wrote:

>   +------------------------------------------------------------+
> some other way than via a global variable! Which brings me back
> to my original question.

You don't need to use a global variable. Signal handlers are
closure.

  window = get_window
  button = Gtk::Button.new("_Hello World")
  button.signal_connect("clicked") {window.destroy}



Happy new year,
--
kou
74f7b4679cfe88d76faedf5ee3aa7c6e?d=identicon&s=25 Torli Birnbauer (rubinx)
on 2009-01-01 00:59
Kouhei Sutou wrote:
> You don't need to use a global variable. Signal handlers are
> closure.

Of course, Kou. Now that you've mentioned it I do feel a bit silly.
My mind has not yet switched back to Ruby, and perhaps I'm trying
too hard to see relationships to the good old GTK+ foundation.

Thank you, and happy New Year to you too!
Torli
74f7b4679cfe88d76faedf5ee3aa7c6e?d=identicon&s=25 Torli Birnbauer (rubinx)
on 2009-01-06 18:19
Cursor is a {{ Gdk::Window }} feature. Gtk provides {{ EventBox }} to
access (extend) {{ Gdk }} functionality. In the following program we can
see that the Ruby works with {{ Gdk::Events }}, however, I can not get
the cursor working. Is this feature available in Ruby, or am I not doing
something right?

+--------------------------------------------------------------+
|   require 'gtk2'                                             |
|                                                              |
|   def change_label(event, label)                             |
|    if event.event_type == Gdk::Event::BUTTON2_PRESS          |
|       if label.text[0].chr == 'D'                            |
|         label.text = "I Was Double-Clicked!"                 |
|       else                                                   |
|         label.text = "Double-Click Me Again!"                |
|       end                                                    |
|     end                                                      |
|   end                                                        |
|   window = Gtk::Window.new(Gtk::Window::TOPLEVEL)            |
|                                                              |
|   window.set_title  "Two buttons"                            |
|   window.border_width = 10                                   |
|   window.signal_connect('delete_event') { false }            |
|   window.signal_connect('destroy') { Gtk.main_quit }         |
|                                                              |
|   eventbox = Gtk::EventBox.new                               |
|   label    = Gtk::Label.new('Double-click me!')              |
|                                                              |
|   eventbox.set_events(Gdk::Event::BUTTON_PRESS_MASK)         |
|                                                              |
| #??????????????????????????????????????????????????????????? |
| # eventbox.set_cursor(Gdk::Cursor.new(Gdk::Cursor::HAND1)) ? |
| #??????????????????????????????????????????????????????????? |
|                                                              |
|   eventbox.add(label)                                        |
|   window.add(eventbox)                                       |
|                                                              |
|   eventbox.signal_connect('button_press_event') do |w, e|    |
|     change_label(e, label)                                   |
|   end                                                        |
|                                                              |
|   window.show_all                                            |
|   Gtk.main                                                   |
+--------------------------------------------------------------+

Thank you in advance.
324ce80d9dbe9417607192038fb880bf?d=identicon&s=25 Andrew S. Townley (Guest)
on 2009-01-06 19:08
(Received via mailing list)
Hi Torli,

That's not quite how this works.  I spent a good deal of time trying to
get this right before I finally found the useful solution.

On Tue, 2009-01-06 at 18:19 +0100, Torli Birnbauer wrote:
> |    if event.event_type == Gdk::Event::BUTTON2_PRESS          |
> |   window.border_width = 10                                   |
> | #??????????????????????????????????????????????????????????? |
You can only change the cursor for the GDK window, not the GTK window.
In your case, I'd try eventbox.visible_window.cursor = ..whatever...

One other thing you might want to consider is not creating the same
cursor all the time.  I generally create a set of cursors that I can
reference from everywhere in the code.  You'll also probably want to
investigate the symbolic names as well as the constants.  For example,
to get the "appstart" cursor, you need to do:

appstart = Gdk::Cursor.new(Gdk::Display.default, "left_ptr_watch")

*That* little gem took me ages to find, so it might save you some
trouble too.

Hope this helps,

ast
--
Andrew S. Townley <ast@atownley.org>
http://atownley.org
324ce80d9dbe9417607192038fb880bf?d=identicon&s=25 Andrew S. Townley (Guest)
on 2009-01-06 19:14
(Received via mailing list)
Sorry for the self follow-up, but I didn't have the ability to actually
try this before.  I've amended the example below and it seems to do what
you intend.

Apologies for missing a couple of ordering issues.

On Tue, 2009-01-06 at 17:30 +0000, Andrew S. Townley wrote:
> > something right?
> > |       end                                                    |
> > |   label    = Gtk::Label.new('Double-click me!')              |
> > |                                                              |
> > |   eventbox.set_events(Gdk::Event::BUTTON_PRESS_MASK)

  eventbox.add(label)
  window.add(eventbox)
  window.show_all

  eventbox.realize
  eventbox.window.cursor = Gdk::Cursor.new(Gdk::Cursor::HAND1)


     eventbox.signal_connect('button_press_event') do |w, e|
         change_label(e, label)
     end

     Gtk.main

EOF
> reference from everywhere in the code.  You'll also probably want to
> ast
--
Andrew S. Townley <ast@atownley.org>
http://atownley.org
74f7b4679cfe88d76faedf5ee3aa7c6e?d=identicon&s=25 Torli Birnbauer (rubinx)
on 2009-01-06 20:11
Hi Andrew,

Andrew, are you using Ruby 1.9.x? I am running 1.8.6. This may be my
problem. Namely, after adding :
  +-----------------------------------------------------------------+
  | eventbox.realize                                                |
  | eventbox.window.cursor = Gdk::Cursor.new(Gdk::Cursor::HAND1)    |
  |#   or                                                           |
  |#eventbox.window.set_cursor(Gdk::Cursor.new(Gdk::Cursor::HAND1)) |
  +-----------------------------------------------------------------+
I get the following error on line {{ 3 require 'gtk2' }} :
+--------------------------------------------------------------------+
| eventbox.rb: line 3                                                |
| Gtk-CRITICAL **:gtk_widget_realize: assertion `GTK_WIDGET_ANCHORED |
|  (widget) || GTK_IS_INVISIBLE (widget)' failed                     |
| eventbox.rb:26: undefined method `cursor=' for nil:NilClass        |
|  (NoMethodError)                                                   |
+--------------------------------------------------------------------+

As you see line {{ eventbox.window.cursor =
Gdk::Cursor.new(Gdk::Cursor::HAND1) }} also causes problems. Interpreter
complains about undefined method {{ cursor }}, but I have trouble
finding out where did the {{ window }} came from. Though I can find it
in the book "Foundations of Gtk+ Development" where in the "C" code
example it looks like {{ gtk_window_set_cursor(eventbox->window,
gtk_cursor_new(GTK_HAND1)); }}, I on the other hand can not find it
anywhere in Ruby/GNOME2/Gtk/Gdk documentation.

Regardless, I hope my problem is Ruby1.9.x/1.8.6 related.
Thx, Torli.
74f7b4679cfe88d76faedf5ee3aa7c6e?d=identicon&s=25 Torli Birnbauer (rubinx)
on 2009-01-06 21:10
Andrew, now it's time for me to self-followup :).  Your suggestion
works!!! I made mistake to call realize before I added it to the top
window.

Thank you for your help,
Torli
This topic is locked and can not be replied to.