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
> <tris...@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.borov...@gmail.com
tadeb...@gmail.com
blog.borovsak.si

_______________________________________________
gtk-app-devel-list mailing list
gtk-app-devel-list@gnome.org
https://mail.gnome.org/mailman/listinfo/gtk-app-devel-list

Reply via email to