Re: How to create scales for range widgets?

Vlad Harchev wrote:

>  Could you post your stripped-down source (probably with main function) to
> help us helping you?

A bit hard to strip down but I'll try.

>  I addressed this about half a year ago without any problems.

A key issue for me is to be able to do non standard mappings.  Regardless, it
should be the same.  It's kind of like a clock, where I need values to go
from 1:00 up to 12:59, then right to 1:00.  I have a "conversion" function
that will change values coming in from the adjustment.

Here's a sample function.  Bascially just call it with a ptr to an
adjustment.  It takes in the adj values and creates a slider range widget and
a scale next to it, with some frames to make it look nice.  It also adds a
text box at the bottom which will display the adjustment's "value."  The
problem is that with different "steps" the scale listing gets skewed.  I find
no easy way to correlate a scale to a range widgets value / range.  It always
seems to be ok in one case, but then off in another:


    a slider from 0 - 100 with steps of 10
    vs a slider from 5 - 20 in steps of 5

Here's a sample fn:

GtkAdjustment *slide_adj[16];
GtkAdjustment *text_adj[16];
SPECIAL_struct slide_params[16];  /* max,min, init, etc... */

void make_slider (int adj_no, GtkWidget *box)
  GtkWidget *hbox, *vbox, *tvbox, *s_table;
  GtkWidget *label, *tlabel;
  GtkWidget *vscale;
  GtkWidget *vframe, *lframe;
  char tstring[2];
  gfloat i;
  gint j;
  gfloat sincr;
  float steps;
  int t_ival,isteps,maxcell,maxpad,pad;

  int digs;
  double init, min, max, s_incr, p_incr;
  AdjFlag *flags;

  digs = slide_params[adj_no].sig_digits;
  init = slide_params[adj_no].init;
  min = slide_params[adj_no].min;
  max = slide_params[adj_no].max;
  s_incr = slide_params[adj_no].s_incr;
  p_incr = slide_params[adj_no].p_incr;

  flags = slide_params[adj_no].sflags;

  slide_adj[adj_no] = gtk_adjustment_new (init, min, max+p_incr, s_incr,
p_incr, p_incr);
  if (!GTK_IS_ADJUSTMENT(slide_adj[adj_no])) {
    perror("slider param error");

  vframe = gtk_frame_new(NULL);
  lframe = gtk_frame_new(NULL);

  /* Create a label */
  label = gtk_label_new(slide_params[adj_no].name);
  /* Vertical box for label, scale+slider, value display */
  vbox = gtk_vbox_new(FALSE,0);

  /* Horizontal box for the slider and scale */
  hbox = gtk_hbox_new(FALSE,0);
  /* Vertical box for the scale #'s */
  tvbox = gtk_vbox_new(TRUE,0);

  /* Create the slider */
  vscale = gtk_vscale_new (GTK_ADJUSTMENT (slide_adj[adj_no]));
  scale_set_default_values (GTK_SCALE (vscale));
  gtk_scale_set_digits (GTK_SCALE (vscale), digs);  /* Accuracy */

  /* Put the label in the vbox ... inside a frame */
  gtk_container_add(GTK_CONTAINER(lframe) , label);
  gtk_box_pack_start (GTK_BOX (vbox), lframe, FALSE, FALSE, 0);

  sincr = 0.0;
  /*  printf("slide_params[%d].flag =
%d\n",adj_no,slide_params[adj_no].flag); */
  if (check_adj_flag(flags,NORMAL)) {
    /* Create a scale, and put digits into vertical box */
    sincr = make_incr(min,max); /* Create a reasonable increment amount */
    steps = (max-min)/sincr;
 steps = rint(steps);
 isteps = (int)steps;
    max += (sincr/2);
 s_table = gtk_table_new( isteps, 1, FALSE);
    while(i<=max) {
      if (max >= 1000) {
      else if (max >= 100) {
      else if (max >= 10) {
      else if (max >= 0) {
      else {
      tlabel = gtk_label_new(tstring);
      gtk_widget_show (tlabel);
      gtk_table_attach_defaults (GTK_TABLE (s_table), tlabel, 0, 1, j,j+1);
   i += sincr;
 if (isteps < 10) {  /* Attempt at scaling */
   maxpad = (int)rint(steps/2);
   for(j=0;j<maxcell;j++) {
  if (j<3)
    pad += 3;
  if (j>(steps-3))
    pad -= 1;
  gtk_table_set_row_spacing( s_table, j, pad);

  /* Put slider and scale into hbox */
  gtk_box_pack_start (GTK_BOX (tvbox), s_table, TRUE, TRUE, 10);
  gtk_box_pack_start (GTK_BOX (hbox), tvbox, TRUE, TRUE, 2);
  gtk_box_pack_start (GTK_BOX (hbox), vscale, TRUE, TRUE, 0);

  gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);

  /* Text box for data display */
  text_adj[adj_no] = GTK_OBJECT(gtk_entry_new_with_max_length(6));

  gtk_widget_set_usize (GTK_WIDGET(text_adj[adj_no]), (gint) 20, (gint) 20);
  gtk_entry_set_editable(GTK_ENTRY(text_adj[adj_no]), TRUE);

  /* Put it in the vbox */
  gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET(text_adj[adj_no]), FALSE,
FALSE, 0);

  /* A frame around the vbox so it looks nice :-) */
  gtk_container_add(GTK_CONTAINER(vframe) , vbox);
  gtk_box_pack_start (GTK_BOX (box), vframe, TRUE, TRUE, 0);

  /* Connect signals */
  /* FIXME:  need to do this all int one "cb_trigger_slinc()" */
  gtk_signal_connect (GTK_OBJECT(slide_adj[adj_no]), "value_changed",
       GTK_SIGNAL_FUNC(cb_trigger_slider_slinc), (gint *)adj_no);

  /*   gtk_signal_connect (GTK_OBJECT(slide_adj[adj_no]), "value_changed", */

  /*        GTK_SIGNAL_FUNC(cb_set_sockstr), (gint *)adj_no); */
  gtk_signal_connect (GTK_OBJECT(slide_adj[adj_no]), "value_changed",
        GTK_SIGNAL_FUNC(cb_set_text), (gint *)adj_no);


  gtk_signal_connect (GTK_OBJECT(text_adj[adj_no]), "activate",
       GTK_SIGNAL_FUNC(cb_set_val), (gint *)adj_no);
  gtk_signal_connect(GTK_OBJECT (text_adj[adj_no]), "key_press_event",
      GTK_SIGNAL_FUNC(cb_fake_signal), (gint *)adj_no);

  gtk_widget_show (label);
  gtk_widget_show (tvbox);
  gtk_widget_show (s_table);
  gtk_widget_show (vscale);
  gtk_widget_show (hbox);
  gtk_widget_show (GTK_WIDGET(text_adj[adj_no]));
  gtk_widget_show (vbox);


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