LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   deprecated gtk_range_set_update_policy replacement? (https://www.linuxquestions.org/questions/programming-9/deprecated-gtk_range_set_update_policy-replacement-941641/)

Keith Hedger 04-25-2012 05:32 AM

deprecated gtk_range_set_update_policy replacement?
 
I am trying to make a small app gtk3 compliant and the gtk_range_set_update_policy has been removed from the GtkRange widget, what I need is to get only the value of the range at the end ( on mouse up ) not continuously, ie I want to be able to do
Code:

gtk_range_set_update_policy((GtkRange*)advancedRange,GTK_UPDATE_DISCONTINUOUS);
Been googling but cant seem to find a solution.
The value is queried in a callback, the value is then used in a relatively long routine hence I only need the last value from the range widget NOT the intermediate value.
I'm using 'C'

manu-tm 04-25-2012 05:59 AM

For better chances to find an answer, you could also ask on one of GTK mailing lists:
http://www.gtk.org/mailing-lists.php

Keith Hedger 04-25-2012 06:17 AM

Thanks for the suggestion but there seems to be no recent references to gtk_range_set_update_policy and I don't really want to sign up for yet another mailing list for one question which I would have thought would be quite common, but I guess not, if I can't find a solution soon I guess I'll have to sign up.

Keith Hedger 04-27-2012 06:13 AM

No one? I can't be the only one with this problem, surely?

gnashley 04-27-2012 12:40 PM

Isn't there a doc on the gtk site about how to port code from gtk2 to gtk3?

Keith Hedger 04-28-2012 06:03 AM

Quote:

Originally Posted by gnashley (Post 4664703)
Isn't there a doc on the gtk site about how to port code from gtk2 to gtk3?

Yeah had a look at that but it just says that the function is deprecated and that there is no replacement.

gnashley 04-28-2012 11:40 AM

Well, then you might copy the parts you need from the gtk2 sources.

Keith Hedger 04-28-2012 02:54 PM

Quote:

Originally Posted by gnashley (Post 4665426)
Well, then you might copy the parts you need from the gtk2 sources.

Seriously?

Nominal Animal 04-28-2012 03:36 PM

Quote:

Originally Posted by Keith Hedger (Post 4662557)
what I need is to get only the value of the range at the end ( on mouse up ) not continuously

Okay. So, connect the button-release-event and key-release-event signals of the GtkScale or GtkRange object (inherited from GtkWidget) to a function which remembers the previous state. Query the current state (using e.g gtk_range_get_value()). If the current state differs, then trigger the long routine. Pick the set of signals based on how your widget can be accessed.

Keith Hedger 04-28-2012 04:56 PM

Tried "button-release-event" the range widget doesn't seem to respond to this haven't looked at "key-release-event", will try tomorrow.

Nominal Animal 04-28-2012 08:41 PM

Quote:

Originally Posted by Keith Hedger (Post 4665584)
Tried "button-release-event" the range widget doesn't seem to respond to this haven't looked at "key-release-event", will try tomorrow.

That is strange, as it works fine for me. Perhaps I'm using different library version? On my machine, both libgtk-3-0 and libgtk-3-dev are version 3.2.0-0ubuntu6.

Please try the following example program, to see if it works for you too:
Code:

#include <gtk/gtk.h>
#include <stdio.h>

void value_changed(GtkRange *range, gpointer user_data)
{
    /* This does get called:
        fputs("value_changed\n", stdout);
        fflush(stdout);
    */
}

gboolean button_release_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
    gdouble saved = *(gdouble *)user_data;
    gdouble value = gtk_range_get_value((GtkRange *)widget);

    if (saved != value) {
        *(gdouble *)user_data = value;
        fprintf(stdout, "button_release_event at %g\n", (double)value);
        fflush(stdout);
    } else {
        fprintf(stdout, "button_release_event ignored\n");
        fflush(stdout);
    }

    /* Do propagate this event further. */
    return FALSE;
}

gboolean focus_out_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
    gdouble saved = *(gdouble *)user_data;
    gdouble value = gtk_range_get_value((GtkRange *)widget);

    if (saved != value) {
        *(gdouble *)user_data = value;
        fprintf(stdout, "focus_out_event at %g\n", (double)value);
        fflush(stdout);
    } else {
        fprintf(stdout, "focus_out_event ignored\n");
        fflush(stdout);
    }

    /* Do propagate this event further. */
    return FALSE;
}

gboolean key_release_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
    gdouble saved = *(gdouble *)user_data;
    gdouble value = gtk_range_get_value((GtkRange *)widget);

    if (saved != value) {
        *(gdouble *)user_data = value;
        fprintf(stdout, "key_release_event at %g\n", (double)value);
        fflush(stdout);
    } else {
        fprintf(stdout, "key_release_event ignored\n");
        fflush(stdout);
    }

    /* Do propagate this event further. */
    return FALSE;
}

int main(int argc, char *argv[])
{
    GtkWidget  *window;
    GtkWidget  *scale;
    gdouble      scale_old;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size(GTK_WINDOW(window), 400, 50);
    gtk_window_set_title(GTK_WINDOW(window), "Range");
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    scale_old = -1.0;
    scale = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0.0, 100.0, 0.1);
    gtk_container_add(GTK_CONTAINER(window), scale);
    g_signal_connect(scale, "value-changed", G_CALLBACK(value_changed), NULL);
    g_signal_connect(scale, "button-release-event", G_CALLBACK(button_release_event), &scale_old);
    g_signal_connect(scale, "focus-out-event", G_CALLBACK(focus_out_event), &scale_old);
    g_signal_connect(scale, "key-release-event", G_CALLBACK(key_release_event), &scale_old);

    gtk_widget_show(scale);
    gtk_widget_show(window);
    gtk_main();

    return 0;
}

For those not familiar with building GTK+ C programs, save the above as range.c, and compile using
Code:

gcc range.c `pkg-config gtk+-3.0 --cflags --libs` -o range
When you move the slider, the value is updated immediately (since the relevant callback, value_change, does nothing). You can uncomment the output in the value_change function to check.

When you release the slider, by releasing the mouse button, or releasing the key, or just by focusing elsewhere, one of the three callback functions (*_event) gets called to trigger the desired action. The example program will just output the new value to standard output.

Note that all three signals could have been wired to the same callback function. I used separate functions, so I could easily observe that all desired signals do in fact occur.

Note how I used the user data pointer to point to a gdouble containing the last acted-upon value. Only when it is different to the current value, is there any work to do. When the last acted-upon value is still the same, there is nothing to do, and the signal can be ignored.

When there is work to do, the last acted-upon value should be updated. You most likely want to update it before starting the work (rather than when completing the work), so that you update it to the value you used for the large work. Otherwise you'd likely miss updates in between; the users see a different value than the other effects are.

Keith Hedger 04-29-2012 05:58 AM

Thanks Nominal Animal!

That works just fine, when I tried using the "button-release-event" I used "g_signal_connect_after" instead of "g_signal_connect" to connect the callback which is why it did not work. I mostly always use the "_after" variant and no problems up 'till now, odd.

Thanks again, marking thread as solved.


All times are GMT -5. The time now is 10:10 PM.