diff --git a/settings/xfpm-settings.c b/settings/xfpm-settings.c index 1ecfa86..9dae720 100644 --- a/settings/xfpm-settings.c +++ b/settings/xfpm-settings.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -257,11 +258,71 @@ battery_critical_changed_cb (GtkWidget *w, XfconfChannel *channel) } void +map_value_solve (gint lower, gint upper, gdouble *a, gdouble *b) +{ + /* Do some math to make the sliders use an exponential scale, while + * respecting the configured limits. This is simple algebra, but C makes + * it look cryptic. + * + * y = a * x^e + b + * inversely, + * x = ((y - b) / a)^(1/e) + * + * where x is the input value, y is the output value, e is the exponent + * (controls the magnitude of the effect), and a and b are the constants we + * are solving for. These are our constraints: + * + * l = a * l^e + b + * u = a * u^e + b + * + * where l and u are the lower and upper limits, respectively. These are + * given. We are also given the exponent e. + */ + + gdouble l = (gdouble)lower; + gdouble u = (gdouble)upper; + gdouble e = 2.0; /* exponent */ + + /* solving our constraints */ + *b = (u - (l * pow(u,e) / pow(l,e))) + / + (-(pow(u,e) / pow(l,e)) + 1); + *a = (l - *b) / pow(l,e); +} + +gdouble +map_slider_value (gdouble value, gint lower, gint upper) +{ + gdouble a, b; + gdouble e = 2.0; + map_value_solve(lower, upper, &a, &b); + /* determine the final mapped value */ + /* y = a * x^e + b */ + return a * pow(value, e) + b; +} + +gdouble +unmap_slider_value (gdouble value, gint lower, gint upper) +{ + gdouble a, b; + gdouble e = 2.0; + map_value_solve(lower, upper, &a, &b); + /* determine the final unmapped value */ + /* x = ((y - b) / a)^(1/e) */ + return pow((value - b) / a, (1.0/e)); +} + +void inactivity_on_ac_value_changed_cb (GtkWidget *widget, XfconfChannel *channel) { - gint value = (gint)gtk_range_get_value (GTK_RANGE (widget)); + gdouble value = gtk_range_get_value (GTK_RANGE (widget)); + + /* map the value of this slider exponentially, to make it easier to use */ + value = map_slider_value (value, + 4, /* lower limit */ + 360); /* upper limit */ - if (!xfconf_channel_set_uint (channel, PROPERTIES_PREFIX ON_AC_INACTIVITY_TIMEOUT, value)) + if (!xfconf_channel_set_uint (channel, PROPERTIES_PREFIX ON_AC_INACTIVITY_TIMEOUT, (gint)value)) { g_critical ("Cannot set value for property %s\n", ON_AC_INACTIVITY_TIMEOUT); } @@ -270,9 +331,14 @@ inactivity_on_ac_value_changed_cb (GtkWidget *widget, XfconfChannel *channel) void inactivity_on_battery_value_changed_cb (GtkWidget *widget, XfconfChannel *channel) { - gint value = (gint)gtk_range_get_value (GTK_RANGE (widget)); + gdouble value = gtk_range_get_value (GTK_RANGE (widget)); + + /* map the value of this slider exponentially, to make it easier to use */ + value = map_slider_value (value, + 4, /* lower limit */ + 360); /* upper limit */ - if (!xfconf_channel_set_uint (channel, PROPERTIES_PREFIX ON_BATTERY_INACTIVITY_TIMEOUT, value)) + if (!xfconf_channel_set_uint (channel, PROPERTIES_PREFIX ON_BATTERY_INACTIVITY_TIMEOUT, (gint)value)) { g_critical ("Cannot set value for property %s\n", ON_BATTERY_INACTIVITY_TIMEOUT); } @@ -636,7 +702,12 @@ gchar * format_inactivity_value_cb (GtkScale *scale, gdouble value, gpointer data) { gint h, min; - + + /* map the value of this slider exponentially, to make it easier to use */ + value = map_slider_value (value, + 4, /* lower limit */ + 360); /* upper limit */ + if ( (gint)value <= 4 ) return g_strdup (_("Never")); else if ( (gint)value < 60 ) @@ -935,6 +1006,8 @@ xfpm_settings_on_battery (XfconfChannel *channel, gboolean auth_suspend, } val = xfconf_channel_get_uint (channel, PROPERTIES_PREFIX ON_BATTERY_INACTIVITY_TIMEOUT, 14); + /* unmap minutes back into the correct slider position */ + val = (gint)unmap_slider_value ((gdouble)val, 4, 360) + 1; gtk_range_set_value (GTK_RANGE (inact_timeout), val); @@ -1161,6 +1234,8 @@ xfpm_settings_on_ac (XfconfChannel *channel, gboolean auth_suspend, } val = xfconf_channel_get_uint (channel, PROPERTIES_PREFIX ON_AC_INACTIVITY_TIMEOUT, 14); + /* unmap minutes back into the correct slider position */ + val = (gint)unmap_slider_value ((gdouble)val, 4, 360) + 1; gtk_range_set_value (GTK_RANGE (inact_timeout), val); /*