Very good. Your text should be IMHO added to library.gnome.org.
On Sat, Sep 18, 2010 at 9:24 AM, richard boaz <[email protected]> wrote:
> yep, i concur with the set sensitive method.
>
> the way i do this is: when the user:
>
> - executes something that gets done in the background,
> - that requires some time,
> - is non-interruptable,
> - and must complete before any next user action
>
> loop over a list of GtkWidget pointers i have saved to a g_ptr_array() at
> program startup/widget creation, making them insensitive for the entire
> duration of the blocking operation. once the operation completes/returns,
> execute the set sensitive loop again making all necessary widgets again
> sensitive, i.e., return to the user access to the widget's function.
>
> you can also use this paradigm to make various widgets visible/invisible,
> editable/uneditable, or sensitive/insensitive, according to one of many
> possible display states. your example has only two states, ON or OFF;
> however, many other examples abound, e.g., connected/not connected to a DB,
> viewing data in read-only vs. edit mode, background op is interruptable
> (making interrupt button the only possible action), etc.
>
> in the example below, the following end-user display states are defined:
>
> - No connection to DB
> - DB Connection to a particular DB - read-only mode
> - DB Connection to a particular DB - edit mode
> - DB Connection to server - DB Creation mode
>
> for each state, a particular widget is defined to be:
>
> - sensitive or insensitive
> - visible or invisible
> - editable or non-editable
>
> with this particular model, all states are absolutely defined. that is, no
> assumptions are made as to the previous state when setting a widget's
> current display state. this is good since you can then just call
> setDispState() for a particular display state and know that all widgets
> will be correctly defined and displayed regardless where you're coming from.
> as well, as development continues, one need only to add new widgets to the
> pointer arrays appropriately and everything else just keeps running, no need
> to write anything further to make a widget's state be what it needs to be.
>
> cheers,
>
> richard
>
>
> ==== BEGIN CODE SNIPPET ==============
>
> enum { // display states
> DBNOCONN, // No DB Connection
> DBDISPLAY, // DB Info Display
> DBEDIT, // DB Info Edit
> DBCREATE, // DB Create
> TTLDBDISPSTATES
> };
>
> enum { // display state types
> DISPSENS, // sensitivity
> DISPVISIBLE, // visibility
> DISPEDITABLE, // editable
> TTLDISPTYPES
> };
>
> enum { // display state settings
> OFF,
> ON,
> TTLDISPDIRS
> };
>
> GPtrArray *dispState[TTLDBDISPSTATES][TTLDISPTYPES][TTLDISPDIRS];
>
> static void _setSensitive(GtkWidget *widget, gpointer s)
> {
> gboolean sens = (gboolean) GPOINTER_TO_INT(s);
> gtk_widget_set_sensitive(widget, sens);
> }
>
> static void _setVisible(GtkWidget *widget, gpointer v)
> {
> gboolean vis = (gboolean) GPOINTER_TO_INT(v);
> vis ? gtk_widget_show(widget) : gtk_widget_hide(widget);
> }
>
> static void _setEditable(GtkWidget *widget, gpointer e)
> {
> gboolean edit = (gboolean) GPOINTER_TO_INT(e);
> gtk_editable_set_editable(GTK_EDITABLE(widget), edit);
> }
>
> void setDispState(int state)
> { // set all widgets ON | OFF for the requested state
> int i;
> for (i=0;i<TTLDISPDIRS;i++)
> {
> g_ptr_array_foreach(dispState[state][DISPSENS][i], (GFunc)
> _setSensitive, GINT_TO_POINTER(i));
> g_ptr_array_foreach(dispState[state][DISPVISIBLE][i], (GFunc)
> _setVisible, GINT_TO_POINTER(i));
> g_ptr_array_foreach(dispState[state][DISPEDITABLE][i], (GFunc)
> _setEditable, GINT_TO_POINTER(i));
> }
> }
>
> void makeWidgets()
> {
> int i, j, k;
> // make our display state pointer arrays
> for (i=0;i<TTLDBDISPSTATES;i++)
> for (j=0;j<TTLDISPTYPES;j++)
> for (k=0;k<TTLDISPDIRS;k++)
> dispState[i][j][k] = g_ptr_array_new();
>
> // A Manage Button that is only displayed when no DB Connection exists,
> otherwise invisible
> button = gtk_button_new_with_label("Manage");
> g_signal_connect((button), "clicked", G_CALLBACK(servers), NULL);
> g_ptr_array_add(dispState[DBNOCONN][DISPVISIBLE][ON], button);
> g_ptr_array_add(dispState[DBDISPLAY][DISPVISIBLE][OFF], button);
> g_ptr_array_add(dispState[DBEDIT][DISPVISIBLE][OFF], button);
> g_ptr_array_add(dispState[DBCREATE][DISPVISIBLE][OFF], button);
>
> // An Entry Area that is only editable when creating a database,
> otherwise read-only
> entry = gtk_entry_new();
> gtk_widget_set_tooltip_text(entry, "Name of the Database");
> g_ptr_array_add(dispState[DBNOCONN][DISPEDITABLE][OFF], entry);
> g_ptr_array_add(dispState[DBDISPLAY][DISPEDITABLE][OFF], entry);
> g_ptr_array_add(dispState[DBEDIT][DISPEDITABLE][OFF], entry);
> g_ptr_array_add(dispState[DBCREATE][DISPEDITABLE][ON], entry);
>
> // A button that is sensitive only when editing a database, otherwise not
> selectable
> button = gtk_button_new_with_label("ADD");
> g_ptr_array_add(dispState[DBNOCONN][DISPSENS][OFF], button);
> g_ptr_array_add(dispState[DBDISPLAY][DISPSENS][OFF], button);
> g_ptr_array_add(dispState[DBEDIT][DISPSENS][ON], button);
> g_ptr_array_add(dispState[DBCREATE][DISPSENS][ON], button);
>
> // add all other widgets appropriately as they are created
> //...
>
> // Initialize Display State to NO DB Connection
> setDispState(DBNOCONN);
> }
>
> ==== END CODE SNIPPET ==============
>
> On Sat, Sep 18, 2010 at 4:39 AM, Milosz Derezynski <
> [email protected]> wrote:
>
>> One option as already said is a modal dialog with progress bar, another
>> option is to have a progress bar in the main GUI and set the rest of the GUI
>> insensitive (you _really_ should familiarize yourself with
>> gtk_widget_set_sensitive() ).
>>
>>
>> http://library.gnome.org/devel/gtk/unstable/GtkWidget.html#gtk-widget-set-sensitive
>>
>> M.
>>
>>
>> On Sat, Sep 18, 2010 at 3:01 AM, Jeffrey Barish <
>> [email protected]> wrote:
>>
>>> Lex Trotman wrote:
>>>
>>> > On 18 September 2010 08:22, Jeffrey Barish <[email protected]>
>>> > wrote:
>>> >> Jeffrey Barish wrote:
>>> >>
>>> >>> My application has one operation that runs for a long time (~1
>>> minute).
>>> >>> During this time, the user is not allowed to do anything.
>>> Nevertheless,
>>> >>> I felt that it was important to give the user some feedback that the
>>> >>> application is still alive and that the operation is running. My
>>> >>> solution was to print a message in a TextBuffer and follow the
>>> message
>>> >>> with a string
>>> >>> of dots that grows in length by one every second. To get the
>>> TextView
>>> >>> to update, I used events_pending/main_iteration. This all works
>>> nicely.
>>> >>> However, because of the events_pending/main_iteration statements, the
>>> >>> entire
>>> >>> GUI is now alive. Thus, the user is able to do things that disrupt
>>> the
>>> >>> long-running operation. Basically, what I want is a way to get the
>>> >>> TextView to update so that I can update the progress indicator but
>>> for
>>> >>> everything
>>> >>> else still to be locked out. Is there a way to do this?
>>> >>
>>> >> Here's a possibility that seems to work:
>>> >>
>>> >> I used event_handler_set to define an event handler that filters out
>>> all
>>> >> events (by not calling main_do_event) except EXPOSE while the
>>> >> long-running operation is underway. I wish that there were a way to
>>> >> restore the default event handler, but there is only a set method.
>>> >> Anything bad about this solution?
>>> >> --
>>> >> Jeffrey Barish
>>> >
>>> > You should show progress and block the application by showing a modal
>>> > dialog containing a progress bar.
>>> >
>>> > Cheers
>>> > Lex
>>>
>>> Good point. The TextView is where I put all messages, so I didn't want
>>> to
>>> put the progress indicator in a different place, if I could avoid it.
>>>
>>> My solution still seems to be working, but I worry about having all
>>> events
>>> go through my filter all the time because it seems a bit inefficient.
>>> --
>>> Jeffrey Barish
>>>
>>> _______________________________________________
>>> gtk-list mailing list
>>> [email protected]
>>> http://mail.gnome.org/mailman/listinfo/gtk-list
>>>
>>
>>
>>
>> --
>> Please note that according to the German law on data retention,
>> information on every electronic information exchange with me is
>> retained for a period of six months.
>> [Bitte beachten Sie, dass dem Gesetz zur Vorratsdatenspeicherung zufolge
>> jeder elektronische Kontakt mit mir sechs Monate lang gespeichert wird.]
>>
>> _______________________________________________
>> gtk-list mailing list
>> [email protected]
>> http://mail.gnome.org/mailman/listinfo/gtk-list
>>
>>
>
--
Please note that according to the German law on data retention,
information on every electronic information exchange with me is
retained for a period of six months.
[Bitte beachten Sie, dass dem Gesetz zur Vorratsdatenspeicherung zufolge
jeder elektronische Kontakt mit mir sechs Monate lang gespeichert wird.]
_______________________________________________
gtk-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gtk-list