Re: How to create scales for range widgets?
- From: "David J. Topper" <topper virginia edu>
- To: Vlad Harchev <hvv hippo ru>, gtk-list gnome org
- Subject: Re: How to create scales for range widgets?
- Date: Tue, 22 Aug 2000 20:17:58 -0400
Vlad Harchev wrote:
> Could you post your stripped-down source (probably with main function) to
> help us helping you?
It's a bit hard to strip down but I'll try. The following compiles with:
gcc -g slider_stuff.c `gtk-config --cflags` `gtk-config --libs`
Just start moving the sliders and you'll see what I mean about scales,
values, and special type scales.
---- slider_stuff.c -----
#include <stdio.h>
#include <unistd.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include <math.h>
typedef enum {
NO = 0,
YES
} Bool;
typedef enum {
NORMAL=0,
OPC,
MAX_ADJ_FLAG
} AdjFlag;
typedef struct {
double init;
Bool inited;
Bool ainit;
double min;
double max;
double value;
double last_val;
AdjFlag sflags[MAX_ADJ_FLAG];
char name[32]; /* The rest used only by sliders */
int sig_digits;
double s_incr;
double p_incr;
double p_size;
} SLINC_param;
GtkAdjustment *slide_adj[4];
GtkAdjustment *text_adj[4];
SLINC_param slide_params[4];
double octpch(double pch)
{
int oct = pch;
return(oct + 8.333333 * (pch - oct));
}
double pchoct(double oct)
{
double x, result;
x = (int)oct;
result = (.12 * (oct - x) + x);
return result;
}
void cb_set_text (GtkAdjustment *adj, int adj_num)
{
int i;
char tstring[10];
char format[5];
double val;
AdjFlag flag;
#ifdef DBUG
printf("cb_set_text()\n");
#endif
val = adj->value;
/* FIXME: a little hack to retrofit new flag system */
for (i=0;i<MAX_ADJ_FLAG;i++) {
flag = slide_params[adj_num].sflags[i];
if (flag == OPC)
continue;
}
if (flag == OPC) { /* Need to do special stuff for OPC */
val = pchoct(val);
if (val < 10) {
strcpy(format,"%1.2f");
}
else {
strcpy(format,"%2.2f");
}
sprintf(tstring,format,val);
}
else {
if (val > 999) {
sprintf(tstring,"%4.0f",val);
}
else if (val > 99) {
sprintf(tstring,"%3.0f",val);
}
else if (val > 9) {
sprintf(tstring,"%2.1f",val);
}
else if (val >= 0) {
sprintf(tstring,"%1.2f",val);
}
else {
sprintf(tstring,"%0.3f",val);
}
}
/* Then do the rest */
gtk_entry_set_text(GTK_ENTRY(text_adj[adj_num]), tstring);
}
double make_incr(double min, double max)
{
double diff, tdiff, d_incr;
int i_incr;
if ((min >= 0) && (max > 0)) { /* If we're > 0 */
diff = (max-min);
if (diff < 20){ /* diff < 20 */
if (diff > 10) {
return 1.0;
}
else if (diff > 1) {
return 0.5;
}
else if (diff > 0.1) {
return 0.05;
}
else if (diff > 0.01) {
return 0.005;
}
}
else { /* diff > 20 */
d_incr = diff/20;
i_incr = (int)d_incr;
tdiff = d_incr - (double)i_incr;
return (d_incr-tdiff);
}
}
else { /* We're < 0 */
d_incr = diff/20;
if ((d_incr < 1) && (d_incr > 0.1)) {
return 0.1;
}
else if ((d_incr < 0.1) && (d_incr > 0.01)) {
return 0.01;
}
else if ((d_incr < 0.01) && (d_incr > 0.001)) {
return 0.001;
}
}
return 0.0; /* This can never happen ... here to get rid of gcc warning */
}
void scale_set_default_values (GtkScale *scale)
{
gtk_range_set_update_policy (GTK_RANGE (scale),
GTK_UPDATE_CONTINUOUS);
gtk_scale_set_digits (scale, 1);
gtk_scale_set_value_pos (scale, GTK_POS_LEFT);
gtk_scale_set_draw_value (scale, FALSE);
}
/* make_slider
-------------------------------------------------------------*/
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;
/* if (check_adj_flag(flags,OPC)) { */
/* min = (gfloat)octpch(min); */
/* max = (gfloat)octpch(max); */
/* } */
/* Don't think we want to do this */
/* if (check_adj_flag(flags,OPC)) { */
/* s_incr = (gfloat)opc2real(s_incr); */
/* p_incr = (gfloat)opc2real(p_incr); */
/* } */
/* Create an adjustment corresponding to the slider */
/*
printf("\ngtk_adjustment_new(%2.2f,%2.2f,%2.2f,%2.2f,%2.2f,%2.2f)\n",init,min,max+p_incr,s_incr,p_incr,p_incr);
*/
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");
fflush(stdout);
exit(1);
}
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_widget_show(lframe);
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 (slide_params[adj_no].sflags[0] == 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);
i=min;
j=0;
s_table = gtk_table_new( isteps, 1, FALSE);
while(i<=max) {
if (max >= 1000) {
sprintf(tstring,"%4.0f",i);
}
else if (max >= 100) {
sprintf(tstring,"%3.0f",i);
}
else if (max >= 10) {
sprintf(tstring,"%2.1f",i);
}
else if (max >= 0) {
sprintf(tstring,"%1.2f",i);
}
else {
sprintf(tstring,"%0.3f",i);
}
tlabel = gtk_label_new(tstring);
gtk_widget_show (tlabel);
gtk_table_attach_defaults (GTK_TABLE (s_table), tlabel, 0, 1, j,j+1);
j++;
i += sincr;
}
maxcell=j-1;
if (isteps < 10) { /* Attempt at scaling */
pad=1;
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);
}
}
}
else if (slide_params[adj_no].sflags[0] == OPC) {
if (max > 4) {
sincr = 0.06; /* Create a reasonable increment amount */
}
else if (max > 1.0) {
sincr = 0.01;
}
else if (max > 0.05) {
sincr = 0.005;
}
steps = (max-min)/sincr;
steps = (max-min)/sincr;
steps = rint(steps);
isteps = (int)steps;
max += (sincr/2);
i=min;
s_table = gtk_table_new( isteps, 1, FALSE);
j=0;
i=min;
while(i<=max) {
if ((i < 1) && (max < 0.07)) {
sprintf(tstring,"%1.3f",i);
}
else if (i < 10) {
sprintf(tstring,"%1.2f",i);
}
else {
sprintf(tstring,"%2.2f",i);
}
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;
j++;
t_ival = (int)i;
if (i>=((gfloat)t_ival+0.11))
i = (gfloat)t_ival+1.00;
}
maxcell=j-1;
if (isteps < 0) { /* Attempt at scaling */
pad=1;
maxpad = (int)rint(steps/2);
for(j=0;j<maxcell;j++) {
gtk_table_set_row_spacing( s_table, j, pad);
if (j<3)
pad += 1;
if (j>(steps-3))
pad -= 1;
}
}
}
/* 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_entry_new_with_max_length(6);
gtk_widget_set_events(GTK_WIDGET(text_adj[adj_no]),
GDK_EXPOSURE_MASK|
GDK_KEY_PRESS_MASK|
GDK_KEY_RELEASE_MASK);
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);
gtk_signal_connect (GTK_OBJECT(slide_adj[adj_no]), "value_changed",
GTK_SIGNAL_FUNC(cb_set_text), (gint *)adj_no);
/* 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_widget_show(vframe);
gtk_box_pack_start (GTK_BOX (box), vframe, TRUE, TRUE, 0);
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);
}
/* create_sliders
------------------------------------------------------------*/
int main (int argc, char *argv[])
{
int i,adj_no;
GtkWidget *window;
GtkWidget *main_box;
gtk_init(&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
main_box = gtk_hbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), main_box);
gtk_widget_show (main_box);
adj_no = 0;
slide_params[adj_no].sig_digits = 2;
slide_params[adj_no].init = 10;
slide_params[adj_no].min = 0;
slide_params[adj_no].max = 30;
slide_params[adj_no].s_incr = 0.01;
slide_params[adj_no].p_incr = 0.01;
slide_params[adj_no].sflags[0] = NORMAL;
make_slider(adj_no,main_box);
adj_no = 1;
slide_params[adj_no].sig_digits = 2;
slide_params[adj_no].init = 2;
slide_params[adj_no].min = 1;
slide_params[adj_no].max = 8;
slide_params[adj_no].s_incr = 0.01;
slide_params[adj_no].p_incr = 0.01;
slide_params[adj_no].sflags[1] = OPC;
make_slider(adj_no,main_box);
gtk_widget_show (window);
gtk_main();
}
----- snip -----
DT
--
Technical Director - Virginia Center for Computer Music
http://www.people.virginia.edu/~djt7p
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]