[Glade-users] Glade questions.




Damon Chaplin wrote:

Matthew Tuck wrote:
5.  What's the best way to handle dynamic menus, both in the situation
where the whole menu is dynamic, and only part of the menu is dynamic?
In particular I can't find any way to create an empty submenu.

Create the stable part in Glade, then manipulate the widgets in your
code to add/remove menus. I don't think that would be too difficult.


It's not too difficult.

Here is some code from one of my functions.  I stored the return value
of the glade-generated create_...() function as pTextState->pTextWin, so
that is my root for looking up widgets by name.

The code here is mostly from glade, I built the interface including the
optional widgets, then cut that text out of the create_..() function and
moved it to a later function.  Note that I continue the glade practice
of adding pointers to my widgets as object data, by name, to the
toplevel widget.

The only consequence of this example is that my output text window is
inside an unnecessary vbox if the commandline label and entry widgets
are not present (in their own hbox).

There are layouts that would be tougher to accomodate.  E.g., a table
may not allow downsizing if widgets occupy the cells to be removed (or,
it may).  One would have to find some widgets by name, remove them from
the container, delete the container, add a new container, add back the
desired widgetes, add new widgets, and refresh.  But the vbox in my
example handles either having one or two items without problems.  I
suspect that menus whould be even easier.

One note, as a UI principle it is considered poor practice to change the
interface, as it confuses the operator.  My code is the interface to
underlying processes, and each underlying thing interface will always
look the same to the operator, but the display code is common by using
the dynamic addition.  If a set of menu choices is simply not available
at this point, or because of previous operator choices, setting them
insensitive is often clearer.

HTH,

Eric Monsler

/* After getting a message, well after window creation */
if(ntohl(pFormatMsg->bAcceptsCommand) != FALSE)
{
  GtkWidget *label_n_cmd_hbox;
  GtkWidget *label1;
  GtkWidget *cmd_entry1;
  GtkWidget *txt_n_cmd_vbox;
              
  /* First, find the vbox with text that we'll be adding to */
  txt_n_cmd_vbox = lookup_widget(pTextState->pTextWin,
                                 "txt_n_cmd_vbox");
              
  /* As we add widgets, we add data referring to them by
     name to our toplevel window object. */

  label_n_cmd_hbox = gtk_hbox_new (FALSE, 0);
  gtk_widget_ref (label_n_cmd_hbox);
  gtk_object_set_data_full (GTK_OBJECT (pTextState->pTextWin),
"label_n_cmd_hbox", label_n_cmd_hbox,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (label_n_cmd_hbox);
  gtk_box_pack_start (GTK_BOX (txt_n_cmd_vbox), label_n_cmd_hbox, FALSE,
TRUE, 0);
              
  label1 = gtk_label_new ("Command: ");
  gtk_widget_ref (label1);
  gtk_object_set_data_full (GTK_OBJECT (pTextState->pTextWin), "label1",
label1,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (label1);
  gtk_box_pack_start (GTK_BOX (label_n_cmd_hbox), label1, FALSE, FALSE,
0);
              
  cmd_entry1 = gtk_entry_new ();
  gtk_widget_ref (cmd_entry1);
  gtk_object_set_data_full (GTK_OBJECT (pTextState->pTextWin),
"cmd_entry1", cmd_entry1,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (cmd_entry1);

  gtk_signal_connect( GTK_OBJECT(cmd_entry1),
                      "activate",
                      GTK_SIGNAL_FUNC(vGenTextCommandEntered),
                      pTextState);
              

  gtk_box_pack_start (GTK_BOX (label_n_cmd_hbox), 
                      cmd_entry1, TRUE, TRUE, 0);
              
} /* End of setting up command entry. */




/* From my glade-generated create function.. */
/* ...Lots of other stuff */
  txt_n_cmd_vbox = gtk_vbox_new (FALSE, 0);
  gtk_widget_ref (txt_n_cmd_vbox);
  gtk_object_set_data_full (GTK_OBJECT (window1), "txt_n_cmd_vbox",
txt_n_cmd_vbox,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (txt_n_cmd_vbox);
  gtk_box_pack_start (GTK_BOX (vbox1), txt_n_cmd_vbox, TRUE, TRUE, 0);

  txt_scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
  gtk_widget_ref (txt_scrolledwindow1);
  gtk_object_set_data_full (GTK_OBJECT (window1), "txt_scrolledwindow1",
txt_scrolledwindow1,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (txt_scrolledwindow1);
  gtk_box_pack_start (GTK_BOX (txt_n_cmd_vbox), txt_scrolledwindow1,
TRUE, TRUE, 0);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW
(txt_scrolledwindow1), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);

  text1 = gtk_text_new (NULL, NULL);
  gtk_widget_ref (text1);
  gtk_object_set_data_full (GTK_OBJECT (window1), "text1", text1,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (text1);
  gtk_container_add (GTK_CONTAINER (txt_scrolledwindow1), text1);
  gtk_text_insert (GTK_TEXT (text1), NULL, NULL, NULL,
                   "No messages yet.", 16);
#if 0
  /* This was glade code, now moved to where we process a format message
*/
  label_n_cmd_hbox = gtk_hbox_new (FALSE, 0);
  gtk_widget_ref (label_n_cmd_hbox);

etc. etc. etc.





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]