945 lines
29 KiB
C++
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
|
|
|