1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
|
/*
* this file is an attempt at making a "control box" routine that will
* take an array of variables and make a bunch of sliders to control
* each of the variables. It will put them in their own form widget
* and return the form widget which you can then place wherever you like.
*
* The idea here is that a lot of times you just have a bunch of
* parameters you want to control with sliders. It should be easy
* to do that, and this function is an attempt at making it easy.
* All you should have to do with this is declare an array of SliderVal
* structures describing the parameters you want to have under slider
* control (i.e. min, max, size_shown and their name) and blammo! you've
* got a nice box with a title that has a bunch of sliders that control
* your variables. You also have access to the underlying slider widgets
* in case you need to change the parameters.
*
* Dominic Giampaolo
* dbg@sgi.com
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "libsx.h"
#include "controlbox.h"
static void
change_val(Widget w, float new_val, void *arg)
{
SliderVar *var = (SliderVar *)arg;
char buff[256];
sprintf(buff, "%f", new_val);
SetStringEntry(var->text, buff);
*var->val = new_val;
}
static void
str_change_val(Widget w, char *txt, void *arg)
{
SliderVar *var = (SliderVar *)arg;
float new_val;
char buff[256];
if (txt == NULL)
return;
if (*txt != '.' && *txt != '-' && isdigit(*txt) == 0)
return;
new_val = atof(txt);
if (new_val < 0)
{
new_val = 0.0;
sprintf(buff, "%f", new_val);
SetStringEntry(var->text, buff);
}
if (new_val > var->max)
{
new_val = var->max;
sprintf(buff, "%f", new_val);
SetStringEntry(var->text, buff);
}
SetScrollbar(var->slider, new_val, var->max, var->shown);
*var->val = new_val;
}
Widget
MakeControlBox(char *title_str, SliderVar *vars)
{
int i, longest_len, longest_index, num_sliders;
Widget form, title = None, *label, *slider, *text, previous_form;
XFont font;
previous_form = GetForm();
form = MakeForm(TOP_LEVEL_FORM); /* the parent could be passed in */
if (form == NULL)
return NULL;
if (title_str)
title = MakeLabel(title_str);
longest_len = -1;
font = GetWidgetFont(form);
for(i=0; vars[i].name != NULL; i++)
{
int len;
if (font != NULL)
len = TextWidth(font, vars[i].name);
else
len = strlen(vars[i].name);
if (len > longest_len)
{
longest_len = len;
longest_index = i;
}
}
/*
* At this point "i" contains how many sliders we need to create.
* We'll use this information to allocate some arrays to hold
* the widget pointers we get back from the MakeXXX() functions.
* We need to save the values so that we can set their position later.
*/
num_sliders = i;
label = calloc(1, num_sliders*sizeof(Widget));
slider = calloc(1, num_sliders*sizeof(Widget));
text = calloc(1, num_sliders*sizeof(Widget));
if (label == NULL || slider == NULL || text == NULL)
{
if (label) free(label);
if (slider) free(slider);
if (text) free(text);
return NULL;
}
/*
* First we just create the widgets, then we'll lay them out.
*/
for(i=0; i < num_sliders; i++)
{
char buff[256];
sprintf(buff, "%f", *vars[i].val);
label[i] = MakeLabel(vars[i].name);
slider[i] = MakeHorizScrollbar(250, change_val, &vars[i]);
text[i] = MakeStringEntry(buff, 100, str_change_val, &vars[i]);
vars[i].slider = slider[i]; /* save it for the user */
vars[i].text = text[i];
if (label[i] == NULL || slider[i] == NULL || text == NULL)
{
/* XXX -- destroy the widgets? how? */
free(label);
free(slider);
free(text);
return NULL;
}
SetScrollbar(slider[i], *vars[i].val, vars[i].max, vars[i].shown);
}
/*
* Here we set the positions of all the widgets we just created.
* We set the first row of things just under the title string
* if there was one. All the sliders always get put to the right
* of the widest name (based on the width of text).
*/
if (title)
{
AttachEdge(title, TOP_EDGE, ATTACH_TOP);
AttachEdge(title, BOTTOM_EDGE, ATTACH_TOP);
AttachEdge(title, LEFT_EDGE, ATTACH_LEFT);
AttachEdge(title, RIGHT_EDGE, ATTACH_LEFT);
}
for(i=0; i < num_sliders; i++)
{
if (i == 0)
{
SetWidgetPos(label[i], PLACE_UNDER, title, NO_CARE, NULL);
SetWidgetPos(slider[i], PLACE_RIGHT, label[longest_index],
PLACE_UNDER, title);
SetWidgetPos(text[i], PLACE_RIGHT, slider[i], PLACE_UNDER, title);
}
else
{
SetWidgetPos(label[i], PLACE_UNDER, label[i-1], NO_CARE, NULL);
SetWidgetPos(slider[i], PLACE_RIGHT, label[longest_index],
PLACE_UNDER, label[i-1]);
SetWidgetPos(text[i], PLACE_RIGHT, slider[i],PLACE_UNDER,label[i-1]);
}
AttachEdge(label[i], TOP_EDGE, ATTACH_TOP);
AttachEdge(label[i], BOTTOM_EDGE, ATTACH_TOP);
AttachEdge(label[i], LEFT_EDGE, ATTACH_LEFT);
AttachEdge(label[i], RIGHT_EDGE, ATTACH_LEFT);
AttachEdge(slider[i], TOP_EDGE, ATTACH_TOP);
AttachEdge(slider[i], BOTTOM_EDGE, ATTACH_TOP);
AttachEdge(slider[i], LEFT_EDGE, ATTACH_LEFT);
AttachEdge(slider[i], RIGHT_EDGE, ATTACH_RIGHT);
AttachEdge(text[i], TOP_EDGE, ATTACH_TOP);
AttachEdge(text[i], BOTTOM_EDGE, ATTACH_TOP);
AttachEdge(text[i], LEFT_EDGE, ATTACH_RIGHT);
AttachEdge(text[i], RIGHT_EDGE, ATTACH_RIGHT);
}
SetForm(previous_form);
return form;
}
|