Re: Status for long-running operation

2010-09-21 Thread Paul Davis
On Mon, Sep 20, 2010 at 2:37 AM, richard boaz  wrote:
> On Sun, Sep 19, 2010 at 8:33 PM, Paul Davis 
> wrote:
>>
>> On Sat, Sep 18, 2010 at 3:24 AM, richard boaz  wrote:
>> > yep, i concur with the set sensitive method.
>>
>> all good, except that in an ideal world, the sensitivity changes are
>> applied to GtkAction's, not widgets. this way, keybindings and other
>> methods of driving specific actions are all taken care of together.
>>
>> of course, not many GTK apps have been written with an action-centric
>> approach, which is unfortunate.
>
> but since GtkActions are pointers, and can be made both visible/invisible
> and/or sensitive/insensitive using available methods, can the paradigm not
> be extended to work for these "user-available functions" as well?

GtkActions are an encapsulation of user-available functions.
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Status for long-running operation

2010-09-21 Thread Pádraig Brady
On 17/09/10 22:01, 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?

fslint does this, except that it allows one
to click only a stop button. It does this in the
the look_busy() function by doing:

  self.stop.grab_focus()
  self.control_buttons.grab_add()

You could do the same with a dummy widget?

http://www.pixelbeat.org/fslint/

cheers,
Pádraig.
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Status for long-running operation

2010-09-19 Thread richard boaz
On Sun, Sep 19, 2010 at 8:33 PM, Paul Davis wrote:

> On Sat, Sep 18, 2010 at 3:24 AM, richard boaz  wrote:
> > yep, i concur with the set sensitive method.
>
> all good, except that in an ideal world, the sensitivity changes are
> applied to GtkAction's, not widgets. this way, keybindings and other
> methods of driving specific actions are all taken care of together.
>
> of course, not many GTK apps have been written with an action-centric
> approach, which is unfortunate.
>

but since GtkActions are pointers, and can be made both visible/invisible
and/or sensitive/insensitive using available methods, can the paradigm not
be extended to work for these "user-available functions" as well?

i would think yes, but since my program doesn't employ GtkAction (i.e., i am
unfamiliar with its particular implementation details), perhaps i'm missing
something.

richard
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Status for long-running operation

2010-09-19 Thread Paul Davis
On Sat, Sep 18, 2010 at 3:24 AM, richard boaz  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

all good, except that in an ideal world, the sensitivity changes are
applied to GtkAction's, not widgets. this way, keybindings and other
methods of driving specific actions are all taken care of together.

of course, not many GTK apps have been written with an action-centric
approach, which is unfortunate.
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Status for long-running operation

2010-09-18 Thread Milosz Derezynski
Very good. Your text should be IMHO added to library.gnome.org.

On Sat, Sep 18, 2010 at 9:24 AM, richard boaz  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   {
> 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 for (j=0;j   for (k=0;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 = 

Re: Status for long-running operation

2010-09-18 Thread richard boaz
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;iwrote:

> 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  > wrote:
>
>> Lex Trotman wrote:
>>
>> > On 18 September 2010 08:22, Jeffrey Barish 
>> > 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 i

Re: Status for long-running operation

2010-09-17 Thread Milosz Derezynski
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
wrote:

> Lex Trotman wrote:
>
> > On 18 September 2010 08:22, Jeffrey Barish 
> > 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
> gtk-list@gnome.org
> 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
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Status for long-running operation

2010-09-17 Thread Jeffrey Barish
Lex Trotman wrote:

> On 18 September 2010 08:22, Jeffrey Barish 
> 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
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Status for long-running operation

2010-09-17 Thread Lex Trotman
On 18 September 2010 08:22, Jeffrey Barish  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
>
> ___
> gtk-list mailing list
> gtk-list@gnome.org
> http://mail.gnome.org/mailman/listinfo/gtk-list
>

You should show progress and block the application by showing a modal
dialog containing a progress bar.

Cheers
Lex
___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Re: Status for long-running operation

2010-09-17 Thread Jeffrey Barish
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

___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list


Status for long-running operation

2010-09-17 Thread Jeffrey Barish
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?
-- 
Jeffrey Barish

___
gtk-list mailing list
gtk-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-list