Guest User

Untitled

a guest
Jul 9th, 2012
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Vala 6.99 KB | None | 0 0
  1. /* Copyright 2012 Andrew Higginson
  2.  *
  3.  * This program is free software; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7. */
  8.  
  9. public class ContainerMenuItem : Gtk.MenuItem {
  10.  
  11.     public Gtk.Box box;
  12.  
  13.     public ContainerMenuItem(Gtk.Orientation orientation, int spacing) {
  14.         this.add_events(Gdk.EventMask.KEY_PRESS_MASK);
  15.    
  16.         this.box = new Gtk.Box(orientation, spacing);
  17.         this.box.set_name("box");
  18.         this.add(this.box);
  19.         this.connect_signals();
  20.     }
  21.    
  22.     public void pack_start(Gtk.Widget child, bool expand, bool fill, int padding = 0) {
  23.         this.box.pack_start(child, expand, fill, padding);
  24.     }
  25.    
  26.     public void pack_end(Gtk.Widget child, bool expand, bool fill, int padding = 0) {
  27.         this.box.pack_end(child, expand, fill, padding);
  28.     }
  29.    
  30.     private void connect_signals() {
  31.         this.parent_set.connect(this.on_parent_set);
  32.         this.button_release_event.connect(this.on_button_event);
  33.         this.button_press_event.connect(this.on_button_event);
  34.         this.enter_notify_event.connect(this.on_enter_notify_event);
  35.         this.leave_notify_event.connect(this.on_leave_notify_event);
  36.         this.motion_notify_event.connect(this.on_motion_notify_event);
  37.     }
  38.    
  39.     public Gtk.Widget[] get_all_child_widgets(Gtk.Widget? parent = null) {
  40.         if (parent == null) { parent = this; }
  41.        
  42.         Gtk.Widget[] widgets = {};
  43.         foreach (var child in (parent as Gtk.Container).get_children()) {
  44.             widgets += child;
  45.             if (child is Gtk.Container) {
  46.                 var child_widgets = this.get_all_child_widgets(child);
  47.                 foreach (var child_widget in child_widgets) {
  48.                     widgets += child_widget;
  49.                 }
  50.             }
  51.         }
  52.         return widgets;
  53.     }
  54.    
  55.     private void on_parent_set(Gtk.Widget? parent_old) {
  56.         if (parent_old != null)
  57.             parent_old.key_press_event.disconnect(this.on_parent_key_press_event);
  58.         var parent_new = this.get_parent();
  59.         if (parent_new != null)
  60.             parent_new.key_press_event.connect(this.on_parent_key_press_event);
  61.     }
  62.    
  63.     private bool on_button_event(Gdk.EventButton event) {
  64.         foreach (var widget in this.get_all_child_widgets()) {
  65.             Gtk.Allocation allocation;
  66.             widget.get_allocation(out allocation);
  67.            
  68.             if (event.x >= allocation.x && event.y >= allocation.y &&
  69.                 event.x <= allocation.x + allocation.width &&
  70.                 event.y <= allocation.y + allocation.height)
  71.             {
  72.                 foreach (var window in widget.get_window().get_children()) {
  73.                     int x_window, y_window;
  74.                     window.get_origin(out x_window, out y_window);
  75.                    
  76.                     if (event.x_root >= x_window && event.y_root >= y_window &&
  77.                         event.x_root <= x_window + window.get_width() &&
  78.                         event.y_root <= y_window + window.get_height())
  79.                     {
  80.                         var event_new = event;
  81.                         event_new.window = window;
  82.                         event_new.x = event.x_root - x_window;
  83.                         event_new.y = event.y_root - y_window;
  84.    
  85.                         if (event.type == Gdk.EventType.BUTTON_PRESS) {
  86.                             widget.button_press_event(event_new);
  87.                         }
  88.                         else if (event.type == Gdk.EventType.BUTTON_RELEASE) {
  89.                             widget.button_release_event(event_new);
  90.                         }
  91.                        
  92.                     }
  93.                 }
  94.             }
  95.         }
  96.         return true; // Don't appear as a menuitem
  97.     }
  98.    
  99.     private bool on_motion_notify_event(Gtk.Widget parent, Gdk.EventMotion event) {
  100.         foreach (var widget in this.get_all_child_widgets()) {
  101.             Gtk.Allocation allocation;
  102.             widget.get_allocation(out allocation);
  103.                    
  104.             foreach (var window in widget.get_window().get_children()) {
  105.                 int x_window, y_window;
  106.                 window.get_origin(out x_window, out y_window);
  107.                
  108.                 bool widget_in_event = (event.x >= allocation.x && event.y >= allocation.y &&
  109.                     event.x <= allocation.x + allocation.width &&
  110.                     event.y <= allocation.y + allocation.height);
  111.                    
  112.                 bool window_in_event = (event.x_root >= x_window && event.y_root >= y_window &&
  113.                     event.x_root <= x_window + window.get_width() &&
  114.                     event.y_root <= y_window + window.get_height());
  115.                
  116.                 if (widget_in_event && window_in_event) {
  117.                     var event_crossing = Gdk.EventCrossing();
  118.                     var event_motion = Gdk.EventMotion();
  119.                    
  120.                     event_crossing.type = Gdk.EventType.ENTER_NOTIFY;
  121.                     event_crossing.window = event_motion.window = window;
  122.                     event_crossing.x = event_motion.x = event.x_root - x_window;
  123.                     event_crossing.y = event_motion.y = event.y_root - y_window;
  124.  
  125.                     widget.enter_notify_event(event_crossing);
  126.                     widget.motion_notify_event(event_motion);
  127.                 } else {
  128.                     var event_new = Gdk.EventCrossing();
  129.                     event_new.type = Gdk.EventType.LEAVE_NOTIFY;
  130.                     event_new.window = window;
  131.                     event_new.x = event.x_root - x_window;
  132.                     event_new.y = event.y_root - y_window;
  133.  
  134.                     widget.leave_notify_event(event_new);
  135.                 }
  136.             }
  137.         }
  138.        
  139.         return true;
  140.     }
  141.    
  142.     private bool on_enter_notify_event(Gdk.EventCrossing event) { return true; }
  143.    
  144.     private bool on_leave_notify_event(Gdk.EventCrossing event) {
  145.         foreach (var widget in this.get_children()) {
  146.        
  147.             widget.set_data("over", "false");
  148.                
  149.             foreach (var window in widget.get_window().get_children()) {
  150.                 int x_window, y_window;
  151.                 window.get_origin(out x_window, out y_window);
  152.  
  153.                 var event_new = event;
  154.                 event_new.window = window;
  155.                 event_new.x = event.x_root - x_window;
  156.                 event_new.y = event.y_root - y_window;
  157.  
  158.                 widget.leave_notify_event(event_new);
  159.             }
  160.         }
  161.    
  162.         return true;
  163.     }
  164.    
  165.     private bool on_parent_key_press_event(Gdk.EventKey event) {
  166.         foreach (var child in this.get_all_child_widgets()) {
  167.             if (child.is_focus) {
  168.                 child.key_press_event(event);
  169.             }
  170.         }
  171.    
  172.         return true;
  173.     }
  174.  
  175. }
Advertisement
Add Comment
Please, Sign In to add comment