Advertisement
Guest User

GtkHVBox

a guest
Oct 19th, 2011
182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Vala 11.03 KB | None | 0 0
  1. /*
  2.  * Nick Glynn 2011
  3.  * Johan Dahlin 2008
  4.  *
  5.  * A quite simple Gtk.Widget subclass which demonstrates how to subclass
  6.  * and do realizing, sizing and drawing. Originally based on widget.py in PyGTK
  7.  * and ported to GTK+ 3
  8.  *
  9.  * valac --pkg gtk+-3.0  ./main.vala
  10.  *
  11.  * http://www.valadoc.org/gtk+-3.0/Gtk.Container.html
  12.  * http://developer.gnome.org/gtk3/3.0/GtkContainer.html#gtk-container-get-resize-mode
  13.  * http://developer.gnome.org/gtkmm-tutorial/3.0/sec-custom-containers.html.en
  14.  * https://github.com/mdamt/blankon-panel
  15.  * https://live.gnome.org/Vala/CustomWidgetSamples
  16.  * http://git.xmms2.org/xmms2/abraca/tree/src/widgets/rating_entry.vala?id=ed5e182c4074f1bff56010658a36a75d95807921
  17.  */
  18.  
  19. using Gtk;
  20. using Cairo;
  21.  
  22. public class HVBox : Container {
  23.  
  24.     private int height = 28;
  25.     private int minimum_width = 0;
  26.     private int natural_width = 0;//store available width
  27.     private int natural_height = 0;
  28.     private int width = 0;
  29.     private Gtk.SizeRequestMode mode = Gtk.SizeRequestMode.HEIGHT_FOR_WIDTH;
  30.  
  31.     private List<Widget> children;
  32.     private Window HVBParent;
  33.  
  34.  
  35.     public HVBox(Window parent) {
  36.         set_has_window (false);
  37.         children = new List<Widget> ();
  38.         HVBParent=parent;
  39.     }
  40.  
  41.  
  42.     public static Gdk.Rectangle get_primary_monitor_geometry () {
  43.         Gdk.Rectangle r = {0, 0};
  44.         var screen = Gdk.Screen.get_default ();
  45.         screen.get_monitor_geometry (screen.get_primary_monitor(), out r);
  46.         return r;
  47.     }
  48.  
  49.  
  50.  
  51. /*3.2   public override void size_allocate (Gtk.Allocation allocation) {
  52. /*3.0*/ public override void size_allocate (Gdk.Rectangle allocation) {
  53.  
  54.         /*
  55.         if(allocation.width != this.natural_width){
  56.             this.queue_resize_no_redraw ();
  57.  
  58.             var minimum_height_1=0;
  59.             this._get_preferred_height_for_width(allocation.width,out minimum_height_1, out this.natural_height);
  60.             HVBParent.set_size_request (-1,this.natural_height);
  61.             stdout.printf("orig size_allocate !!!! natural_height=%d\n",this.natural_height);
  62.         }*/
  63.  
  64.         //base.size_allocate (allocation);
  65.         stdout.printf("orig size_allocate x=%d y=%d w=%d h=%d\n",allocation.x,allocation.y,allocation.width,allocation.height);
  66.  
  67.         //Gdk.Rectangle allocation
  68.         var pos_x=allocation.x;
  69.         var orig_pos_x = allocation.x;
  70.         var orig_pos_y = allocation.y;
  71.         var orig_pos_h = allocation.height;
  72.         var orig_pos_w = allocation.width;
  73.         var sum_w=0;
  74.         var sum_h=0;
  75.         var w_count=0;
  76.         var level=0;
  77.  
  78.  
  79.         foreach( Widget widget in this.children){
  80.             allocation.height=this.height;
  81.  
  82.  
  83.             var natural_width = 0;
  84. /*3.2               widget.get_preferred_width (out allocation.width, out natural_width);
  85. /*3.0           */  widget.get_preferred_width (out allocation.width, natural_width);
  86.  
  87.             if(w_count>0){
  88.                 if( (sum_w + allocation.width) > orig_pos_w-1){
  89.                     allocation.y += ( w_count > 0 ? allocation.height : 0);
  90.                     pos_x = orig_pos_x;
  91.                     sum_w = allocation.width;
  92.                     level++;
  93.                 }else{
  94.                     sum_w += allocation.width;
  95.                 }
  96.                 allocation.y = orig_pos_y+allocation.height * level;
  97.             } else {
  98.                 allocation.y = orig_pos_y;
  99.                 sum_w += allocation.width;
  100.             }//if w_count
  101.  
  102.             allocation.x=pos_x;
  103.  
  104.             widget.size_allocate(allocation);
  105.  
  106.             pos_x=orig_pos_x+sum_w;
  107.             w_count++;
  108.  
  109.         }//foreach
  110.  
  111.         allocation.x = orig_pos_x;
  112.         allocation.y = orig_pos_y;
  113.         allocation.height = allocation.height * (level+1);//(orig_pos_h>sum_h ? orig_pos_h : sum_h);
  114.         allocation.width  = orig_pos_w;
  115.  
  116.         stdout.printf("orig2 size_allocate x=%d y=%d w=%d h=%d\n",allocation.x,allocation.y,allocation.width,allocation.height);
  117.  
  118.         base.size_allocate (allocation);
  119.     }
  120.  
  121.  
  122.     public override void get_preferred_width (out int minimum_width, out int natural_width) {
  123.         var sum_w = 0;
  124.         var max_w = 0;
  125.         foreach( Widget widget in this.children){
  126. /*3.2           widget.get_preferred_width (out minimum_width, out natural_width);
  127. /*3.0       */  widget.get_preferred_width (out minimum_width,  natural_width);
  128.             max_w=(minimum_width>max_w ? minimum_width : max_w);
  129.             sum_w+=minimum_width;
  130.         }
  131.         this.minimum_width=minimum_width=this.width=max_w;
  132.         natural_width=sum_w;
  133.         stdout.printf("get_preferred_width minimum=%d natural=%d\n",minimum_width,natural_width);
  134.     }
  135.  
  136.     public override void get_preferred_width_for_height (int height,out int minimum_width, out int natural_width) {
  137.         var sum_w = 0;
  138.         foreach( Widget widget in this.children){
  139. /*3.2           widget.get_preferred_width (out minimum_width,out natural_width);
  140. /*3.0       */  widget.get_preferred_width (out minimum_width, natural_width);
  141.             sum_w+=minimum_width;
  142.         }
  143.         if(minimum_width>this.width){
  144.             minimum_width=(int)(sum_w/((int)(height/28)));
  145.         }else{
  146.             minimum_width=this.width;
  147.         }
  148.         natural_width=minimum_width;
  149.         stdout.printf("get_preferred_width_for_height=%d minimum=%d natural=%d\n",height,minimum_width,natural_width);
  150.     }
  151.  
  152.  
  153.     public override void get_preferred_height (out int minimum_height, out int natural_height) {
  154.  
  155.         natural_height=minimum_height=28;
  156.  
  157.         stdout.printf("get_preferred_height minimum=%d natural=%d\n",minimum_height,natural_height);
  158.     }
  159.  
  160.     public override void get_preferred_height_for_width (int width,out int minimum_height, out int natural_height) {
  161.  
  162.         /*workaround for min_height, if actual available width more than self minimum width*/
  163.         if( this.minimum_width!=width ||
  164.         !(this.minimum_width==width && this.natural_width >= width) ){
  165.             this.natural_width=width;
  166.         }
  167.  
  168.         this._get_preferred_height_for_width(this.natural_width,out minimum_height, out natural_height);
  169.         this.natural_height = natural_height;
  170.  
  171.         stdout.printf("get_preferred_height_for_width=%d != %d minimum=%d natural=%d\n",width,this.natural_width,minimum_height,natural_height);
  172.  
  173.     }
  174.  
  175.     private void _get_preferred_height_for_width (int width,out int minimum_height, out int natural_height) {
  176.         var max_h = 0;
  177.         var allocation = Gtk.Allocation();//don't use new for struct
  178.  
  179.         allocation.x=0;
  180.         allocation.y=0;
  181.         allocation.height=0;
  182.         allocation.width=width;
  183.  
  184.         //Gdk.Rectangle allocation
  185.         var pos_x=allocation.x;
  186.         var orig_pos_x = allocation.x;
  187.         var orig_pos_y = allocation.y;
  188.         var orig_pos_h = allocation.height;
  189.         var orig_pos_w = allocation.width;
  190.         var sum_w=0;
  191.         var sum_h=0;
  192.         var w_count=0;
  193.         var level=0;
  194.  
  195.  
  196.         foreach( Widget widget in this.children){
  197.             allocation.height=this.height;
  198.             var natural_width = 0;
  199. /*3.2           widget.get_preferred_width (out allocation.width, out natural_width);*/
  200. /*3.0       */  widget.get_preferred_width (out allocation.width, natural_width);
  201.  
  202.             if(w_count>0){
  203.                 if( (sum_w + allocation.width) > orig_pos_w-1){
  204.                     allocation.y += ( w_count > 0 ? allocation.height : 0);
  205.                     pos_x = orig_pos_x;
  206.                     sum_w = allocation.width;
  207.                     level++;
  208.                 }else{
  209.                     sum_w += allocation.width;
  210.                     //allocation.y=orig_pos_y+sum_h;
  211.                 }
  212.                 allocation.y = orig_pos_y+allocation.height * level;
  213.             } else {
  214.                 allocation.y = orig_pos_y;
  215.                 sum_w += allocation.width;
  216.             }//if w_count
  217.  
  218.             allocation.x=pos_x;//allocation2.width;
  219.             //stdout.printf("size_allocate x=%d y=%d w=%d h=%d\n",allocation.x,allocation.y,allocation.width,allocation.height);
  220.             pos_x=orig_pos_x+sum_w;
  221.             w_count++;
  222.         }//foreach
  223.  
  224.         allocation.x = orig_pos_x;
  225.         allocation.y = orig_pos_y;
  226.         allocation.height = allocation.height * (level+1);//(orig_pos_h>sum_h ? orig_pos_h : sum_h);
  227.         allocation.width  = orig_pos_w;
  228.  
  229.         //stdout.printf("orig2 size_allocate x=%d y=%d w=%d h=%d\n",allocation.x,allocation.y,allocation.width,allocation.height);
  230.  
  231.         minimum_height=natural_height=allocation.height;
  232.  
  233.     }//_get_preferred_height_for_width
  234.  
  235.     public override SizeRequestMode get_request_mode () {
  236.         //stdout.printf("get_request_mode\n");
  237.         return (this.mode /*| Gtk.SizeRequestMode.WIDTH_FOR_HEIGHT*/);//.CONSTANT_SIZE;//WIDTH_FOR_HEIGHT;//HEIGHT_FOR_WIDTH;
  238.  
  239.     }
  240.  
  241.     public override void forall_internal(bool include_internal,Gtk.Callback callback){
  242.         //stdout.printf("forall_internal %d is_internal=%s\n",(int)callback,include_internal.to_string());
  243.  
  244.         foreach( Widget widget in this.children){
  245.             callback(widget);
  246.         }
  247.     }
  248.  
  249.     public override void add (Widget widget){
  250.         stdout.printf("add\n");
  251.         widget.set_parent(this);
  252.         if(children.first()!=null)
  253.             children.append(widget);
  254.         else
  255.             children.prepend(widget);
  256.     }
  257.  
  258.     public override void remove (Widget widget){
  259.         stdout.printf("remove\n");
  260.         children.remove(widget);
  261.     }
  262.  
  263.     public Widget children_nth (int index){
  264.         stdout.printf("Get_from_index\n");
  265.         return children.nth_data(index);
  266.     }
  267.  
  268.     public Widget children_last (){
  269.         stdout.printf("children_last\n");
  270.             return children.last().data;
  271.     }
  272.  
  273. }
  274.  
  275. int main (string[] args) {
  276.     Gtk.init (ref args);
  277.  
  278.     var win = new Window ();
  279.     //win.set_size_request (20,20);
  280.     win.border_width = 5;
  281.     win.title = "Widget test";
  282.     win.destroy.connect (Gtk.main_quit);
  283.     //win.default_height=20;
  284.     //win.default_width =20;
  285.     win.resizable = true;
  286.  
  287.     //var frame = new Frame (".");
  288.     //win.add (frame);
  289.  
  290.     var hvbox = new HVBox(win);
  291.  
  292.  
  293.     var my_button = new Button.with_label ("1Click me!_____________");
  294.         my_button.set_has_window (false);
  295.         my_button.show();
  296.  
  297.         hvbox.add(my_button);
  298.  
  299.         my_button = new Button.with_label ("2Click me!");
  300.         my_button.set_has_window (false);
  301.         my_button.show();
  302.  
  303.         hvbox.add(my_button);
  304.  
  305.         my_button = new Button.with_label ("3Click me!______________________________________________________");
  306.         my_button.set_has_window (false);
  307.         my_button.show();
  308.  
  309.         hvbox.add(my_button);
  310.  
  311.         my_button = new Button.with_label ("4Click me!");
  312.         my_button.set_has_window (false);
  313.         my_button.show();
  314.  
  315.         hvbox.add(my_button);
  316.  
  317.         my_button = new Button.with_label ("5Click me!");
  318.         my_button.set_has_window (false);
  319.         my_button.show();
  320.  
  321.         hvbox.add(my_button);
  322.  
  323.         my_button = new Button.with_label ("6Click me!");
  324.         my_button.set_has_window (false);
  325.         my_button.show();
  326.  
  327.         hvbox.add(my_button);
  328.  
  329.     hvbox.set_vexpand(false);
  330.     hvbox.set_hexpand(false);
  331.  
  332.  
  333.  
  334.     var hbox = new VBox(false,0);
  335.  
  336.     var hbox2 = new VBox(false,0);
  337.  
  338.     var fmy_button = new Button.with_label ("add");
  339.     fmy_button.set_has_window (false);
  340.     fmy_button.show();
  341.     fmy_button.clicked.connect(()=>{
  342.             var fmy_button2 = new Button.with_label ("Auto button");
  343.             fmy_button2.set_has_window (false);
  344.             fmy_button2.show();
  345.             hvbox.add(fmy_button2);
  346.         });
  347.  
  348.     fmy_button.set_vexpand(true);
  349.     fmy_button.set_hexpand(true);
  350.  
  351.     hbox2.pack_start(fmy_button,false,false,0);
  352.  
  353.     fmy_button = new Button.with_label ("remove");
  354.     fmy_button.set_has_window (false);
  355.     fmy_button.show();
  356.     fmy_button.clicked.connect(()=>{
  357.             Widget w=hvbox.children_last();
  358.             hvbox.remove(w);
  359.             w.destroy();
  360.         });
  361.  
  362.     hbox2.pack_start(fmy_button,true,true,0);
  363.  
  364.     fmy_button.set_vexpand(false);
  365.     fmy_button.set_hexpand(false);
  366.  
  367.  
  368.     hbox.pack_start(hbox2,true,true,0);
  369.  
  370.     hbox.pack_start(hvbox,false,false,0);
  371.  
  372.     win.add (hbox);
  373.  
  374.  
  375.     win.show_all ();
  376.     Gtk.main ();
  377.  
  378.     return 0;
  379. }
  380.  
  381.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement