Re: GTK signals question.



Dne 05.03.2014 (sre) ob 18:38 +1100 je Chris Angelico napisal(a):
On Wed, Mar 5, 2014 at 6:29 PM, Tristan Van Berkom
<tristan upstairslabs com> wrote:
Interesting, if I were you I would try to share the same adjustment
between all of your views.

I.e. I would keep the adjustment in the finest grained unit of each
unit you want to display, and have your spin buttons format the value
differently depending on what they are used for (or perhaps use GtkScale
if that makes sense in your UI).

Now *that* is an elegant solution, if it can be done!

Sure it can;) In the code below, this sharing is implemented between
spin buttons in first row. Beware though that now both widgets increment
for the same angle - increment in fixed to 0.1 radians.

If you need more flexibility, you can use 2 adjustments and bind their
"value" property through simple transformation. This method is
implemented in second row. Now incrementing can be done independently in
both widgets (first widgets increments in 0.1 radians, second in 1
degree steps).

----------8<-------------

#include <gtk/gtk.h>

static gboolean
cb_output (GtkSpinButton *spin)
{
  GtkAdjustment *adj = gtk_spin_button_get_adjustment (spin);
  double val = gtk_adjustment_get_value (adj);
  gchar *text = g_strdup_printf ("%d", (gint)(val * 180 / G_PI + .5));

  gtk_entry_set_text (GTK_ENTRY (spin), text);
  g_free (text);

  return TRUE;
}

static gint
cb_input (GtkSpinButton *spin,
          gdouble       *value)
{
  gchar const *text = gtk_entry_get_text (GTK_ENTRY (spin));
  double val = g_strtod (text, NULL);
  *value = val * G_PI / 180;

  return TRUE;
}

static gboolean
rad_to_deg (GBinding     *bind G_GNUC_UNUSED,
            const GValue *from,
            GValue       *to,
            gpointer      data G_GNUC_UNUSED)
{
  double val = g_value_get_double (from);
  g_value_set_double (to, val * 180 / G_PI);

  return TRUE;
}

static gboolean
deg_to_rad (GBinding     *bind G_GNUC_UNUSED,
            const GValue *from,
            GValue       *to,
            gpointer      data G_GNUC_UNUSED)
{
  double val = g_value_get_double (from);
  g_value_set_double (to, val / 180 * G_PI);

  return TRUE;
}

int
main (int    argc,
      char **argv)
{
  GtkWidget *window, *grid, *s1, *s2, *s3, *s4;
  GtkAdjustment *adj, *adj1, *adj2;

  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  g_signal_connect (window, "destroy", gtk_main_quit, NULL);

  grid = gtk_grid_new ();
  gtk_container_add (GTK_CONTAINER (window), grid);

  /* Use single adjustment: both spin buttons use radians as the data
   * storage, second one converts radians to degrees on input/output */
  adj = gtk_adjustment_new (1, 0, 2 * G_PI, 0.1, 0.5, 0);
  s1 = gtk_spin_button_new (adj, 0.5, 2);
  g_object_set (s1, "expand", TRUE, NULL);
  gtk_grid_attach (GTK_GRID (grid), s1, 0, 0, 1, 1);

  s2 = gtk_spin_button_new (adj, 0.5, 2);
  g_object_set (s2, "expand", TRUE, NULL);
  g_signal_connect (s2, "output", G_CALLBACK (cb_output), NULL);
  g_signal_connect (s2, "input", G_CALLBACK (cb_input), NULL);
  gtk_grid_attach (GTK_GRID (grid), s2, 1, 0, 1, 1);

  /* Use 2 adjustments: one in radians and one in degrees. GBinding
   * keeps values of those adjustments in sync */
  adj1 = gtk_adjustment_new (3.14, 0, 2 * G_PI, 0.1, 0.5, 0);
  s3 = gtk_spin_button_new (adj1, 0.5, 2);
  g_object_set (s3, "expand", TRUE, NULL);
  gtk_grid_attach (GTK_GRID (grid), s3, 0, 1, 1, 1);

  adj2 = gtk_adjustment_new (100, 0, 360, 1, 5, 0);
  s4 = gtk_spin_button_new (adj2, 0.5, 0);
  g_object_set (s4, "expand", TRUE, NULL);
  gtk_grid_attach (GTK_GRID (grid), s4, 1, 1, 1, 1);

  g_object_bind_property_full (adj1, "value", adj2, "value",
                               G_BINDING_BIDIRECTIONAL |
                               G_BINDING_SYNC_CREATE,
                               rad_to_deg, deg_to_rad,
                               NULL, NULL);

  gtk_widget_show_all (window);

  gtk_main ();

  return 0;
}

----------8<-----------

Cheers,
Tadej


-- 
Tadej Borovšak
tadej borovsak gmail com
tadeboro gmail com
blog.borovsak.si



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