/* * * Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * Further, this software is distributed without any warranty that it is * free of the rightful claim of any third person regarding infringement * or the like. Any license provided herein, whether implied or * otherwise, applies only to this software file. Patent licenses, if * any, provided herein do not apply to combinations of this program with * other software, or any other product whatsoever. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, * Mountain View, CA 94043, or: * * http://www.sgi.com * * For further information regarding this notice, see: * * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ * */ /* * Copyright (C) 1990-93 Silicon Graphics, Inc. * _______________________________________________________________________ ______________ S I L I C O N G R A P H I C S I N C . ____________ | | $Revision: 1.2 $ | | Classes: | MyThumbWheel | | Author(s) : Alain Dumesny | ______________ S I L I C O N G R A P H I C S I N C . ____________ _______________________________________________________________________ */ #include #include #include #include #include "MyFloatCallbackList.h" #include "MyThumbWheel.h" #include "MyUIRegion.h" #include /* * Defines */ #define TICK_NUM 21 #define PART1 4 #define PART2 5 #define PART3 7 #define PART4 9 #define UI_THICK 3 #define RECT(x1, y1, x2, y2) \ glBegin(GL_LINE_LOOP); \ glVertex2s(x1, y1); glVertex2s(x1, y2); \ glVertex2s(x2, y2); glVertex2s(x2, y1); \ glEnd(); //////////////////////////////////////////////////////////////////////// // // Public constructor - build the widget right now // MyThumbWheel::MyThumbWheel( Widget parent, const char *name, SbBool buildInsideParent, SbBool horiz) : SoXtGLWidget( parent, name, buildInsideParent, SO_GLX_RGB, FALSE) // tell GLWidget not to build just yet // //////////////////////////////////////////////////////////////////////// { // In this case, this component is what the app wants, so buildNow = TRUE constructorCommon(horiz, TRUE); } //////////////////////////////////////////////////////////////////////// // // SoEXTENDER constructor - the subclass tells us whether to build or not // MyThumbWheel::MyThumbWheel( Widget parent, const char *name, SbBool buildInsideParent, SbBool horiz, SbBool buildNow) : SoXtGLWidget( parent, name, buildInsideParent, SO_GLX_RGB, FALSE) // tell GLWidget not to build just yet // //////////////////////////////////////////////////////////////////////// { // In this case, this component may be what the app wants, // or it may want a subclass of this component. Pass along buildNow // as it was passed to us. constructorCommon(horiz, buildNow); } //////////////////////////////////////////////////////////////////////// // // Called by the constructors // // private // void MyThumbWheel::constructorCommon(SbBool horiz, SbBool buildNow) // ////////////////////////////////////////////////////////////////////// { mouse = new SoXtMouse(ButtonPressMask | ButtonReleaseMask | ButtonMotionMask); // init local vars startCallbacks = new MyFloatCallbackList; changedCallbacks = new MyFloatCallbackList; finishCallbacks = new MyFloatCallbackList; interactive = FALSE; value = 0.0; horizontal = horiz; // default size if (horizontal) setGlxSize( SbVec2s(120, 22) ); else setGlxSize( SbVec2s(22, 120) ); // Build the widget tree, and let SoXtComponent know about our base widget. if (buildNow) { Widget w = buildWidget(getParentWidget()); setBaseWidget(w); } } //////////////////////////////////////////////////////////////////////// // // Destructor. // MyThumbWheel::~MyThumbWheel() // //////////////////////////////////////////////////////////////////////// { delete startCallbacks; delete changedCallbacks; delete finishCallbacks; delete mouse; } //////////////////////////////////////////////////////////////////////// // // This routine draws the entire thumb wheel region. // // Use: virtual protected // void MyThumbWheel::redraw() // //////////////////////////////////////////////////////////////////////// { if (! isVisible()) return; glXMakeCurrent(getDisplay(), getNormalWindow(), getNormalContext()); int i, n; short x, y, x1, y1, x2, y2; short mid, rad, l, d; float angle, ang_inc; SbVec2s size = getGlxSize(); x1 = y1 = 0; x2 = size[0] - 1; y2 = size[1] - 1; drawDownUIBorders(x1, y1, x2, y2); x1+=UI_THICK; y1+=UI_THICK; x2-=UI_THICK; y2-=UI_THICK; LIGHT1_UI_COLOR; RECT(x1, y1, x2, y2); x1++; y1++; x2--; y2--; RECT(x1, y1, x2, y2); x1++; y1++; x2--; y2--; glBegin(GL_LINES); if (horizontal) { DARK3_UI_COLOR; glVertex2s(x1,y2); glVertex2s(x2,y2); BLACK_UI_COLOR; glVertex2s(x1,y1); glVertex2s(x2,y1); y1++; y2--; l = x2 - x1; d = 0; BLACK_UI_COLOR; glVertex2s(x1+d, y1); glVertex2s(x2-d, y1); glVertex2s(x1+d, y2); glVertex2s(x2-d, y2); d = (short)(l * .06); DARK2_UI_COLOR; glVertex2s(x1+d, y1); glVertex2s(x2-d, y1); glVertex2s(x1+d, y2); glVertex2s(x2-d, y2); d = (short)(l * .12); DARK1_UI_COLOR; glVertex2s(x1+d, y1); glVertex2s(x2-d, y1); glVertex2s(x1+d, y2); glVertex2s(x2-d, y2); d = (short)(l * .20); MAIN_UI_COLOR; glVertex2s(x1+d, y1); glVertex2s(x2-d, y1); glVertex2s(x1+d, y2); glVertex2s(x2-d, y2); d = (short)(l * .30); LIGHT1_UI_COLOR; glVertex2s(x1+d, y1); glVertex2s(x2-d, y1); glVertex2s(x1+d, y2); glVertex2s(x2-d, y2); d = (short)(l * .40); WHITE_UI_COLOR; glVertex2s(x1+d, y1); glVertex2s(x2-d, y1); glVertex2s(x1+d, y2); glVertex2s(x2-d, y2); x1++; y1++; x2--; y2--; } else { DARK3_UI_COLOR; glVertex2s(x1,y1); glVertex2s(x1,y2); BLACK_UI_COLOR; glVertex2s(x2,y1); glVertex2s(x2,y2); x1++; x2--; l = y2 - y1; d = 0; BLACK_UI_COLOR; glVertex2s(x1, y1+d); glVertex2s(x1, y2-d); glVertex2s(x2, y1+d); glVertex2s(x2, y2-d); d = (short)(l * .06); DARK2_UI_COLOR; glVertex2s(x1, y1+d); glVertex2s(x1, y2-d); glVertex2s(x2, y1+d); glVertex2s(x2, y2-d); d = (short)(l * .12); DARK1_UI_COLOR; glVertex2s(x1, y1+d); glVertex2s(x1, y2-d); glVertex2s(x2, y1+d); glVertex2s(x2, y2-d); d = (short)(l * .20); MAIN_UI_COLOR; glVertex2s(x1, y1+d); glVertex2s(x1, y2-d); glVertex2s(x2, y1+d); glVertex2s(x2, y2-d); d = (short)(l * .30); LIGHT1_UI_COLOR; glVertex2s(x1, y1+d); glVertex2s(x1, y2-d); glVertex2s(x2, y1+d); glVertex2s(x2, y2-d); d = (short)(l * .40); WHITE_UI_COLOR; glVertex2s(x1, y1+d); glVertex2s(x1, y2-d); glVertex2s(x2, y1+d); glVertex2s(x2, y2-d); x1++; y1++; x2--; y2--; } glEnd(); MAIN_UI_COLOR; glRecti(x1, y1, x2, y2); // // draw the tick marks // angle = value; ang_inc = M_PI / TICK_NUM; n = (int)(floorf(angle / ang_inc)); angle -= n * ang_inc; glBegin(GL_LINES); if (horizontal) { mid = size[0] / 2; rad = mid - UI_THICK - 2; for (i=0; i(TICK_NUM - PART1)) { BLACK_UI_COLOR; glVertex2s(x, y1); glVertex2s(x, y2); x++; DARK1_UI_COLOR; glVertex2s(x, y1); glVertex2s(x, y2); } else if (i(TICK_NUM - PART2)) { DARK3_UI_COLOR; glVertex2s(x, y1); glVertex2s(x, y2); } else if (i(TICK_NUM - PART3)) { LIGHT1_UI_COLOR; glVertex2s(x, y1); glVertex2s(x, y2); x++; DARK2_UI_COLOR; glVertex2s(x, y1); glVertex2s(x, y2); } else if (i(TICK_NUM - PART4)) { WHITE_UI_COLOR; glVertex2s(x, y1); glVertex2s(x, y2); x++; DARK2_UI_COLOR; glVertex2s(x, y1); glVertex2s(x, y2); } else { WHITE_UI_COLOR; x--; glVertex2s(x, y1); glVertex2s(x, y2); x++; glVertex2s(x, y1); glVertex2s(x, y2); DARK2_UI_COLOR; x++; glVertex2s(x, y1); glVertex2s(x, y2); } angle += ang_inc; } } else { mid = size[1] / 2; rad = mid - UI_THICK - 2; for (i=0; i(TICK_NUM - PART1)) { BLACK_UI_COLOR; glVertex2s(x1, y); glVertex2s(x2, y); y--; DARK1_UI_COLOR; glVertex2s(x1, y); glVertex2s(x2, y); } else if (i(TICK_NUM - PART2)) { DARK3_UI_COLOR; glVertex2s(x1, y); glVertex2s(x2, y); } else if (i(TICK_NUM - PART3)) { LIGHT1_UI_COLOR; glVertex2s(x1, y); glVertex2s(x2, y); y--; DARK2_UI_COLOR; glVertex2s(x1, y); glVertex2s(x2, y); } else if (i(TICK_NUM - PART4)) { WHITE_UI_COLOR; glVertex2s(x1, y); glVertex2s(x2, y); y--; DARK2_UI_COLOR; glVertex2s(x1, y); glVertex2s(x2, y); } else { WHITE_UI_COLOR; y++; glVertex2s(x1, y); glVertex2s(x2, y); y--; glVertex2s(x1, y); glVertex2s(x2, y); DARK2_UI_COLOR; y--; glVertex2s(x1, y); glVertex2s(x2, y); } angle += ang_inc; } } glEnd(); glFlush(); } //////////////////////////////////////////////////////////////////////// // // Description: // This builds the parent Glx widget, then registers interest // in mouse events. // // Use: protected Widget MyThumbWheel::buildWidget(Widget parent) // //////////////////////////////////////////////////////////////////////// { Widget w = SoXtGLWidget::buildWidget(parent); mouse->enable(getNormalWidget(), (XtEventHandler) SoXtGLWidget::eventHandler, (XtPointer) this); return w; } //////////////////////////////////////////////////////////////////////// // // Process the passed X event. // // Use: virtual protected // void MyThumbWheel::processEvent(XAnyEvent *xe) // //////////////////////////////////////////////////////////////////////// { XButtonEvent *be; XMotionEvent *me; SbVec2s size = getGlxSize(); switch (xe->type) { case ButtonPress: be = (XButtonEvent *) xe; if (be->button == Button1) { startCallbacks->invokeCallbacks(value); interactive = TRUE; // get starting point lastPosition = (horizontal) ? be->x : (size[1] - be->y); } break; case ButtonRelease: be = (XButtonEvent *) xe; if (be->button == Button1) { interactive = FALSE; finishCallbacks->invokeCallbacks(value); } break; case MotionNotify: me = (XMotionEvent *) xe; if (me->state & Button1Mask) { float r; if (horizontal) r = (me->x - lastPosition) / float(size[0] - 2 * UI_THICK); else r = (size[1] - me->y - lastPosition) / float(size[1] - 2 * UI_THICK); // now rotate wheel if (r != 0.0) { value += r * M_PI; changedCallbacks->invokeCallbacks(value); redraw(); } lastPosition = (horizontal) ? me->x : (size[1] - me->y); } break; } } //////////////////////////////////////////////////////////////////////// // // Sets the thumb wheel to this value.. // // Use: public // void MyThumbWheel::setValue(float v) // //////////////////////////////////////////////////////////////////////// { if (value == v) return; value = v; // call the callbacks changedCallbacks->invokeCallbacks(value); redraw(); } //////////////////////////////////////////////////////////////////////// // // This routine is when the window has changed size // // Use: virtual protected // void MyThumbWheel::sizeChanged(const SbVec2s &newSize) // //////////////////////////////////////////////////////////////////////// { glXMakeCurrent(getDisplay(), getNormalWindow(), getNormalContext()); // reset projection glViewport(0, 0, newSize[0], newSize[1]); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0, newSize[0], 0, newSize[1], -1, 1); } void MyThumbWheel::addStartCallback(MyThumbWheelCB *f, void *userData) { startCallbacks->addCallback((MyFloatCallbackListCB *)f, userData); } void MyThumbWheel::addValueChangedCallback(MyThumbWheelCB *f, void *userData) { changedCallbacks->addCallback((MyFloatCallbackListCB *)f, userData); } void MyThumbWheel::addFinishCallback(MyThumbWheelCB *f, void *userData) { finishCallbacks->addCallback((MyFloatCallbackListCB *)f, userData); } void MyThumbWheel::removeStartCallback(MyThumbWheelCB *f, void *userData) { startCallbacks->removeCallback((MyFloatCallbackListCB *)f, userData); } void MyThumbWheel::removeValueChangedCallback(MyThumbWheelCB *f, void *userData) { changedCallbacks->removeCallback((MyFloatCallbackListCB *)f, userData); } void MyThumbWheel::removeFinishCallback(MyThumbWheelCB *f, void *userData) { finishCallbacks->removeCallback((MyFloatCallbackListCB *)f, userData); }