+++ /dev/null
-#ifndef FAUST_GTKUI_H
-#define FAUST_GTKUI_H
-
-#include "GUI.h"
-
-/******************************************************************************
-*******************************************************************************
-
- GRAPHIC USER INTERFACE
- gtk interface
-
-*******************************************************************************
-*******************************************************************************/
-#include <string>
-#include <set>
-
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include <assert.h>
-
-using namespace std;
-
-#define max(x,y) (((x)>(y)) ? (x) : (y))
-#define min(x,y) (((x)<(y)) ? (x) : (y))
-
-#define stackSize 256
-
-// Insertion modes
-
-#define kSingleMode 0
-#define kBoxMode 1
-#define kTabMode 2
-
-//------------ calculate needed precision
-static int precision(double n)
-{
- if (n < 0.009999) return 3;
- else if (n < 0.099999) return 2;
- else if (n < 0.999999) return 1;
- else return 0;
-}
-
-namespace gtk_knob
-{
-
-class GtkKnob
-{
-private:
- double start_x, start_y, max_value;
-public:
- GtkRange parent;
- int last_quadrant;
- GtkKnob();
- ~GtkKnob();
- GtkWidget *gtk_knob_new_with_adjustment(GtkAdjustment *_adjustment);
-
-};
-
-#define GTK_TYPE_KNOB (gtk_knob_get_type())
-#define GTK_KNOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_KNOB, GtkKnob))
-#define GTK_IS_KNOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_KNOB))
-#define GTK_KNOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_KNOB, GtkKnobClass))
-#define GTK_IS_KNOB_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_KNOB))
-
-GtkKnob::GtkKnob()
-// GtkKnob constructor
-{
-
-}
-
-GtkKnob::~GtkKnob()
-{
- // Nothing specific to do...
-}
-
-struct GtkKnobClass {
- GtkRangeClass parent_class;
- int knob_x;
- int knob_y;
- int knob_step;
- int button_is;
-
-};
-
-//------forward declaration
-GType gtk_knob_get_type ();
-
-/****************************************************************
- ** calculate the knop pointer with dead zone
- */
-
-const double scale_zero = 20 * (M_PI/180); // defines "dead zone" for knobs
-
-static void knob_expose(GtkWidget *widget, int knob_x, int knob_y, GdkEventExpose *event, int arc_offset)
-{
- /** check resize **/
- int grow;
- if(widget->allocation.width > widget->allocation.height) {
- grow = widget->allocation.height;
- } else {
- grow = widget->allocation.width;
- }
- knob_x = grow-4;
- knob_y = grow-4;
- /** get values for the knob **/
- GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget));
- int knobx = (widget->allocation.x+2 + (widget->allocation.width-4 - knob_x) * 0.5);
- int knoby = (widget->allocation.y+2 + (widget->allocation.height-4 - knob_y) * 0.5);
- int knobx1 = (widget->allocation.x+2 + (widget->allocation.width-4)* 0.5);
- int knoby1 = (widget->allocation.y+2 + (widget->allocation.height-4) * 0.5);
- double knobstate = (adj->value - adj->lower) / (adj->upper - adj->lower);
- double angle = scale_zero + knobstate * 2 * (M_PI - scale_zero);
- double knobstate1 = (0. - adj->lower) / (adj->upper - adj->lower);
- double pointer_off = knob_x/6;
- double radius = min(knob_x-pointer_off, knob_y-pointer_off) / 2;
- double lengh_x = (knobx+radius+pointer_off/2) - radius * sin(angle);
- double lengh_y = (knoby+radius+pointer_off/2) + radius * cos(angle);
- double radius1 = min(knob_x, knob_y) / 2 ;
-
- /** get widget forground color convert to cairo **/
- GtkStyle *style = gtk_widget_get_style (widget);
- double r = min(0.6,style->fg[gtk_widget_get_state(widget)].red/65535.0),
- g = min(0.6,style->fg[gtk_widget_get_state(widget)].green/65535.0),
- b = min(0.6,style->fg[gtk_widget_get_state(widget)].blue/65535.0);
-
- /** paint focus **/
- if (GTK_WIDGET_HAS_FOCUS(widget)== TRUE) {
- gtk_paint_focus(widget->style, widget->window, GTK_STATE_NORMAL, NULL, widget, NULL,
- knobx-2, knoby-2, knob_x+4, knob_y+4);
- }
- /** create clowing knobs with cairo **/
- cairo_t *cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
- GdkRegion *region;
- region = gdk_region_rectangle (&widget->allocation);
- gdk_region_intersect (region, event->region);
- gdk_cairo_region (cr, region);
- cairo_clip (cr);
-
- cairo_arc(cr,knobx1+arc_offset, knoby1+arc_offset, knob_x/2.1, 0, 2 * M_PI );
- cairo_pattern_t*pat =
- cairo_pattern_create_radial (knobx1+arc_offset-knob_x/6,knoby1+arc_offset-knob_x/6, 1,knobx1+arc_offset,knoby1+arc_offset,knob_x/2.1 );
- if(adj->lower<0 && adj->value>0.) {
- cairo_pattern_add_color_stop_rgb (pat, 0, r+0.4, g+0.4 + knobstate-knobstate1, b+0.4);
- cairo_pattern_add_color_stop_rgb (pat, 0.7, r+0.15, g+0.15 + (knobstate-knobstate1)*0.5, b+0.15);
- cairo_pattern_add_color_stop_rgb (pat, 1, r, g, b);
- } else if(adj->lower<0 && adj->value<=0.) {
- cairo_pattern_add_color_stop_rgb (pat, 0, r+0.4 +knobstate1- knobstate, g+0.4, b+0.4);
- cairo_pattern_add_color_stop_rgb (pat, 0.7, r+0.15 +(knobstate1- knobstate)*0.5, g+0.15, b+0.15);
- cairo_pattern_add_color_stop_rgb (pat, 1, r, g, b);
- } else {
- cairo_pattern_add_color_stop_rgb (pat, 0, r+0.4, g+0.4 +knobstate, b+0.4);
- cairo_pattern_add_color_stop_rgb (pat, 0.7, r+0.15, g+0.15 + knobstate*0.5, b+0.15);
- cairo_pattern_add_color_stop_rgb (pat, 1, r, g, b);
- }
- cairo_set_source (cr, pat);
- cairo_fill_preserve (cr);
- gdk_cairo_set_source_color(cr, gtk_widget_get_style (widget)->fg);
- cairo_set_line_width(cr, 2.0);
- cairo_stroke(cr);
-
- /** create a rotating pointer on the kob**/
- cairo_set_source_rgb(cr, 0.1, 0.1, 0.1);
- cairo_set_line_width(cr,max(3, min(7, knob_x/15)));
- cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
- cairo_set_line_join(cr, CAIRO_LINE_JOIN_BEVEL);
- cairo_move_to(cr, knobx+radius1, knoby+radius1);
- cairo_line_to(cr,lengh_x,lengh_y);
- cairo_stroke(cr);
- cairo_set_source_rgb(cr, 0.9, 0.9, 0.9);
- cairo_set_line_width(cr,min(5, max(1,knob_x/30)));
- cairo_move_to(cr, knobx+radius1, knoby+radius1);
- cairo_line_to(cr,lengh_x,lengh_y);
- cairo_stroke(cr);
- cairo_pattern_destroy (pat);
- gdk_region_destroy (region);
- cairo_destroy(cr);
-}
-
-/****************************************************************
- ** general expose events for all "knob" controllers
- */
-
-//----------- draw the Knob when moved
-static gboolean gtk_knob_expose (GtkWidget *widget, GdkEventExpose *event)
-{
- g_assert(GTK_IS_KNOB(widget));
- GtkKnobClass *klass = GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget));
- knob_expose(widget, klass->knob_x, klass->knob_y, event, 0);
- return TRUE;
-}
-
-/****************************************************************
- ** set initial size for GdkDrawable per type
- */
-
-static void gtk_knob_size_request (GtkWidget *widget, GtkRequisition *requisition)
-{
- g_assert(GTK_IS_KNOB(widget));
- GtkKnobClass *klass = GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget));
- requisition->width = klass->knob_x;
- requisition->height = klass->knob_y;
-}
-
-/****************************************************************
- ** set value from key bindings
- */
-
-static void gtk_knob_set_value (GtkWidget *widget, int dir_down)
-{
- g_assert(GTK_IS_KNOB(widget));
-
- GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget));
-
- int oldstep = (int)(0.5f + (adj->value - adj->lower) / adj->step_increment);
- int step;
- int nsteps = (int)(0.5f + (adj->upper - adj->lower) / adj->step_increment);
- if (dir_down)
- step = oldstep - 1;
- else
- step = oldstep + 1;
- float value = adj->lower + step * double(adj->upper - adj->lower) / nsteps;
- gtk_widget_grab_focus(widget);
- gtk_range_set_value(GTK_RANGE(widget), value);
-}
-
-/****************************************************************
- ** keyboard bindings
- */
-
-static gboolean gtk_knob_key_press (GtkWidget *widget, GdkEventKey *event)
-{
- g_assert(GTK_IS_KNOB(widget));
-
- GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget));
- switch (event->keyval) {
- case GDK_Home:
- gtk_range_set_value(GTK_RANGE(widget), adj->lower);
- return TRUE;
- case GDK_End:
- gtk_range_set_value(GTK_RANGE(widget), adj->upper);
- return TRUE;
- case GDK_Up:
- gtk_knob_set_value(widget, 0);
- return TRUE;
- case GDK_Right:
- gtk_knob_set_value(widget, 0);
- return TRUE;
- case GDK_Down:
- gtk_knob_set_value(widget, 1);
- return TRUE;
- case GDK_Left:
- gtk_knob_set_value(widget, 1);
- return TRUE;
- }
-
- return FALSE;
-}
-
-/****************************************************************
- ** alternative (radial) knob motion mode (ctrl + mouse pressed)
- */
-
-static void knob_pointer_event(GtkWidget *widget, gdouble x, gdouble y, int knob_x, int knob_y,
- bool drag, int state)
-{
- static double last_y = 2e20;
- GtkKnob *knob = GTK_KNOB(widget);
- GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget));
- double radius = min(knob_x, knob_y) / 2;
- int knobx = (widget->allocation.width - knob_x) / 2;
- int knoby = (widget->allocation.height - knob_y) / 2;
- double posx = (knobx + radius) - x; // x axis right -> left
- double posy = (knoby + radius) - y; // y axis top -> bottom
- double value;
- if (!drag) {
- if (state & GDK_CONTROL_MASK) {
- last_y = 2e20;
- return;
- } else {
- last_y = posy;
- }
- }
- if (last_y < 1e20) { // in drag started with Control Key
- const double scaling = 0.005;
- double scal = (state & GDK_SHIFT_MASK ? scaling*0.1 : scaling);
- value = (last_y - posy) * scal;
- last_y = posy;
- gtk_range_set_value(GTK_RANGE(widget), adj->value - value * (adj->upper - adj->lower));
- return;
- }
-
- double angle = atan2(-posx, posy) + M_PI; // clockwise, zero at 6 o'clock, 0 .. 2*M_PI
- if (drag) {
- // block "forbidden zone" and direct moves between quadrant 1 and 4
- int quadrant = 1 + int(angle/M_PI_2);
- if (knob->last_quadrant == 1 && (quadrant == 3 || quadrant == 4)) {
- angle = scale_zero;
- } else if (knob->last_quadrant == 4 && (quadrant == 1 || quadrant == 2)) {
- angle = 2*M_PI - scale_zero;
- } else {
- if (angle < scale_zero) {
- angle = scale_zero;
- } else if (angle > 2*M_PI - scale_zero) {
- angle = 2*M_PI - scale_zero;
- }
- knob->last_quadrant = quadrant;
- }
- } else {
- if (angle < scale_zero) {
- angle = scale_zero;
- } else if (angle > 2*M_PI - scale_zero) {
- angle = 2*M_PI - scale_zero;
- }
- knob->last_quadrant = 0;
- }
- angle = (angle - scale_zero) / (2 * (M_PI-scale_zero)); // normalize to 0..1
- gtk_range_set_value(GTK_RANGE(widget), adj->lower + angle * (adj->upper - adj->lower));
-}
-
-/****************************************************************
- ** mouse button pressed set value
- */
-
-static gboolean gtk_knob_button_press (GtkWidget *widget, GdkEventButton *event)
-{
- g_assert(GTK_IS_KNOB(widget));
-
- GtkKnobClass *klass = GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget));
-
-
- switch (event->button) {
- case 1: // left button
- gtk_widget_grab_focus(widget);
- gtk_widget_grab_default (widget);
- gtk_grab_add(widget);
- klass->button_is = 1;
- knob_pointer_event(widget, event->x, event->y, klass->knob_x, klass->knob_y,
- false, event->state);
- break;
- case 2: //wheel
- klass->button_is = 2;
- break;
- case 3: // right button
- klass->button_is = 3;
- break;
- default: // do nothing
- break;
- }
- return TRUE;
-}
-
-/****************************************************************
- ** mouse button release
- */
-
-static gboolean gtk_knob_button_release (GtkWidget *widget, GdkEventButton *event)
-{
- g_assert(GTK_IS_KNOB(widget));
- GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget))->button_is = 0;
- if (GTK_WIDGET_HAS_GRAB(widget))
- gtk_grab_remove(widget);
- return FALSE;
-}
-
-/****************************************************************
- ** set the value from mouse movement
- */
-
-static gboolean gtk_knob_pointer_motion (GtkWidget *widget, GdkEventMotion *event)
-{
- g_assert(GTK_IS_KNOB(widget));
- GtkKnobClass *klass = GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget));
-
- gdk_event_request_motions (event);
-
- if (GTK_WIDGET_HAS_GRAB(widget)) {
- knob_pointer_event(widget, event->x, event->y, klass->knob_x, klass->knob_y,
- true, event->state);
- }
- return FALSE;
-}
-
-/****************************************************************
- ** set value from mouseweel
- */
-
-static gboolean gtk_knob_scroll (GtkWidget *widget, GdkEventScroll *event)
-{
- usleep(5000);
- gtk_knob_set_value(widget, event->direction);
- return FALSE;
-}
-
-/****************************************************************
- ** init the GtkKnobClass
- */
-
-static void gtk_knob_class_init (GtkKnobClass *klass)
-{
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
-
- /** set here the sizes and steps for the used knob **/
-//--------- small knob size and steps
-
- klass->knob_x = 30;
- klass->knob_y = 30;
- klass->knob_step = 86;
-
-//--------- event button
- klass->button_is = 0;
-
-//--------- connect the events with funktions
- widget_class->expose_event = gtk_knob_expose;
- widget_class->size_request = gtk_knob_size_request;
- widget_class->button_press_event = gtk_knob_button_press;
- widget_class->button_release_event = gtk_knob_button_release;
- widget_class->motion_notify_event = gtk_knob_pointer_motion;
- widget_class->key_press_event = gtk_knob_key_press;
- widget_class->scroll_event = gtk_knob_scroll;
-}
-
-/****************************************************************
- ** init the Knob type/size
- */
-
-static void gtk_knob_init (GtkKnob *knob)
-{
- GtkWidget *widget = GTK_WIDGET(knob);
- GtkKnobClass *klass = GTK_KNOB_CLASS(GTK_OBJECT_GET_CLASS(widget));
-
- GTK_WIDGET_SET_FLAGS (GTK_WIDGET(knob), GTK_CAN_FOCUS);
- GTK_WIDGET_SET_FLAGS (GTK_WIDGET(knob), GTK_CAN_DEFAULT);
-
- widget->requisition.width = klass->knob_x;
- widget->requisition.height = klass->knob_y;
-
-}
-
-/****************************************************************
- ** redraw when value changed
- */
-
-static gboolean gtk_knob_value_changed(gpointer obj)
-{
- GtkWidget *widget = (GtkWidget *)obj;
- gtk_widget_queue_draw(widget);
- return FALSE;
-}
-
-/****************************************************************
- ** create small knob
- */
-
-GtkWidget *GtkKnob::gtk_knob_new_with_adjustment(GtkAdjustment *_adjustment)
-{
- GtkWidget *widget = GTK_WIDGET( g_object_new (GTK_TYPE_KNOB, NULL ));
- GtkKnob *knob = GTK_KNOB(widget);
- knob->last_quadrant = 0;
- if (widget) {
- gtk_range_set_adjustment(GTK_RANGE(widget), _adjustment);
- g_signal_connect(GTK_OBJECT(widget), "value-changed",
- G_CALLBACK(gtk_knob_value_changed), widget);
- }
- return widget;
-}
-
-/****************************************************************
- ** get the Knob type
- */
-
-GType gtk_knob_get_type (void)
-{
- static GType kn_type = 0;
- if (!kn_type) {
- static const GTypeInfo kn_info = {
- sizeof(GtkKnobClass), NULL, NULL, (GClassInitFunc)gtk_knob_class_init, NULL, NULL, sizeof (GtkKnob), 0, (GInstanceInitFunc)gtk_knob_init
- };
- kn_type = g_type_register_static(GTK_TYPE_RANGE, "GtkKnob", &kn_info, (GTypeFlags)0);
- }
- return kn_type;
-}
-}/* end of gtk_knob namespace */
-
-gtk_knob::GtkKnob myGtkKnob;
-
-/**
- * rmWhiteSpaces(): Remove the leading and trailing white spaces of a string
- * (but not those in the middle of the string)
- */
-static string rmWhiteSpaces(const string& s)
-{
- size_t i = s.find_first_not_of(" \t");
- size_t j = s.find_last_not_of(" \t");
-
- if (i != string::npos & j != string::npos) {
- return s.substr(i, 1+j-i);
- } else {
- return "";
- }
-}
-
-
-/**
- * Extracts metdata from a label : 'vol [unit: dB]' -> 'vol' + metadata
- */
-static void extractMetadata(const string& fulllabel, string& label, map<string, string>& metadata)
-{
- enum {kLabel, kEscape1, kEscape2, kEscape3, kKey, kValue};
- int state = kLabel; int deep = 0;
- string key, value;
-
- for (unsigned int i=0; i < fulllabel.size(); i++) {
- char c = fulllabel[i];
- switch (state) {
- case kLabel :
- assert (deep == 0);
- switch (c) {
- case '\\' : state = kEscape1; break;
- case '[' : state = kKey; deep++; break;
- default : label += c;
- }
- break;
-
- case kEscape1 :
- label += c;
- state = kLabel;
- break;
-
- case kEscape2 :
- key += c;
- state = kKey;
- break;
-
- case kEscape3 :
- value += c;
- state = kValue;
- break;
-
- case kKey :
- assert (deep > 0);
- switch (c) {
- case '\\' : state = kEscape2;
- break;
-
- case '[' : deep++;
- key += c;
- break;
-
- case ':' : if (deep == 1) {
- state = kValue;
- } else {
- key += c;
- }
- break;
- case ']' : deep--;
- if (deep < 1) {
- metadata[rmWhiteSpaces(key)] = "";
- state = kLabel;
- key="";
- value="";
- } else {
- key += c;
- }
- break;
- default : key += c;
- }
- break;
-
- case kValue :
- assert (deep > 0);
- switch (c) {
- case '\\' : state = kEscape3;
- break;
-
- case '[' : deep++;
- value += c;
- break;
-
- case ']' : deep--;
- if (deep < 1) {
- metadata[rmWhiteSpaces(key)]=rmWhiteSpaces(value);
- state = kLabel;
- key="";
- value="";
- } else {
- value += c;
- }
- break;
- default : value += c;
- }
- break;
-
- default :
- cerr << "ERROR unrecognized state " << state << endl;
- }
- }
- label = rmWhiteSpaces(label);
-}
-
-
-class GTKUI : public GUI
-{
- private :
- static bool fInitialized;
- static map<float*, float> fGuiSize; // map widget zone with widget size coef
- static map<float*, string> fTooltip; // map widget zone with tooltip strings
- static set<float*> fKnobSet; // set of widget zone to be knobs
- string gGroupTooltip;
-
- bool isKnob(float* zone){return fKnobSet.count(zone) > 0;}
-
- protected :
- GtkWidget* fWindow;
- int fTop;
- GtkWidget* fBox[stackSize];
- int fMode[stackSize];
- bool fStopped;
-
- GtkWidget* addWidget(const char* label, GtkWidget* w);
- virtual void pushBox(int mode, GtkWidget* w);
-
-
- public :
- static const gboolean expand = TRUE;
- static const gboolean fill = TRUE;
- static const gboolean homogene = FALSE;
-
- GTKUI(char * name, int* pargc, char*** pargv);
-
- // -- Labels and metadata
-
- virtual void declare (float* zone, const char* key, const char* value);
- virtual int checkLabelOptions (GtkWidget* widget, const string& fullLabel, string& simplifiedLabel);
- virtual void checkForTooltip (float* zone, GtkWidget* widget);
-
- // -- layout groups
-
- virtual void openFrameBox(const char* label);
- virtual void openTabBox(const char* label = "");
- virtual void openHorizontalBox(const char* label = "");
- virtual void openVerticalBox(const char* label = "");
-
- // -- extra widget's layouts
-
- virtual void openDialogBox(const char* label, float* zone);
- virtual void openEventBox(const char* label = "");
- virtual void openHandleBox(const char* label = "");
- virtual void openExpanderBox(const char* label, float* zone);
-
- virtual void closeBox();
- virtual void adjustStack(int n);
-
- // -- active widgets
-
- virtual void addButton(const char* label, float* zone);
- virtual void addToggleButton(const char* label, float* zone);
- virtual void addCheckButton(const char* label, float* zone);
- virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step);
- virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step);
- virtual void addKnob(const char* label, float* zone, float init, float min, float max, float step);
- virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step);
-
- // -- passive display widgets
-
- virtual void addNumDisplay(const char* label, float* zone, int precision);
- virtual void addTextDisplay(const char* label, float* zone, const char* names[], float min, float max);
- virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max);
- virtual void addVerticalBargraph(const char* label, float* zone, float min, float max);
-
- virtual void show();
- virtual void run();
-
-};
-
-
-
-/******************************************************************************
-*******************************************************************************
-
- GRAPHIC USER INTERFACE (v2)
- gtk implementation
-
-*******************************************************************************
-*******************************************************************************/
-
-// global static fields
-
-bool GTKUI::fInitialized = false;
-map<float*, float> GTKUI::fGuiSize;
-map<float*, string> GTKUI::fTooltip;
-set<float*> GTKUI::fKnobSet; // set of widget zone to be knobs
-
-/**
-* Format tooltip string by replacing some white spaces by
-* return characters so that line width doesn't exceed n.
-* Limitation : long words exceeding n are not cut
-*/
-static string formatTooltip(int n, const string& tt)
-{
- string ss = tt; // ss string we are going to format
- int lws = 0; // last white space encountered
- int lri = 0; // last return inserted
- for (int i=0; i<tt.size(); i++) {
- if (tt[i] == ' ') lws = i;
- if (((i-lri) >= n) && (lws > lri)) {
- // insert return here
- ss[lws] = '\n';
- lri = lws;
- }
- }
- cout << ss;
- return ss;
-}
-
-
-
-static gint delete_event( GtkWidget *widget, GdkEvent *event, gpointer data )
-{
- return FALSE;
-}
-
-static void destroy_event( GtkWidget *widget, gpointer data )
-{
- gtk_main_quit ();
-}
-
-
-GTKUI::GTKUI(char * name, int* pargc, char*** pargv)
-{
- if (!fInitialized) {
- gtk_init(pargc, pargv);
- fInitialized = true;
- }
-
- fWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- //gtk_container_set_border_width (GTK_CONTAINER (fWindow), 10);
- gtk_window_set_title (GTK_WINDOW (fWindow), name);
- gtk_signal_connect (GTK_OBJECT (fWindow), "delete_event", GTK_SIGNAL_FUNC (delete_event), NULL);
- gtk_signal_connect (GTK_OBJECT (fWindow), "destroy", GTK_SIGNAL_FUNC (destroy_event), NULL);
-
- fTop = 0;
- fBox[fTop] = gtk_vbox_new (homogene, 4);
- fMode[fTop] = kBoxMode;
- gtk_container_add (GTK_CONTAINER (fWindow), fBox[fTop]);
- fStopped = false;
-}
-
-// empilement des boites
-
-void GTKUI::pushBox(int mode, GtkWidget* w)
-{
- ++fTop;
- assert(fTop < stackSize);
- fMode[fTop] = mode;
- fBox[fTop] = w;
-}
-
-
-/**
- * Remove n levels from the stack S before the top level
- * adjustStack(n): S -> S' with S' = S(0),S(n+1),S(n+2),...
- */
-void GTKUI::adjustStack(int n)
-{
- if (n > 0) {
- assert(fTop >= n);
-
- fTop -= n;
- fMode[fTop] = fMode[fTop+n];
- fBox[fTop] = fBox[fTop+n];
- }
-}
-
-void GTKUI::closeBox()
-{
- --fTop;
- assert(fTop >= 0);
-}
-
-
-/**
- * Analyses the widget zone metadata declarations and takes
- * appropriate actions
- */
-void GTKUI::declare(float* zone, const char* key, const char* value)
-{
- if (zone == 0) {
- // special zone 0 means group metadata
- if (strcmp(key,"tooltip")==0) {
- // only group tooltip are currently implemented
- gGroupTooltip = formatTooltip(30, value);
- }
- } else {
- if (strcmp(key,"size")==0) {
- fGuiSize[zone]=atof(value);
- }
- else if (strcmp(key,"tooltip")==0) {
- fTooltip[zone] = formatTooltip(30,value) ;
- }
- else if (strcmp(key,"style")==0) {
- if (strcmp(value,"knob") == 0) {
- fKnobSet.insert(zone);
- }
- }
- }
-}
-
-
-
-/**
- * Analyses a full label and activates the relevant options. returns a simplified
- * label (without options) and an amount of stack adjustement (in case additional
- * containers were pushed on the stack).
- */
-
-int GTKUI::checkLabelOptions(GtkWidget* widget, const string& fullLabel, string& simplifiedLabel)
-{
- map<string, string> metadata;
- extractMetadata(fullLabel, simplifiedLabel, metadata);
-
- if (metadata.count("tooltip")) {
- gtk_tooltips_set_tip (gtk_tooltips_new (), widget, metadata["tooltip"].c_str(), NULL);
- }
- if (metadata["option"] == "detachable") {
- openHandleBox(simplifiedLabel.c_str());
- return 1;
- }
-
- //---------------------
- if (gGroupTooltip != string()) {
- gtk_tooltips_set_tip (gtk_tooltips_new (), widget, gGroupTooltip.c_str(), NULL);
- gGroupTooltip = string();
- }
-
- //----------------------
-
- // no adjustement of the stack needed
- return 0;
-}
-
-/**
- * Check if a tooltip is associated to a zone and add it to the corresponding widget
- */
-void GTKUI::checkForTooltip(float* zone, GtkWidget* widget)
-{
- if (fTooltip.count(zone)) {
- gtk_tooltips_set_tip (gtk_tooltips_new (), widget, fTooltip[zone].c_str(), NULL);
- }
-}
-
-
-// les differentes boites
-
-void GTKUI::openFrameBox(const char* label)
-{
- GtkWidget * box = gtk_frame_new (label);
- //gtk_container_set_border_width (GTK_CONTAINER (box), 10);
-
- pushBox(kSingleMode, addWidget(label, box));
-}
-
-
-void GTKUI::openTabBox(const char* fullLabel)
-{
- string label;
- GtkWidget* widget = gtk_notebook_new();
-
- int adjust = checkLabelOptions(widget, fullLabel, label);
-
- pushBox(kTabMode, addWidget(label.c_str(), widget));
-
- // adjust stack because otherwise Handlebox will remain open
- adjustStack(adjust);
-}
-
-
-void GTKUI::openHorizontalBox(const char* fullLabel)
-{
- string label;
- GtkWidget* box = gtk_hbox_new (homogene, 4);
- int adjust = checkLabelOptions(box, fullLabel, label);
-
- gtk_container_set_border_width (GTK_CONTAINER (box), 10);
-
- if (fMode[fTop] != kTabMode && label[0] != 0) {
- GtkWidget * frame = addWidget(label.c_str(), gtk_frame_new (label.c_str()));
- gtk_container_add (GTK_CONTAINER(frame), box);
- gtk_widget_show(box);
- pushBox(kBoxMode, box);
- } else {
- pushBox(kBoxMode, addWidget(label.c_str(), box));
- }
-
- // adjust stack because otherwise Handlebox will remain open
- adjustStack(adjust);
-}
-
-
-void GTKUI::openVerticalBox(const char* fullLabel)
-{
- string label;
- GtkWidget * box = gtk_vbox_new (homogene, 4);
- int adjust = checkLabelOptions(box, fullLabel, label);
-
- gtk_container_set_border_width (GTK_CONTAINER (box), 10);
-
- if (fMode[fTop] != kTabMode && label[0] != 0) {
- GtkWidget * frame = addWidget(label.c_str(), gtk_frame_new (label.c_str()));
- gtk_container_add (GTK_CONTAINER(frame), box);
- gtk_widget_show(box);
- pushBox(kBoxMode, box);
- } else {
- pushBox(kBoxMode, addWidget(label.c_str(), box));
- }
-
- // adjust stack because otherwise Handlebox will remain open
- adjustStack(adjust);
-}
-
-
-void GTKUI::openHandleBox(const char* label)
-{
- GtkWidget * box = gtk_hbox_new (homogene, 4);
- gtk_container_set_border_width (GTK_CONTAINER (box), 2);
- if (fMode[fTop] != kTabMode && label[0] != 0)
- {
- GtkWidget * frame = addWidget(label, gtk_handle_box_new ());
- gtk_container_add (GTK_CONTAINER(frame), box);
- gtk_widget_show(box);
- pushBox(kBoxMode, box);
- }
- else
- {
- pushBox(kBoxMode, addWidget(label, box));
- }
-}
-
-
-void GTKUI::openEventBox(const char* label)
-{
- GtkWidget * box = gtk_hbox_new (homogene, 4);
- gtk_container_set_border_width (GTK_CONTAINER (box), 2);
- if (fMode[fTop] != kTabMode && label[0] != 0)
- {
- GtkWidget * frame = addWidget(label, gtk_event_box_new ());
- gtk_container_add (GTK_CONTAINER(frame), box);
- gtk_widget_show(box);
- pushBox(kBoxMode, box);
- }
- else
- {
- pushBox(kBoxMode, addWidget(label, box));
- }
-}
-
-
-struct uiExpanderBox : public uiItem
-{
- GtkExpander* fButton;
- uiExpanderBox(GUI* ui, float* zone, GtkExpander* b) : uiItem(ui, zone), fButton(b) {}
- static void expanded (GtkWidget *widget, gpointer data)
- {
- float v = gtk_expander_get_expanded (GTK_EXPANDER(widget));
- if (v == 1.000000)
- {
- v = 0;
- }
- else v = 1;
- ((uiItem*)data)->modifyZone(v);
- }
-
- virtual void reflectZone()
- {
- float v = *fZone;
- fCache = v;
- gtk_expander_set_expanded(GTK_EXPANDER(fButton), v);
- }
-};
-
-void GTKUI::openExpanderBox(const char* label, float* zone)
-{
- *zone = 0.0;
- GtkWidget * box = gtk_hbox_new (homogene, 4);
- gtk_container_set_border_width (GTK_CONTAINER (box), 2);
- if (fMode[fTop] != kTabMode && label[0] != 0)
- {
- GtkWidget * frame = addWidget(label, gtk_expander_new (label));
- gtk_container_add (GTK_CONTAINER(frame), box);
- uiExpanderBox* c = new uiExpanderBox(this, zone, GTK_EXPANDER(frame));
- gtk_signal_connect (GTK_OBJECT (frame), "activate", GTK_SIGNAL_FUNC (uiExpanderBox::expanded), (gpointer)c);
- gtk_widget_show(box);
- pushBox(kBoxMode, box);
- }
- else
- {
- pushBox(kBoxMode, addWidget(label, box));
- }
-}
-
-
-
-GtkWidget* GTKUI::addWidget(const char* label, GtkWidget* w)
-{
- switch (fMode[fTop]) {
- case kSingleMode : gtk_container_add (GTK_CONTAINER(fBox[fTop]), w); break;
- case kBoxMode : gtk_box_pack_start (GTK_BOX(fBox[fTop]), w, expand, fill, 0); break;
- case kTabMode : gtk_notebook_append_page (GTK_NOTEBOOK(fBox[fTop]), w, gtk_label_new(label)); break;
- }
- gtk_widget_show (w);
- return w;
-}
-
-// --------------------------- Press button ---------------------------
-
-struct uiButton : public uiItem
-{
- GtkButton* fButton;
-
- uiButton (GUI* ui, float* zone, GtkButton* b) : uiItem(ui, zone), fButton(b) {}
-
- static void pressed( GtkWidget *widget, gpointer data )
- {
- uiItem* c = (uiItem*) data;
- c->modifyZone(1.0);
- }
-
- static void released( GtkWidget *widget, gpointer data )
- {
- uiItem* c = (uiItem*) data;
- c->modifyZone(0.0);
- }
-
- virtual void reflectZone()
- {
- float v = *fZone;
- fCache = v;
- if (v > 0.0) gtk_button_pressed(fButton); else gtk_button_released(fButton);
- }
-};
-
-void GTKUI::addButton(const char* label, float* zone)
-{
- *zone = 0.0;
- GtkWidget* button = gtk_button_new_with_label (label);
- addWidget(label, button);
-
- uiButton* c = new uiButton(this, zone, GTK_BUTTON(button));
-
- gtk_signal_connect (GTK_OBJECT (button), "pressed", GTK_SIGNAL_FUNC (uiButton::pressed), (gpointer) c);
- gtk_signal_connect (GTK_OBJECT (button), "released", GTK_SIGNAL_FUNC (uiButton::released), (gpointer) c);
-
- checkForTooltip(zone, button);
-}
-
-// --------------------------- Toggle Buttons ---------------------------
-
-struct uiToggleButton : public uiItem
-{
- GtkToggleButton* fButton;
-
- uiToggleButton(GUI* ui, float* zone, GtkToggleButton* b) : uiItem(ui, zone), fButton(b) {}
-
- static void toggled (GtkWidget *widget, gpointer data)
- {
- float v = (GTK_TOGGLE_BUTTON (widget)->active) ? 1.0 : 0.0;
- ((uiItem*)data)->modifyZone(v);
- }
-
- virtual void reflectZone()
- {
- float v = *fZone;
- fCache = v;
- gtk_toggle_button_set_active(fButton, v > 0.0);
- }
-};
-
-void GTKUI::addToggleButton(const char* label, float* zone)
-{
- *zone = 0.0;
- GtkWidget* button = gtk_toggle_button_new_with_label (label);
- addWidget(label, button);
-
- uiToggleButton* c = new uiToggleButton(this, zone, GTK_TOGGLE_BUTTON(button));
- gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC (uiToggleButton::toggled), (gpointer) c);
-
- checkForTooltip(zone, button);
-}
-
-
-
-void show_dialog(GtkWidget *widget, gpointer data)
-{
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)) == TRUE)
- {
- gtk_widget_show(GTK_WIDGET(data));
- gint root_x, root_y;
- gtk_window_get_position (GTK_WINDOW(data), &root_x, &root_y);
- root_y -= 120;
- gtk_window_move(GTK_WINDOW(data), root_x, root_y);
- }
- else gtk_widget_hide(GTK_WIDGET(data));
-}
-
-static gboolean deleteevent( GtkWidget *widget, gpointer data )
-{
-return TRUE;
-}
-
-void GTKUI::openDialogBox(const char* label, float* zone)
-{
- // create toplevel window and set properties
- GtkWidget * dialog = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- gtk_window_set_decorated(GTK_WINDOW(dialog), TRUE);
- gtk_window_set_deletable(GTK_WINDOW(dialog), FALSE);
- gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
- gtk_window_set_gravity(GTK_WINDOW(dialog), GDK_GRAVITY_SOUTH);
- gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(fWindow));
- gtk_window_set_position (GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
- gtk_window_set_keep_below (GTK_WINDOW(dialog), FALSE);
- gtk_window_set_title (GTK_WINDOW (dialog), label);
- g_signal_connect (G_OBJECT (dialog), "delete_event", G_CALLBACK (deleteevent), NULL);
- gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);
-
- GtkWidget * box = gtk_hbox_new (homogene, 4);
-
- *zone = 0.0;
- GtkWidget* button = gtk_toggle_button_new ();
- gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC (show_dialog), (gpointer) dialog);
-
- gtk_container_add (GTK_CONTAINER(fBox[fTop]), button);
- gtk_container_add (GTK_CONTAINER(dialog), box);
- gtk_widget_show (button);
- gtk_widget_show(box);
- pushBox(kBoxMode, box);
-}
-
-
-
-
-// --------------------------- Check Button ---------------------------
-
-struct uiCheckButton : public uiItem
-{
- GtkToggleButton* fButton;
-
- uiCheckButton(GUI* ui, float* zone, GtkToggleButton* b) : uiItem(ui, zone), fButton(b) {}
-
- static void toggled (GtkWidget *widget, gpointer data)
- {
- float v = (GTK_TOGGLE_BUTTON (widget)->active) ? 1.0 : 0.0;
- ((uiItem*)data)->modifyZone(v);
- }
-
- virtual void reflectZone()
- {
- float v = *fZone;
- fCache = v;
- gtk_toggle_button_set_active(fButton, v > 0.0);
- }
-};
-
-void GTKUI::addCheckButton(const char* label, float* zone)
-{
- *zone = 0.0;
- GtkWidget* button = gtk_check_button_new_with_label (label);
- addWidget(label, button);
-
- uiCheckButton* c = new uiCheckButton(this, zone, GTK_TOGGLE_BUTTON(button));
- gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC(uiCheckButton::toggled), (gpointer) c);
-
- checkForTooltip(zone, button);
-}
-
-
-// --------------------------- Adjustmenty based widgets ---------------------------
-
-struct uiAdjustment : public uiItem
-{
- GtkAdjustment* fAdj;
-
- uiAdjustment(GUI* ui, float* zone, GtkAdjustment* adj) : uiItem(ui, zone), fAdj(adj) {}
-
- static void changed (GtkWidget *widget, gpointer data)
- {
- float v = GTK_ADJUSTMENT (widget)->value;
- ((uiItem*)data)->modifyZone(v);
- }
-
- virtual void reflectZone()
- {
- float v = *fZone;
- fCache = v;
- gtk_adjustment_set_value(fAdj, v);
- }
-};
-
-// --------------------------- format knob value display ---------------------------
-
-struct uiValueDisplay : public uiItem
-{
- GtkLabel* fLabel;
- int fPrecision ;
-
- uiValueDisplay(GUI* ui, float* zone, GtkLabel* label, int precision)
- : uiItem(ui, zone), fLabel(label), fPrecision(precision) {}
-
- virtual void reflectZone()
- {
- float v = *fZone;
- fCache = v;
- char s[64];
- if (fPrecision <= 0)
- snprintf(s, 63, "%d", int(v));
-
- else if (fPrecision > 3)
- snprintf(s, 63, "%f", v);
-
- else if (fPrecision == 1)
- {
- const char* format[] = {"%.1f", "%.2f", "%.3f"};
- snprintf(s, 63, format[1-1], v);
- }
- else if (fPrecision == 2)
- {
- const char* format[] = {"%.1f", "%.2f", "%.3f"};
- snprintf(s, 63, format[2-1], v);
- }
- else
- {
- const char* format[] = {"%.1f", "%.2f", "%.3f"};
- snprintf(s, 63, format[3-1], v);
- }
- gtk_label_set_text(fLabel, s);
- }
-};
-
-// ------------------------------- Knob -----------------------------------------
-
-void GTKUI::addKnob(const char* label, float* zone, float init, float min, float max, float step)
-{
- *zone = init;
- GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0);
-
- uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
-
- gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
-
- GtkWidget* slider = gtk_vbox_new (FALSE, 0);
- GtkWidget* fil = gtk_vbox_new (FALSE, 0);
- GtkWidget* rei = gtk_vbox_new (FALSE, 0);
- GtkWidget* re =myGtkKnob.gtk_knob_new_with_adjustment(GTK_ADJUSTMENT(adj));
- GtkWidget* lw = gtk_label_new("");
- new uiValueDisplay(this, zone, GTK_LABEL(lw),precision(step));
- gtk_container_add (GTK_CONTAINER(rei), re);
- if(fGuiSize[zone]) {
- float size = 30 * fGuiSize[zone];
- gtk_widget_set_size_request(rei, size, size );
- gtk_box_pack_start (GTK_BOX(slider), fil, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX(slider), rei, FALSE, FALSE, 0);
- } else {
- gtk_container_add (GTK_CONTAINER(slider), fil);
- gtk_container_add (GTK_CONTAINER(slider), rei);
- }
- gtk_container_add (GTK_CONTAINER(slider), lw);
- gtk_widget_show_all(slider);
-
- if (label && label[0]!=0) {
- openFrameBox(label);
- addWidget(label, slider);
- closeBox();
- } else {
- addWidget(label, slider);
- }
-
- checkForTooltip(zone, slider);
-}
-
-// -------------------------- Vertical Slider -----------------------------------
-
-void GTKUI::addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
-{
- if (isKnob(zone)) {
- addKnob(label, zone, init, min, max, step);
- return;
- }
- *zone = init;
- GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0);
-
- uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
-
- gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
-
- GtkWidget* slider = gtk_vscale_new (GTK_ADJUSTMENT(adj));
- gtk_scale_set_digits(GTK_SCALE(slider), precision(step));
- float size = 160;
- if(fGuiSize[zone]) {
- size = 160 * fGuiSize[zone];
- }
- gtk_widget_set_size_request(slider, -1, size);
-
- gtk_range_set_inverted (GTK_RANGE(slider), TRUE);
-
- if (label && label[0]!=0) {
- openFrameBox(label);
- addWidget(label, slider);
- closeBox();
- } else {
- addWidget(label, slider);
- }
-
- checkForTooltip(zone, slider);
-}
-
-// -------------------------- Horizontal Slider -----------------------------------
-
-void GTKUI::addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
-{
- if (isKnob(zone)) {
- addKnob(label, zone, init, min, max, step);
- return;
- }
- *zone = init;
- GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0);
-
- uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
-
- gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
-
- GtkWidget* slider = gtk_hscale_new (GTK_ADJUSTMENT(adj));
- gtk_scale_set_digits(GTK_SCALE(slider), precision(step));
- float size = 160;
- if(fGuiSize[zone]) {
- size = 160 * fGuiSize[zone];
- }
- gtk_widget_set_size_request(slider, size, -1);
-
- if (label && label[0]!=0) {
- openFrameBox(label);
- addWidget(label, slider);
- closeBox();
- } else {
- addWidget(label, slider);
- }
-
- checkForTooltip(zone, slider);
-}
-
-
-// ------------------------------ Num Entry -----------------------------------
-
-void GTKUI::addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
-{
- if (isKnob(zone)) {
- addKnob(label, zone, init, min, max, step);
- return;
- }
- *zone = init;
- GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, step);
-
- uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
-
- gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
-
- GtkWidget* spinner = gtk_spin_button_new (GTK_ADJUSTMENT(adj), 0.005, precision(step));
-
- openFrameBox(label);
- addWidget(label, spinner);
- closeBox();
-
- checkForTooltip(zone, spinner);
-}
-
-
-// ========================== passive widgets ===============================
-
-
-// ------------------------------ Progress Bar -----------------------------------
-
-struct uiBargraph : public uiItem
-{
- GtkProgressBar* fProgressBar;
- float fMin;
- float fMax;
-
- uiBargraph(GUI* ui, float* zone, GtkProgressBar* pbar, float lo, float hi)
- : uiItem(ui, zone), fProgressBar(pbar), fMin(lo), fMax(hi) {}
-
- float scale(float v) { return (v-fMin)/(fMax-fMin); }
-
- virtual void reflectZone()
- {
- float v = *fZone;
- fCache = v;
- gtk_progress_bar_set_fraction(fProgressBar, scale(v));
- }
-};
-
-
-
-void GTKUI::addVerticalBargraph(const char* label, float* zone, float lo, float hi)
-{
- GtkWidget* pb = gtk_progress_bar_new();
- gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(pb), GTK_PROGRESS_BOTTOM_TO_TOP);
- gtk_widget_set_size_request(pb, 8, -1);
- new uiBargraph(this, zone, GTK_PROGRESS_BAR(pb), lo, hi);
- openFrameBox(label);
- addWidget(label, pb);
- closeBox();
-
- checkForTooltip(zone, pb);
-}
-
-
-void GTKUI::addHorizontalBargraph(const char* label, float* zone, float lo, float hi)
-{
- GtkWidget* pb = gtk_progress_bar_new();
- gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(pb), GTK_PROGRESS_LEFT_TO_RIGHT);
- gtk_widget_set_size_request(pb, -1, 8);
- new uiBargraph(this, zone, GTK_PROGRESS_BAR(pb), lo, hi);
- openFrameBox(label);
- addWidget(label, pb);
- closeBox();
-
- checkForTooltip(zone, pb);
-}
-
-
-// ------------------------------ Num Display -----------------------------------
-
-struct uiNumDisplay : public uiItem
-{
- GtkLabel* fLabel;
- int fPrecision;
-
- uiNumDisplay(GUI* ui, float* zone, GtkLabel* label, int precision)
- : uiItem(ui, zone), fLabel(label), fPrecision(precision) {}
-
- virtual void reflectZone()
- {
- float v = *fZone;
- fCache = v;
- char s[64];
- if (fPrecision <= 0) {
- snprintf(s, 63, "%d", int(v));
- } else if (fPrecision>3) {
- snprintf(s, 63, "%f", v);
- } else {
- const char* format[] = {"%.1f", "%.2f", "%.3f"};
- snprintf(s, 63, format[fPrecision-1], v);
- }
- gtk_label_set_text(fLabel, s);
- }
-};
-
-
-void GTKUI::addNumDisplay(const char* label, float* zone, int precision )
-{
- GtkWidget* lw = gtk_label_new("");
- new uiNumDisplay(this, zone, GTK_LABEL(lw), precision);
- openFrameBox(label);
- addWidget(label, lw);
- closeBox();
-
- checkForTooltip(zone, lw);
-}
-
-
-// ------------------------------ Text Display -----------------------------------
-
-struct uiTextDisplay : public uiItem
-{
- GtkLabel* fLabel;
- const char** fNames;
- float fMin;
- float fMax;
- int fNum;
-
-
- uiTextDisplay (GUI* ui, float* zone, GtkLabel* label, const char* names[], float lo, float hi)
- : uiItem(ui, zone), fLabel(label), fNames(names), fMin(lo), fMax(hi)
- {
- fNum = 0;
- while (fNames[fNum] != 0) fNum++;
- }
-
- virtual void reflectZone()
- {
- float v = *fZone;
- fCache = v;
-
- int idx = int(fNum*(v-fMin)/(fMax-fMin));
-
- if (idx < 0) idx = 0;
- else if (idx >= fNum) idx = fNum-1;
-
- gtk_label_set_text(fLabel, fNames[idx]);
- }
-};
-
-
-void GTKUI::addTextDisplay(const char* label, float* zone, const char* names[], float lo, float hi )
-{
- GtkWidget* lw = gtk_label_new("");
- new uiTextDisplay (this, zone, GTK_LABEL(lw), names, lo, hi);
- openFrameBox(label);
- addWidget(label, lw);
- closeBox();
-
- checkForTooltip(zone, lw);
-}
-
-
-
-void GTKUI::show()
-{
- assert(fTop == 0);
- gtk_widget_show (fBox[0]);
- gtk_widget_show (fWindow);
-}
-
-
-/**
- * Update all user items reflecting zone z
- */
-
-static gboolean callUpdateAllGuis(gpointer)
-{
- GUI::updateAllGuis();
- return TRUE;
-}
-
-
-void GTKUI::run()
-{
- assert(fTop == 0);
- gtk_widget_show (fBox[0]);
- gtk_widget_show (fWindow);
- gtk_timeout_add(40, callUpdateAllGuis, 0);
- gtk_main ();
- stop();
-}
-
-
-
-#endif
-