plib-mac-dist/include/plib/puAux.h
2022-10-15 14:31:14 +08:00

945 lines
29 KiB
C++

/*
PUI Auxiliary Widget Library
Derived from PLIB, the Portable Game Library by Steve Baker.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library 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
For further information visit http://plib.sourceforge.net
$Id: puAux.h 2160 2010-02-27 03:48:23Z fayjf $
*/
#ifndef _PUI_AUX_WIDGETS_H_
#define _PUI_AUX_WIDGETS_H_ 1
#include "pu.h"
// Widget Class Bit Patterns
// PUI classes take up 0x00000001 through 0x00020000
#define PUCLASS_FILESELECTOR 0x00040000 /* Because FilePicker is obsolete */
#define PUCLASS_BISLIDER 0x00080000
#define PUCLASS_TRISLIDER 0x00100000
#define PUCLASS_VERTMENU 0x00200000
#define PUCLASS_LARGEINPUT 0x00400000
#define PUCLASS_COMBOBOX 0x00800000
#define PUCLASS_SELECTBOX 0x01000000
#define PUCLASS_SPINBOX 0x02000000
#define PUCLASS_SCROLLBAR 0x04000000
#define PUCLASS_BISLIDERWITHENDS 0x08000000
#define PUCLASS_SLIDERWITHINPUT 0x10000000
#define PUCLASS_COMPASS 0x20000000
#define PUCLASS_CHOOSER 0x40000000
#define PUCLASS_LIST 0x80000000
// Widget Declarations
class puaSpinBox ;
class puaFileSelector ;
class puaBiSlider ;
class puaTriSlider ;
class puaVerticalMenu ;
class puaLargeInput ;
class puaComboBox ;
class puaSelectBox ;
class puaScrollBar ;
class puaBiSliderWithEnds ;
class puaCompass ;
class puaSliderWithInput ;
class puaChooser ;
class puaList ;
// A File selector widget
class puaFileSelector : public puDialogBox
{
UL_TYPE_DATA
protected:
char** files ;
char* dflag ;
int num_files ;
int arrow_count ;
char *startDir ;
void find_files ( void ) ;
static void handle_select ( puObject* ) ;
static void input_entered ( puObject* ) ;
puFrame *frame ;
puListBox *list_box ;
puSlider *slider ;
puOneShot *cancel_button ;
puOneShot *ok_button ;
puInput *input ;
puArrowButton *up_arrow ;
puArrowButton *down_arrow ;
puArrowButton *fastup_arrow ;
puArrowButton *fastdown_arrow ;
void puaFileSelectorInit ( int x, int y, int w, int h,
int arrows, const char *dir, const char *title ) ;
public:
puaFileSelector ( int x, int y, int w, int h, int arrows,
const char *dir, const char *title = "Pick a file" ) :
puDialogBox ( x, y )
{
puaFileSelectorInit ( x, y, w, h, arrows, dir, title ) ;
}
puaFileSelector ( int x, int y, int w, int h,
const char *dir, const char *title = "Pick a file" ) :
puDialogBox ( x, y )
{
puaFileSelectorInit ( x, y, w, h, 1, dir, title ) ;
}
puaFileSelector ( int x, int y, int arrows,
const char *dir, const char *title = "Pick a file" ) :
puDialogBox ( x, y )
{
puaFileSelectorInit ( x, y, 220, 170, arrows, dir, title ) ;
}
puaFileSelector ( int x, int y,
const char *dir, const char *title = "Pick a file" ) :
puDialogBox ( x, y )
{
puaFileSelectorInit ( x, y, 220, 170, 1, dir, title ) ;
}
~puaFileSelector () ;
/* Not for application use!! */
puInput *__getInput ( void ) const { return input ; }
char *__getStartDir ( void ) const { return (char *) startDir ; }
void setInitialValue ( const char *fname ) ;
void setSize ( int w, int h ) ;
} ;
// An input box that takes an arbitrary number of lines of input
class puaLargeInput : public puInputBase, public puGroup
{
UL_TYPE_DATA
protected:
int num_lines ; // Number of lines of text in the box
int lines_in_window ; // Number of lines showing in the window
int top_line_in_window ; // Number of the first line in the window
int max_width ; // Width of longest line of text in box, in pixels
int slider_width ;
int line_height ; // Text height + interline gap
int vgap ; // Gap on top and bottom
int hgap ; // Gap on the left and right side
int input_width ; // Width of display area (widget minus gaps & slider)
int input_height ; // Height of display area
puFrame *frame ;
puFrame *plug ; // Little square in the bottom right corner
puaScrollBar *bottom_slider ; // Horizontal slider at bottom of window
puaScrollBar *right_slider ; // Vertical slider at right of window
int arrow_count ; // Number of up/down arrows above and below the right slider
void normalizeCursors ( void ) ;
void removeSelectRegion ( void ) ;
void updateGeometry ( void ) ;
char *wrapText ( int target_width = 0, int *numlines = 0, int *maxwidth = 0 ) ;
void getTextProperties(int *numlines, int *maxwidth) ;
char *getText () { return bottom_slider ? getStringValue () : getDisplayedText () ; }
public:
puaLargeInput ( int x, int y, int w, int h, int arrows, int sl_width, int wrap_text = FALSE ) ;
~puaLargeInput ()
{
if ( puActiveWidget() == this )
puDeactivateWidget () ;
}
void setSize ( int w, int h ) ;
void setLegendFont ( puFont f ) { puGroup::setLegendFont ( f ) ; updateGeometry () ; }
int getNumLines ( void ) const { return num_lines ; }
int getLinesInWindow ( void ) const { return lines_in_window ; }
void setTopLineInWindow ( int val ) { top_line_in_window = (val<0) ? 0 : ( (val>num_lines-2) ? num_lines-2 : val ) ; }
void setSliderPosition ( float fraction ) ;
void draw ( int dx, int dy ) ;
int checkHit ( int button, int updown, int x, int y ) ;
void doHit ( int button, int updown, int x, int y ) ;
int checkKey ( int key, int updown ) ;
void setSelectRegion ( int s, int e ) ;
void selectEntireLine ( void ) ;
void invokeDownCallback ( void )
{
rejectInput () ;
normalizeCursors () ;
if ( down_cb != NULL ) (*down_cb)(this) ;
}
void setValue ( const char *s ) ;
void addNewLine ( const char *l ) ;
void addText ( const char *l ) ;
void appendText ( const char *l ) ;
void removeText ( int start, int end ) ;
char *getDisplayedText ( void )
{
return ( displayed_text == NULL ? getStringValue () : displayed_text ) ;
}
} ;
// A box that contains a set of alternatives that drop down when the user clicks on the down-arrow
// Defined constants telling how the callback got triggered. This is needed for
// cases in which the user has deleted the entry in the input box and wants that
// entry deleted from the list of items.
#define PUACOMBOBOX_CALLBACK_NONE 0
#define PUACOMBOBOX_CALLBACK_INPUT 1
#define PUACOMBOBOX_CALLBACK_ARROW 2
class puaComboBox : public puGroup
{
UL_TYPE_DATA
protected:
char ** list ;
int num_items ;
int curr_item ;
puInput *input ;
puArrowButton *arrow_btn ;
puPopupMenu *popup_menu ;
int callback_source ;
static void input_cb ( puObject *inp ) ;
static void input_active_cb ( puObject *inp ) ;
static void input_down_cb ( puObject *inp ) ;
static void handle_arrow ( puObject *arrow ) ;
static void handle_popup ( puObject *popupm ) ;
void update_widgets ( void ) ;
void update_current_item ( void ) ;
void setCallbackSource ( int s ) { callback_source = s ; }
public:
/* Not for application use ! */
puPopupMenu * __getPopupMenu ( void ) const { return popup_menu ; }
void newList ( char ** _list ) ;
int getNumItems ( void ) const { return num_items ; }
char *getNewEntry ( void ) const { return input->getStringValue () ; }
int getCurrentItem ( void ) ;
void setCurrentItem ( int item )
{
if ( ( item >= 0 ) && ( item < num_items ) )
{
curr_item = item ;
update_widgets () ;
callback_source = PUACOMBOBOX_CALLBACK_ARROW ;
invokeCallback () ;
}
}
void setCurrentItem ( const char *item_ptr ) ;
void setPosition ( int x, int y )
{
puGroup::setPosition ( x, y ) ;
/* Ensure that popup menu will show up at the right place */
newList ( list ) ;
}
void setSize ( int w, int h ) ;
void setValue ( float f ) { puValue::setValue ( f ) ; input->setValue ( f ) ; }
void setValue ( int i ) { puValue::setValue ( i ) ; input->setValue ( i ) ; }
void setValue ( const char *s ) { puValue::setValue ( s ) ; input->setValue ( s ) ; }
void setValue ( puValue *pv ) { puValue::setValue ( pv ) ; input->setValue ( pv ) ; }
void draw ( int dx, int dy ) ;
int checkHit ( int button, int updown, int x, int y ) ;
int checkKey ( int key, int updown ) ;
int getCallbackSource ( void ) const { return callback_source ; }
virtual void setColourScheme ( float r, float g, float b, float a = 1.0f ) ;
virtual void setColour ( int which, float r, float g, float b, float a = 1.0f ) ;
puaComboBox ( int minx, int miny, int maxx, int maxy,
char **list, int editable = TRUE ) ;
~puaComboBox ()
{
int i ;
for ( i = 0; i < num_items; i++ )
delete [] list[i] ;
delete [] list ;
}
} ;
// Like a menu bar, but the selections are one above the other
class puaVerticalMenu : public puGroup
{
UL_TYPE_DATA
protected:
public:
puaVerticalMenu ( int x = -1, int y = -1 ) :
puGroup ( x < 0 ? puGetWindowWidth() -
( puGetDefaultLegendFont().getStringWidth ( " " )
+ PUSTR_TGAP + PUSTR_BGAP ) : x,
y < 0 ? puGetWindowHeight() -
( puGetDefaultLegendFont().getStringHeight ()
+ PUSTR_TGAP + PUSTR_BGAP ) : y)
{
type |= PUCLASS_VERTMENU ;
floating = TRUE ; // DEPRECATED! -- we need to replace this code.
if ( y < 0 ) { setVStatus( TRUE ) ; } /* It is now supposed to stick to the top left - JCJ*/
}
void add_submenu ( const char *str, char *items[], puCallback _cb[],
void *_user_data[] = NULL ) ;
void close ( void ) ;
} ;
// Not sure what this one does ...
class puaSelectBox : public puGroup
{
UL_TYPE_DATA
protected:
char ** list ;
int num_items ;
int curr_item ;
puInput *input ;
puArrowButton *down_arrow ;
puArrowButton *up_arrow ;
static void handle_arrow ( puObject *arrow ) ;
void update_widgets ( void ) ;
public:
void newList ( char ** _list ) ;
int getNumItems ( void ) const { return num_items ; }
int getCurrentItem ( void ) const { return curr_item ; }
void setCurrentItem ( int item )
{
if ( ( item >= 0 ) && ( item < num_items ) )
{
curr_item = item ;
update_widgets () ;
invokeCallback () ;
}
}
void setSize ( int w, int h ) ;
void draw ( int dx, int dy ) ;
int checkKey ( int key, int updown ) ;
virtual void setColourScheme ( float r, float g, float b, float a = 1.0f ) ;
virtual void setColour ( int which, float r, float g, float b, float a = 1.0f ) ;
puaSelectBox ( int minx, int miny, int maxx, int maxy,
char **list ) ;
} ;
// A slider with up- and down-arrows on its ends
class puaScrollBar : public puSlider
{
UL_TYPE_DATA
protected:
int arrow_count ;
int active_arrow ;
float line_step_size ;
enum { NONE = 0, FASTDOWN = 1, DOWN = 2, UP = 4, FASTUP = 8 };
public:
void doHit ( int button, int updown, int x, int y ) ;
void draw ( int dx, int dy ) ;
int checkHit ( int button, int updown, int x, int y ) ;
puaScrollBar ( int minx, int miny, int sz, int arrows, int vertical = FALSE ) :
puSlider ( minx, miny, sz, vertical )
{
type |= PUCLASS_SCROLLBAR ;
arrow_count = arrows ;
active_arrow = NONE ;
line_step_size = 0.0f ;
}
/* Alternate constructor which lets you explicitly set width */
puaScrollBar ( int minx, int miny, int sz, int arrows, int vertical, int width ) :
puSlider ( minx, miny, sz, vertical, width )
{
type |= PUCLASS_SCROLLBAR ;
arrow_count = arrows ;
active_arrow = NONE ;
line_step_size = 0.0f ;
}
void setMaxValue ( float f )
{
maximum_value = f ;
slider_fraction = 1.0f / ( getMaxValue() - getMinValue() + 1.0f ) ;
puPostRefresh () ;
}
void setMinValue ( float i )
{
minimum_value = i ;
slider_fraction = 1.0f / ( getMaxValue() - getMinValue() + 1.0f ) ;
puPostRefresh () ;
}
void setLineStepSize ( float s ) { line_step_size = s ; }
float getLineStepSize ( void ) const { return line_step_size ; }
} ;
// A puSlider with two slide boxes instead of one
class puaBiSlider : public puSlider
{
UL_TYPE_DATA
protected:
float current_max ;
float current_min ;
int active_button ; // Zero for none, one for min, two for max
public:
void doHit ( int button, int updown, int x, int y ) ;
void draw ( int dx, int dy ) ;
puaBiSlider ( int minx, int miny, int sz, int vertical = FALSE ) :
puSlider ( minx, miny, sz, vertical )
{
type |= PUCLASS_BISLIDER ;
setMaxValue ( 1.0f ) ;
setMinValue ( 0.0f ) ;
setStepSize ( 1.0f ) ;
current_max = 1.0f ;
current_min = 0.0f ;
active_button = 0 ;
}
/* Alternate constructor which lets you explicitly set width */
puaBiSlider ( int minx, int miny, int sz, int vertical, int width ) :
puSlider ( minx, miny, sz, vertical, width )
{
type |= PUCLASS_BISLIDER ;
setMaxValue ( 1.0f ) ;
setMinValue ( 0.0f ) ;
setStepSize ( 1.0f ) ;
current_max = 1.0f ;
current_min = 0.0f ;
active_button = 0 ;
}
void setMaxValue ( float i )
{
maximum_value = i ;
slider_fraction = 1.0f / ( getMaxValue() - getMinValue() + 1.0f ) ;
puPostRefresh () ;
}
void setMinValue ( float i )
{
minimum_value = i ;
slider_fraction = 1.0f / ( getMaxValue() - getMinValue() + 1.0f ) ;
puPostRefresh () ;
}
void setCurrentMax ( int i ) { current_max = (float) i ; puPostRefresh () ; } /* DEPRECATED */
void setCurrentMax ( float f ) { current_max = f ; puPostRefresh () ; }
float getCurrentMax ( void ) const { return current_max ; }
void setCurrentMin ( int i ) { current_min = (float) i ; puPostRefresh () ; } /* DEPRECATED */
void setCurrentMin ( float f ) { current_min = f ; puPostRefresh () ; }
float getCurrentMin ( void ) const { return current_min ; }
void setActiveButton ( int i ) { active_button = i ; }
int getActiveButton ( void ) const { return active_button ; }
} ;
// A puSlider with three slide boxes
class puaTriSlider : public puaBiSlider
{
UL_TYPE_DATA
protected:
// "active_button" is now zero for none, one for min, two for middle, three for max
int freeze_ends ; // true to make end sliders unmovable
public:
void doHit ( int button, int updown, int x, int y ) ;
void draw ( int dx, int dy ) ;
puaTriSlider ( int minx, int miny, int sz, int vertical = FALSE ) :
puaBiSlider ( minx, miny, sz, vertical )
{
type |= PUCLASS_TRISLIDER ;
freeze_ends = TRUE ;
}
/* Alternate constructor which lets you explicitly set width */
puaTriSlider ( int minx, int miny, int sz, int vertical, int width ) :
puaBiSlider ( minx, miny, sz, vertical, width )
{
type |= PUCLASS_TRISLIDER ;
freeze_ends = TRUE ;
}
int getFreezeEnds ( void ) const { return freeze_ends ; }
void setFreezeEnds ( int val ) { freeze_ends = val ; puPostRefresh () ; }
} ;
// A vertical puBiSlider with a puInput box above it showing the current maximum
// value and a puInput box below it showing the current minimum value
class puaBiSliderWithEnds : public puGroup
{
UL_TYPE_DATA
protected:
puaBiSlider *slider ;
puInput *max_box ;
puInput *min_box ;
static void handle_slider ( puObject *obj ) ;
static void handle_max ( puObject *obj ) ;
static void handle_min ( puObject *obj ) ;
static void input_down_callback ( puObject *obj ) ;
void update_widgets ( void ) ;
public:
// For internal use only:
void __setMax ( float f ) { max_box->setValue ( f ) ; }
void __setMin ( float f ) { min_box->setValue ( f ) ; }
// For public use:
void draw ( int dx, int dy ) ;
int checkHit ( int button, int updown, int x, int y )
{
return puGroup::checkHit ( button, updown, x, y ) ;
}
int checkKey ( int key, int updown ) ;
puaBiSliderWithEnds ( int minx, int miny, int maxx, int maxy ) ;
void setSize ( int w, int h ) ;
void setMaxValue ( float f ) { slider->setMaxValue ( f ) ; }
float getMaxValue ( void ) const { return slider->getMaxValue () ; }
void setMinValue ( float f ) { slider->setMinValue ( f ) ; }
float getMinValue ( void ) const { return slider->getMinValue () ; }
void setCurrentMax ( float f )
{
slider->setCurrentMax ( f ) ;
max_box->setValue ( f ) ;
}
float getCurrentMax ( void ) const { return slider->getCurrentMax () ; }
void setCurrentMin ( float f )
{
slider->setCurrentMin ( f ) ;
min_box->setValue ( f ) ;
}
float getCurrentMin ( void ) const { return slider->getCurrentMin () ; }
void setActiveButton ( int i ) { slider->setActiveButton ( i ) ; }
int getActiveButton ( void ) const { return slider->getActiveButton () ; }
char *getValidData ( void ) const { return max_box->getValidData () ; }
void setValidData ( char *data ) { max_box->setValidData ( data ) ; min_box->setValidData ( data ) ; }
void addValidData ( char *data ) { max_box->addValidData ( data ) ; min_box->addValidData ( data ) ; }
void setCBMode ( int m ) { slider->setCBMode ( m ) ; }
int getCBMode ( void ) const { return slider->getCBMode () ; }
void setDelta ( float f ) { slider->setDelta ( f ) ; }
float getDelta ( void ) const { return slider->getDelta () ; }
float getStepSize ( void ) const { return slider->getStepSize () ; }
void setStepSize ( float f ) { slider->setStepSize ( f ) ; }
} ;
// A vertical puSlider with a puInput box above or below it showing its value
class puaSliderWithInput : public puGroup
{
UL_TYPE_DATA
protected:
puSlider *slider ;
puInput *input_box ;
int input_position ;
static void handle_slider ( puObject *obj ) ;
static void handle_input ( puObject *obj ) ;
static void input_down_callback ( puObject *obj ) ;
void update_widgets ( void ) ;
public:
// For internal use only:
void __setInputBox ( float f ) { input_box->setValue ( f ) ; }
// For public use:
void draw ( int dx, int dy ) ;
int checkHit ( int button, int updown, int x, int y )
{
return puGroup::checkHit ( button, updown, x, y ) ;
}
int checkKey ( int key, int updown ) ;
puaSliderWithInput ( int minx, int miny, int maxx, int maxy, int above = 0 ) ;
void setSize ( int w, int h ) ;
void setMaxValue ( float f ) { slider->setMaxValue ( f ) ; }
float getMaxValue ( void ) const { return slider->getMaxValue () ; }
void setMinValue ( float f ) { slider->setMinValue ( f ) ; }
float getMinValue ( void ) const { return slider->getMinValue () ; }
void setValue ( int i ) { slider->setValue ( i ) ; input_box->setValue ( i ) ; }
void setValue ( float f ) { slider->setValue ( f ) ; input_box->setValue ( f ) ; }
virtual void setValue ( const char *s ) { slider->setValue ( s ) ; }
virtual void setValue ( bool b ) { slider->setValue ( b ) ; }
int getIntegerValue ( void ) { return slider->getIntegerValue () ; }
float getFloatValue ( void ) { return slider->getFloatValue () ; }
char getCharValue ( void ) { return slider->getCharValue () ; }
char *getStringValue ( void ) { return slider->getStringValue () ; }
bool getBooleanValue ( void ) { return slider->getBooleanValue () ; }
char *getValidData ( void ) const { return input_box->getValidData () ; }
void setValidData ( char *data ) { input_box->setValidData ( data ) ; }
void addValidData ( char *data ) { input_box->addValidData ( data ) ; }
void setCBMode ( int m ) { slider->setCBMode ( m ) ; }
int getCBMode ( void ) const { return slider->getCBMode () ; }
void setDelta ( float f ) { slider->setDelta ( f ) ; }
float getDelta ( void ) const { return slider->getDelta () ; }
float getStepSize ( void ) const { return slider->getStepSize () ; }
void setStepSize ( float f ) { slider->setStepSize ( f ) ; }
} ;
class puaSpinBox : public puRange, public puGroup
{
UL_TYPE_DATA
protected :
puInput *input_box ;
puArrowButton *up_arrow ;
puArrowButton *down_arrow ;
int arrow_position ;
public :
/* Whether the arrows are on the LEFT of the input box (0) or RIGHT (1 DEFAULT) */
int getArrowPosition ( void ) const { return arrow_position ; }
/* Offered as a proportion of the input box height. Default = 0.5 */
void setArrowHeight ( float height )
{
puBox ibox = *(input_box->getABox()) ;
int size = int(height * ( ibox.max[1] - ibox.min[1] )) ;
up_arrow->setSize ( size, size ) ;
down_arrow->setSize ( size, size ) ;
int xpos = getArrowPosition () ? ibox.max[0] : ibox.min[0] - size ;
int ymid = ( ibox.max[1] + ibox.min[1] ) / 2 ;
if ( getArrowPosition () == 0 ) /* Arrows are on the left, adjust the x-position of the input box */
{
ibox.min[0] -= xpos ;
input_box->setPosition ( ibox.min[0], ibox.min[1] ) ;
abox.min[0] += xpos ;
xpos = 0 ;
}
if ( height > 0.5f ) /* Adjust the input box to be up from the bottom */
{
input_box->setPosition ( ibox.min[0], ibox.min[1] + size - ymid ) ;
abox.min[1] += ymid - size ;
ymid = size ;
}
else /* Input box is at the bottom of the group area */
{
input_box->setPosition ( ibox.min[0], 0 ) ;
abox.min[1] += ibox.min[1] ;
}
up_arrow->setPosition ( xpos, ymid ) ;
down_arrow->setPosition ( xpos, ymid - size ) ;
recalc_bbox() ;
}
float getArrowHeight ( void ) const
{
int awid, ahgt, iwid, ihgt ;
input_box->getSize ( &iwid, &ihgt ) ;
up_arrow->getSize ( &awid, &ahgt ) ;
return float(ahgt) / float(ihgt) ;
}
puaSpinBox ( int minx, int miny, int maxx, int maxy, int arrow_pos = 1 ) ;
void setValue ( float f ) { puValue::setValue ( f ) ; input_box->setValue ( f ) ; }
void setValue ( int i ) { puValue::setValue ( i ) ; input_box->setValue ( i ) ; }
void setValue ( const char *s ) { puValue::setValue ( s ) ; input_box->setValue ( s ) ; }
void setValue ( puValue *pv ) { puValue::setValue ( pv ) ; input_box->setValue ( pv ) ; }
} ;
/*
* Widget that looks like a 3-d coordinate system with quarter-circles in the coordinate planes.
* It is used in 3-d modeling to translate and rotate the scene. The coordinates rotate with
* the scene but do not translate. Defined values are:
* 0 - Nothing active
* 1 - Dot at origin active: reset (usually)
* 2 - X-axis dot active: rotate about y- and z-axes
* 3 - Y-axis dot active: rotate about z- and x-axes
* 4 - Z-axis dot active: rotate about x- and y-axes
* 5 - X-axis bar active: translate along x-axis
* 6 - Y-axis bar active: translate along y-axis
* 7 - Z-axis bar active: translate along z-axis
* 8 - XY-plane arc active: rotate about z-axis
* 9 - YZ-plane arc active: rotate about x-axis
* 10 - ZX-plane arc active: rotate about y-axis
* 11 - X-axis, Y-axis, and XY-arc active: translate in xy-plane
* 12 - Y-axis, Z-axis, and YZ-arc active: translate in yz-plane
* 13 - Z-axis, X-axis, and ZX-arc active: translate in zx-plane
*/
#define PUACOMPASS_INACTIVE 0
#define PUACOMPASS_RESET 1
#define PUACOMPASS_ROTATE_Y_Z 2
#define PUACOMPASS_ROTATE_Z_X 3
#define PUACOMPASS_ROTATE_X_Y 4
#define PUACOMPASS_TRANSLATE_X 5
#define PUACOMPASS_TRANSLATE_Y 6
#define PUACOMPASS_TRANSLATE_Z 7
#define PUACOMPASS_ROTATE_Z 8
#define PUACOMPASS_ROTATE_X 9
#define PUACOMPASS_ROTATE_Y 10
#define PUACOMPASS_TRANSLATE_X_Y 11
#define PUACOMPASS_TRANSLATE_Y_Z 12
#define PUACOMPASS_TRANSLATE_Z_X 13
class puaCompass : public puObject
{
UL_TYPE_DATA
protected :
sgQuat rotation ;
sgVec3 translation ;
float point_size ;
int button_state ;
int trigger_button ;
float mouse_x, mouse_y, mouse_z ;
float translation_sensitivity ;
float xint, yint, zint ;
float prev_angle ;
sgQuat prev_rotation ;
public :
puaCompass ( int minx, int miny, int maxx, int maxy ) : puObject ( minx, miny, maxx, maxy )
{
setValue ( PUACOMPASS_INACTIVE ) ;
// sgSetQuat ( rotation, 1.0f, 0.0f, 0.0f, 0.0f ) ;
// sgSetQuat ( rotation, 0.707107f, 0.707107f, 0.0f, 0.0f ) ;
// sgSetQuat ( rotation, 0.5f, -0.5f, 0.5f, 0.5f ) ;
// sgSetQuat ( rotation, 0.866025f, -0.166667f, 0.166667f, 0.166667f ) ;
sgSetQuat ( rotation, 0.866025f, -0.408248f, 0.288675f, 0.0f ) ;
sgSetVec3 ( translation, 0.0f, 0.0f, 0.0f ) ;
point_size = 10.0f ;
button_state = PU_UP ;
trigger_button = active_mouse_button ;
mouse_x = mouse_y = mouse_z = 0.0f ;
translation_sensitivity = 1.0f ;
xint = yint = zint = 0.0f ;
prev_angle = 0.0f ;
sgCopyQuat ( prev_rotation, rotation ) ;
}
void draw ( int dx, int dy ) ;
void doHit ( int button, int updown, int x, int y ) ;
// Accessors and mutators
void getRotation ( sgQuat q ) const { memcpy ( q, rotation, 4 * sizeof(sgFloat) ) ; }
void setRotation ( sgQuat q ) { memcpy ( rotation, q, 4 * sizeof(sgFloat) ) ; }
void setRotation ( sgFloat t, sgFloat x, sgFloat y, sgFloat z )
{
sgFloat sinth = sgSin ( t / 2.0f ) ;
sgFloat norm = sgSqrt ( x * x + y * y + z * z ) ;
if ( norm == 0.0 ) norm = 1.0 ;
rotation[SG_W] = sgCos ( t / 2.0f ) ;
rotation[SG_X] = sinth * x / norm ;
rotation[SG_Y] = sinth * y / norm ;
rotation[SG_Z] = sinth * z / norm ;
}
void getTranslation ( sgVec3 t ) const { memcpy ( t, translation, 3 * sizeof(sgFloat) ) ; }
void setTranslation ( sgVec3 t ) { memcpy ( translation, t, 3 * sizeof(sgFloat) ) ; }
void setTranslation ( sgFloat x, sgFloat y, sgFloat z ) { translation[SG_X] = x ; translation[SG_Y] = y ; translation[SG_Z] = z ; }
float getPointSize () const { return point_size ; }
void setPointSize ( float p ) { point_size = p ; }
int getTriggerButton () const { return trigger_button ; }
void setTriggerButton ( int b ) { trigger_button = b ; }
float getTranslationSensitivity () const { return translation_sensitivity ; }
void setTranslationSensitivity ( float t ) { translation_sensitivity = t ; }
} ;
class puaChooser
{
UL_TYPE_DATA
puButton *chooser_button ;
puPopupMenu *popup_menu ;
int x1, y1, x2, y2 ;
static void static_popup_cb ( puObject * ) ;
static void static_menu_cb ( puObject * ) ;
public:
virtual ~puaChooser ()
{
delete chooser_button ;
delete popup_menu ;
}
puaChooser ( int _x1, int _y1, int _x2, int _y2, char *legend ) ;
void add_item ( char *str, puCallback _cb, void *_user_data = NULL ) ;
void close () ;
void popup_cb () ;
void menuCleanup ( const char *s ) ;
void hide () { chooser_button -> hide () ; popup_menu -> hide () ; }
void reveal () { chooser_button -> reveal () ; popup_menu -> hide () ; }
static void menuCleanup ( puObject * ) ;
} ;
/**
* A scrolling list for PUI.
*
* Believe it or not, PUI does not have one of these.
*
* This widget consists of a puListBox, a slider and two
* arrow buttons. This makes the ListBox scrollable,
* very handy if the box is too small to show all items
* at once.
*
* (Original code taken from FlightGear 0.9.6 sources,
* modified by Jan Reucker)
*/
class puaList : public puGroup
{
UL_TYPE_DATA
char ** _contents;
puFrame * _frame;
puSlider * _slider;
puArrowButton * _up_arrow;
puArrowButton * _down_arrow;
int _style;
int _sw; // slider width
int _width, _height;
protected:
virtual void init (int w, int h, short transparent);
puListBox * _list_box;
public:
puaList (int x, int y, int w, int h, int sl_width = 20);
puaList (int x, int y, int w, int h, char ** contents, int sl_width = 20);
puaList (int x, int y, int w, int h, short transparent, int sl_width = 20);
puaList (int x, int y, int w, int h, short transparent, char ** contents, int sl_width = 20);
virtual ~puaList ();
virtual void newList (char ** contents);
virtual char * getStringValue ();
virtual int getIntegerValue ();
virtual void getValue (char **ps);
virtual void getValue (int *i);
virtual void setColourScheme (float r, float g, float b, float a);
virtual void setColour (int which, float r, float g, float b, float a);
virtual void setSize (int w, int h);
int checkHit ( int button, int updown, int x, int y );
int getNumVisible ( void ) const { return _list_box->getNumVisible(); }
int getNumItems ( void ) const { return _list_box->getNumItems(); }
int getTopItem ( void ) const { return _list_box->getTopItem(); }
void setTopItem ( int item_index );
};
#endif