Updated mouse gui tweaks and Jim's nifty new external view controls.
This commit is contained in:
parent
d227398525
commit
a3bce2f219
8 changed files with 856 additions and 40 deletions
|
@ -12,6 +12,7 @@ libGUI_a_SOURCES = \
|
|||
gui_local.cxx gui_local.hxx \
|
||||
mouse.cxx \
|
||||
$(NETWORK_SRCS) \
|
||||
prop_picker.cxx prop_picker.hxx \
|
||||
sgVec3Slider.cxx sgVec3Slider.hxx \
|
||||
trackball.c trackball.h
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
#include "apt_dlg.hxx"
|
||||
#include "net_dlg.hxx"
|
||||
#include "sgVec3Slider.hxx"
|
||||
#include "prop_picker.hxx"
|
||||
|
||||
SG_USING_STD(string);
|
||||
|
||||
|
@ -882,12 +883,14 @@ puCallback editSubmenuCb [] = {
|
|||
|
||||
extern void fgHUDalphaAdjust( puObject * );
|
||||
char *viewSubmenu [] = {
|
||||
"Properties",
|
||||
"HUD Alpha",
|
||||
"Pilot Offset",
|
||||
/* "Cockpit View > ", "View >","------------", */
|
||||
"Toggle Panel...", NULL
|
||||
};
|
||||
puCallback viewSubmenuCb [] = {
|
||||
prop_pickerView,
|
||||
fgHUDalphaAdjust,
|
||||
PilotOffsetAdjust,
|
||||
/* notCb, notCb, NULL, */
|
||||
|
|
|
@ -21,6 +21,7 @@ typedef enum {
|
|||
} MouseMode;
|
||||
|
||||
extern MouseMode mouse_mode;
|
||||
extern int gui_menu_on;
|
||||
|
||||
extern float lastGuiQuat[4];
|
||||
extern float curGuiQuat[4];
|
||||
|
|
|
@ -199,7 +199,7 @@ void TurnCursorOff( void )
|
|||
|
||||
void maybeToggleMouse( void )
|
||||
{
|
||||
#if defined(WIN32_CURSOR_TWEAKS)
|
||||
#if defined(WIN32_CURSOR_TWEAKS_OFF)
|
||||
static int first_time = ~0;
|
||||
static int mouse_changed = 0;
|
||||
|
||||
|
@ -265,7 +265,20 @@ void guiMotionFunc ( int x, int y )
|
|||
float W, H;
|
||||
double offset;
|
||||
|
||||
ww = fgGetInt("/sim/startup/xsize");
|
||||
wh = fgGetInt("/sim/startup/ysize");
|
||||
|
||||
if (mouse_mode == MOUSE_POINTER) {
|
||||
// TURN MENU ON IF MOUSE AT TOP
|
||||
if( y < 2 ) {
|
||||
if( !gui_menu_on )
|
||||
guiToggleMenu();
|
||||
}
|
||||
// TURN MENU OFF IF MOUSE AT BOTTOM
|
||||
else if( y > wh-2 ) {
|
||||
if( gui_menu_on )
|
||||
guiToggleMenu();
|
||||
}
|
||||
puMouse ( x, y ) ;
|
||||
glutPostRedisplay () ;
|
||||
} else {
|
||||
|
@ -275,9 +288,6 @@ void guiMotionFunc ( int x, int y )
|
|||
// reset left click MOUSE_VIEW toggle feature
|
||||
_mVtoggle = 0;
|
||||
|
||||
ww = fgGetInt("/sim/startup/xsize");
|
||||
wh = fgGetInt("/sim/startup/ysize");
|
||||
|
||||
switch (mouse_mode) {
|
||||
case MOUSE_YOKE:
|
||||
if( !mouse_joystick_control ) {
|
||||
|
|
575
src/GUI/prop_picker.cxx
Executable file
575
src/GUI/prop_picker.cxx
Executable file
|
@ -0,0 +1,575 @@
|
|||
/*
|
||||
|
||||
Adapted by Jim Wilson, beginning Sept 2001 (FG v 0.79)
|
||||
|
||||
**** Insert FlightGear GPL here.
|
||||
|
||||
Based on puFilePicker from:
|
||||
|
||||
********
|
||||
PLIB - A Suite of Portable Game Libraries
|
||||
Copyright (C) 2001 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
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
For further information visit http://plib.sourceforge.net
|
||||
|
||||
$Id$
|
||||
********
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include "prop_picker.hxx"
|
||||
#include <Main/globals.hxx>
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
||||
#define DOTDOTSLASH "../"
|
||||
#define SLASH "/"
|
||||
|
||||
string name, line, value;
|
||||
|
||||
static puObject *PP_widget = 0;
|
||||
|
||||
// widget location and size...
|
||||
#define PROPPICK_X 100
|
||||
#define PROPPICK_Y 200
|
||||
#define PROPPICK_W 500
|
||||
#define PROPPICK_H 300
|
||||
|
||||
static puObject *PE_widget = 0;
|
||||
|
||||
void prop_pickerInit()
|
||||
{
|
||||
if( PP_widget == 0 ) {
|
||||
fgPropPicker *PP = new fgPropPicker ( PROPPICK_X, PROPPICK_Y, PROPPICK_W, PROPPICK_H, 1, "/", "FG Properties");
|
||||
PP_widget = PP;
|
||||
}
|
||||
}
|
||||
|
||||
void prop_pickerView( puObject * )
|
||||
{
|
||||
if( PP_widget == 0 ) {
|
||||
prop_pickerInit();
|
||||
}
|
||||
fgPropPicker *me = (fgPropPicker *)PP_widget -> getUserData();
|
||||
// refresh
|
||||
me -> find_props();
|
||||
FG_PUSH_PUI_DIALOG( me );
|
||||
}
|
||||
|
||||
void prop_pickerRefresh()
|
||||
{
|
||||
if( PP_widget == 0 ) {
|
||||
prop_pickerInit();
|
||||
}
|
||||
fgPropPicker *me = (fgPropPicker *)PP_widget -> getUserData();
|
||||
me -> find_props();
|
||||
}
|
||||
|
||||
void prop_editInit(char * name, char * value, char * proppath)
|
||||
{
|
||||
if( PE_widget == 0 ) {
|
||||
fgPropEdit *PP = new fgPropEdit ( name, value, proppath );
|
||||
PE_widget = PP;
|
||||
}
|
||||
}
|
||||
|
||||
void prop_editOpen( char * name, char * value, char * proppath )
|
||||
{
|
||||
if( PE_widget == 0 ) {
|
||||
prop_editInit( name, value, proppath );
|
||||
}
|
||||
fgPropEdit *me = (fgPropEdit *)PE_widget -> getUserData();
|
||||
me -> propname -> setLabel (name);
|
||||
me -> propinput -> setValue (value);
|
||||
strcpy(me -> propPath, proppath);
|
||||
me -> propinput -> acceptInput ();
|
||||
FG_PUSH_PUI_DIALOG( me );
|
||||
}
|
||||
|
||||
// return a human readable form of the value "type"
|
||||
static string getValueTypeString( const SGPropertyNode *node ) {
|
||||
string result;
|
||||
|
||||
if ( node == NULL ) {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
SGPropertyNode::Type type = node->getType();
|
||||
if ( type == SGPropertyNode::UNSPECIFIED ) {
|
||||
result = "unspecified";
|
||||
} else if ( type == SGPropertyNode::NONE ) {
|
||||
result = "none";
|
||||
} else if ( type == SGPropertyNode::BOOL ) {
|
||||
result = "bool";
|
||||
} else if ( type == SGPropertyNode::INT ) {
|
||||
result = "int";
|
||||
} else if ( type == SGPropertyNode::LONG ) {
|
||||
result = "long";
|
||||
} else if ( type == SGPropertyNode::FLOAT ) {
|
||||
result = "float";
|
||||
} else if ( type == SGPropertyNode::DOUBLE ) {
|
||||
result = "double";
|
||||
} else if ( type == SGPropertyNode::STRING ) {
|
||||
result = "string";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void fgPropPicker::fgPropPickerHandleSlider ( puObject * slider )
|
||||
{
|
||||
float val ;
|
||||
slider -> getValue ( &val ) ;
|
||||
val = 1.0f - val ;
|
||||
|
||||
puListBox* list_box = (puListBox*) slider -> getUserData () ;
|
||||
int index = int ( list_box -> getNumItems () * val ) ;
|
||||
list_box -> setTopItem ( index ) ;
|
||||
}
|
||||
|
||||
void fgPropPicker::fgPropPickerHandleArrow ( puObject *arrow )
|
||||
{
|
||||
puSlider *slider = (puSlider *) arrow->getUserData () ;
|
||||
puListBox* list_box = (puListBox*) slider -> getUserData () ;
|
||||
|
||||
int type = ((puArrowButton *)arrow)->getArrowType() ;
|
||||
int inc = ( type == PUARROW_DOWN ) ? 1 :
|
||||
( type == PUARROW_UP ) ? -1 :
|
||||
( type == PUARROW_FASTDOWN ) ? 10 :
|
||||
( type == PUARROW_FASTUP ) ? -10 : 0 ;
|
||||
|
||||
float val ;
|
||||
slider -> getValue ( &val ) ;
|
||||
val = 1.0f - val ;
|
||||
int num_items = list_box->getNumItems () - 1 ;
|
||||
if ( num_items > 0 )
|
||||
{
|
||||
int index = int ( num_items * val + 0.5 ) + inc ;
|
||||
if ( index > num_items ) index = num_items ;
|
||||
if ( index < 0 ) index = 0 ;
|
||||
|
||||
slider -> setValue ( 1.0f - (float)index / num_items ) ;
|
||||
list_box -> setTopItem ( index ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void fgPropPicker::chop_file ( char *fname )
|
||||
{
|
||||
/* removes everything back to the last '/' */
|
||||
|
||||
for ( int i = strlen(fname)-1 ; fname[i] != SLASH[0] && i >= 0 ; i-- )
|
||||
fname[i] = '\0' ;
|
||||
}
|
||||
|
||||
|
||||
void fgPropPicker::go_up_one_directory ( char *fname )
|
||||
{
|
||||
/* removes everything back to the last but one '/' */
|
||||
|
||||
chop_file ( fname ) ;
|
||||
|
||||
if ( strlen ( fname ) == 0 )
|
||||
{
|
||||
/* Empty string! The only way to go up is to append a "../" */
|
||||
|
||||
strcpy ( fname, DOTDOTSLASH ) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
/* If the last path element is a "../" then we'll have to add another "../" */
|
||||
|
||||
if ( strcmp ( & fname [ strlen(fname)-3 ], DOTDOTSLASH ) == 0 )
|
||||
{
|
||||
if ( strlen ( fname ) + 4 >= PUSTRING_MAX )
|
||||
{
|
||||
ulSetError ( UL_WARNING, "PUI: fgPropPicker - path is too long, max is %d.",
|
||||
PUSTRING_MAX ) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
strcat ( fname, DOTDOTSLASH ) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
/* Otherwise, just delete the last element of the path. */
|
||||
|
||||
/* Remove the trailing slash - then remove the rest as if it was a file name */
|
||||
|
||||
fname [ strlen(fname)-1 ] = '\0' ;
|
||||
chop_file ( fname ) ;
|
||||
}
|
||||
|
||||
|
||||
void fgPropPicker::handle_select ( puObject* list_box )
|
||||
{
|
||||
fgPropPicker* prop_picker = (fgPropPicker*) list_box -> getUserData () ;
|
||||
|
||||
int selected ;
|
||||
list_box -> getValue ( &selected ) ;
|
||||
|
||||
if ( selected >= 0 && selected < prop_picker -> num_files )
|
||||
{
|
||||
char *dst = prop_picker -> startDir ;
|
||||
char *src = prop_picker -> files [ selected ] ;
|
||||
|
||||
if ( strcmp ( src, "." ) == 0 )
|
||||
{
|
||||
/* Do nothing - but better refresh anyway. */
|
||||
|
||||
prop_picker -> find_props () ;
|
||||
return ;
|
||||
}
|
||||
|
||||
printf("select got here 2\n");
|
||||
if ( strcmp ( src, ".." ) == 0 )
|
||||
{
|
||||
/* Do back up one level - so refresh. */
|
||||
|
||||
go_up_one_directory ( dst ) ;
|
||||
prop_picker -> find_props () ;
|
||||
return ;
|
||||
}
|
||||
|
||||
if ( prop_picker -> dflag [ selected ] )
|
||||
{
|
||||
/* If this is a directory - then descend into it and refresh */
|
||||
|
||||
if ( strlen ( dst ) + strlen ( src ) + 2 >= PUSTRING_MAX )
|
||||
{
|
||||
ulSetError ( UL_WARNING,
|
||||
"PUI: fgPropPicker - path is too long, max is %d.", PUSTRING_MAX ) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
strcat ( dst, src ) ; /* add path to descend to */
|
||||
prop_picker -> find_props () ;
|
||||
return ;
|
||||
}
|
||||
|
||||
/* If this is a regular file - then just append it to the string */
|
||||
|
||||
if ( strlen ( dst ) + strlen ( src ) + 2 >= PUSTRING_MAX )
|
||||
{
|
||||
ulSetError ( UL_WARNING,
|
||||
"PUI: fgPropPicker - path is too long, max is %d.", PUSTRING_MAX ) ;
|
||||
return ;
|
||||
}
|
||||
prop_editOpen( prop_picker -> names [ selected ], prop_picker -> values [ selected ], dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
The user clicked on blank screen - maybe we should
|
||||
refresh just in case some other process created the
|
||||
file.
|
||||
*/
|
||||
|
||||
prop_picker -> find_props () ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void fgPropPicker::fgPropPickerHandleOk ( puObject* b )
|
||||
{
|
||||
fgPropPicker* prop_picker = (fgPropPicker*) b -> getUserData () ;
|
||||
|
||||
/* nothing to do, just hide */
|
||||
FG_POP_PUI_DIALOG( prop_picker );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
fgPropPicker::~fgPropPicker ()
|
||||
{
|
||||
if ( files )
|
||||
{
|
||||
for ( int i=0; i<num_files; i++ ) {
|
||||
delete files[i];
|
||||
delete names[i];
|
||||
delete values[i];
|
||||
}
|
||||
|
||||
delete[] files;
|
||||
delete[] names;
|
||||
delete[] values;
|
||||
delete[] dflag;
|
||||
}
|
||||
|
||||
if ( this == puActiveWidget () )
|
||||
puDeactivateWidget () ;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
fgPropPicker::fgPropPicker ( int x, int y, int w, int h, int arrows,
|
||||
const char *dir, const char *title ) : puDialogBox ( x,y )
|
||||
{
|
||||
puFont LegendFont, LabelFont;
|
||||
puGetDefaultFonts ( &LegendFont, &LabelFont );
|
||||
|
||||
files = NULL ;
|
||||
dflag = NULL ;
|
||||
names = NULL ;
|
||||
values = NULL ;
|
||||
num_files = 0 ;
|
||||
|
||||
strcpy ( startDir, dir ) ;
|
||||
printf ( "StartDirLEN=%i", strlen(startDir));
|
||||
if ( arrows > 2 ) arrows = 2 ;
|
||||
if ( arrows < 0 ) arrows = 0 ;
|
||||
arrow_count = arrows ;
|
||||
|
||||
frame = new puFrame ( 0, 0, w, h );
|
||||
|
||||
setUserData( this );
|
||||
|
||||
proppath = new puText (10, h-30);
|
||||
proppath -> setLabel (startDir);
|
||||
|
||||
slider = new puSlider (w-30,40+20*arrows,h-100-40*arrows,TRUE,20);
|
||||
slider->setDelta(0.1f);
|
||||
slider->setValue(1.0f);
|
||||
slider->setSliderFraction (0.2f) ;
|
||||
slider->setCBMode( PUSLIDER_DELTA );
|
||||
|
||||
list_box = new puListBox ( 10, 40, w-40, h-60 ) ;
|
||||
list_box -> setLabel ( title );
|
||||
list_box -> setLabelPlace ( PUPLACE_ABOVE ) ;
|
||||
list_box -> setStyle ( -PUSTYLE_SMALL_SHADED ) ;
|
||||
list_box -> setUserData ( this ) ;
|
||||
list_box -> setCallback ( handle_select ) ;
|
||||
list_box -> setValue ( 0 ) ;
|
||||
|
||||
find_props () ;
|
||||
|
||||
// printf("after Props files[1]=%s\n",files[1]);
|
||||
// printf("num items %i", list_box -> getNumItems ());
|
||||
|
||||
slider -> setUserData ( list_box ) ;
|
||||
slider -> setCallback ( fgPropPickerHandleSlider ) ;
|
||||
|
||||
ok_button = new puOneShot ( 10, 10, (w<170)?(w/2-5):80, 30 ) ;
|
||||
ok_button -> setLegend ( "Ok" ) ;
|
||||
ok_button -> setUserData ( this ) ;
|
||||
ok_button -> setCallback ( fgPropPickerHandleOk ) ;
|
||||
|
||||
if ( arrows > 0 )
|
||||
{
|
||||
puArrowButton *down_arrow = new puArrowButton ( w-30, 20+20*arrows, w-10, 40+20*arrows, PUARROW_DOWN ) ;
|
||||
down_arrow->setUserData ( slider ) ;
|
||||
down_arrow->setCallback ( fgPropPickerHandleArrow ) ;
|
||||
|
||||
puArrowButton *up_arrow = new puArrowButton ( w-30, h-30-20*arrows, w-10, h-10-20*arrows, PUARROW_UP ) ;
|
||||
up_arrow->setUserData ( slider ) ;
|
||||
up_arrow->setCallback ( fgPropPickerHandleArrow ) ;
|
||||
}
|
||||
|
||||
if ( arrows == 2 )
|
||||
{
|
||||
puArrowButton *down_arrow = new puArrowButton ( w-30, 40, w-10, 60, PUARROW_FASTDOWN ) ;
|
||||
down_arrow->setUserData ( slider ) ;
|
||||
down_arrow->setCallback ( fgPropPickerHandleArrow ) ;
|
||||
|
||||
puArrowButton *up_arrow = new puArrowButton ( w-30, h-50, w-10, h-30, PUARROW_FASTUP ) ;
|
||||
up_arrow->setUserData ( slider ) ;
|
||||
up_arrow->setCallback ( fgPropPickerHandleArrow ) ;
|
||||
}
|
||||
|
||||
FG_FINALIZE_PUI_DIALOG( this );
|
||||
printf("fgPropPicker - End of Init\n");
|
||||
}
|
||||
|
||||
|
||||
void fgPropPicker::find_props ()
|
||||
{
|
||||
|
||||
int pi;
|
||||
|
||||
if ( files != NULL )
|
||||
{
|
||||
for ( int i = 0 ; i < num_files ; i++ ) {
|
||||
delete files[i] ;
|
||||
delete names[i] ;
|
||||
delete values[i] ;
|
||||
}
|
||||
|
||||
delete [] files ;
|
||||
delete [] names ;
|
||||
delete [] values ;
|
||||
delete [] dflag ;
|
||||
}
|
||||
|
||||
num_files = 0 ;
|
||||
|
||||
char dir [ PUSTRING_MAX * 2 ] ;
|
||||
|
||||
int iindex = 0;
|
||||
char sindex [ 20 ];
|
||||
|
||||
strcpy ( dir, startDir ) ;
|
||||
|
||||
int i = 0 ;
|
||||
// printf("dir begin of find_props=%s\n",dir);
|
||||
// printf("len of dir=%i",strlen(dir));
|
||||
SGPropertyNode * node = globals->get_props()->getNode(dir);
|
||||
|
||||
printf("find_props: allocation of node\n");
|
||||
num_files = (int)node->nChildren();
|
||||
|
||||
// take off one for the trailing "null" in each SGProperty list
|
||||
num_files = num_files -1;
|
||||
|
||||
// instantiate string objects and add [.] and [..] for subdirs
|
||||
if (strcmp(dir,"/") == 0) {
|
||||
files = new char* [ num_files+1 ] ;
|
||||
names = new char* [ num_files+1 ] ;
|
||||
values = new char* [ num_files+1 ] ;
|
||||
dflag = new char [ num_files+1 ] ;
|
||||
pi = 0;
|
||||
} else {
|
||||
// add two for the .. and .
|
||||
num_files = num_files +2;
|
||||
// make room for .. and .
|
||||
files = new char* [ num_files+3 ] ;
|
||||
names = new char* [ num_files+3 ] ;
|
||||
values = new char* [ num_files+3 ] ;
|
||||
dflag = new char [ num_files+3 ] ;
|
||||
line = ".";
|
||||
files [ 0 ] = new char[ strlen(line.c_str())+2 ];
|
||||
strcpy ( files [ 0 ], line.c_str() );
|
||||
names [ 0 ] = new char[ 2 ];
|
||||
values[ 0 ] = new char[ 2 ] ;
|
||||
line = "..";
|
||||
dflag[ 0 ] = 1;
|
||||
files [ 1 ] = new char[ strlen(line.c_str())+2 ];
|
||||
strcpy ( files [ 1 ], line.c_str() );
|
||||
names [ 1 ] = new char[ 2 ];
|
||||
values[ 1 ] = new char[ 2 ] ;
|
||||
strcpy ( names [ 1 ], line.c_str() );
|
||||
|
||||
dflag[ 1 ] = 1;
|
||||
pi = 2;
|
||||
};
|
||||
|
||||
|
||||
for (int i = 0; i < (int)node->nChildren()-1; i++) {
|
||||
SGPropertyNode * child = node->getChild(i);
|
||||
name = child->getName();
|
||||
line = name;
|
||||
names[ pi ] = new char[ strlen(line.c_str())+2 ] ;
|
||||
strcpy ( names [ pi ], line.c_str() ) ;
|
||||
if ( child->nChildren() > 0 ) {
|
||||
iindex = child->getIndex();
|
||||
sprintf(sindex, "%d", iindex);
|
||||
dflag[ pi ] = 1 ;
|
||||
files[ pi ] = new char[ strlen(line.c_str())+strlen(sindex)+4 ] ;
|
||||
strcpy ( files [ pi ], line.c_str() ) ;
|
||||
strcat ( files [ pi ], "[" ) ;
|
||||
strcat ( files [ pi ], sindex ) ;
|
||||
strcat ( files [ pi ], "]/" ) ;
|
||||
values[ pi ] = new char[ 2 ] ;
|
||||
} else {
|
||||
dflag[ pi ] = 0 ;
|
||||
value = node->getStringValue ( name, "" );
|
||||
values[ pi ] = new char[ strlen(value.c_str())+2 ] ;
|
||||
strcpy ( values [pi], value.c_str() );
|
||||
line += " = '" + value + "' " + "(";
|
||||
line += getValueTypeString( node->getNode( name ) );
|
||||
line += ")";
|
||||
files[ pi ] = new char[ strlen(line.c_str())+2 ] ;
|
||||
strcpy ( files [ pi ], line.c_str() ) ;
|
||||
}
|
||||
printf("files->%i %s\n",pi, files [pi]);
|
||||
++pi;
|
||||
}
|
||||
|
||||
files [ num_files ] = NULL ;
|
||||
|
||||
printf("files pointer=%i\n", files);
|
||||
proppath -> setLabel (startDir);
|
||||
list_box -> newList ( files ) ;
|
||||
|
||||
}
|
||||
|
||||
void fgPropEdit::fgPropEditHandleCancel ( puObject* b )
|
||||
{
|
||||
fgPropEdit* prop_edit = (fgPropEdit*) b -> getUserData () ;
|
||||
FG_POP_PUI_DIALOG( prop_edit );
|
||||
}
|
||||
|
||||
void fgPropEdit::fgPropEditHandleOK ( puObject* b )
|
||||
{
|
||||
fgPropEdit* prop_edit = (fgPropEdit*) b -> getUserData () ;
|
||||
const char* tname;
|
||||
char* tvalue;
|
||||
|
||||
// use label text for property node to be updated
|
||||
tname = prop_edit -> propname -> getLabel();
|
||||
prop_edit -> propinput -> getValue( &tvalue );
|
||||
|
||||
SGPropertyNode * node = globals->get_props()->getNode(prop_edit -> propPath);
|
||||
node->getNode( prop_edit -> propname -> getLabel(), true)->setStringValue(tvalue);
|
||||
|
||||
// update the picker display so it shows new value
|
||||
prop_pickerRefresh();
|
||||
|
||||
FG_POP_PUI_DIALOG( prop_edit );
|
||||
}
|
||||
|
||||
fgPropEdit::fgPropEdit ( char *name, char *value, char *proppath ) : puDialogBox ( 0, 0 )
|
||||
|
||||
{
|
||||
puFont LegendFont, LabelFont;
|
||||
puGetDefaultFonts ( &LegendFont, &LabelFont );
|
||||
|
||||
// locate in relation to picker widget...
|
||||
int fx = PROPPICK_X;
|
||||
int fy = PROPPICK_Y + PROPPICK_H;
|
||||
frame = new puFrame (fx,fy, fx+500, fy+120);
|
||||
|
||||
strcpy (propPath, proppath);
|
||||
|
||||
setUserData( this );
|
||||
|
||||
propname = new puText (fx+10, fy+90);
|
||||
propname -> setLabel (name);
|
||||
|
||||
propinput = new puInput (fx+10, fy+50, fx+480, fy+80);
|
||||
propinput -> setValue (value);
|
||||
propinput -> acceptInput();
|
||||
|
||||
|
||||
ok_button = new puOneShot (fx+10, fy+10, fx+80, fy+30);
|
||||
ok_button -> setUserData (this);
|
||||
ok_button -> setLegend (gui_msg_OK);
|
||||
ok_button -> setCallback (fgPropEditHandleOK);
|
||||
ok_button -> makeReturnDefault(TRUE);
|
||||
|
||||
cancel_button = new puOneShot (fx+100, fy+10, fx+180, fy+30);
|
||||
cancel_button -> setUserData (this);
|
||||
cancel_button -> setLegend (gui_msg_CANCEL);
|
||||
cancel_button -> setCallback (fgPropEditHandleCancel);
|
||||
|
||||
FG_FINALIZE_PUI_DIALOG( this );
|
||||
}
|
||||
|
||||
|
86
src/GUI/prop_picker.hxx
Executable file
86
src/GUI/prop_picker.hxx
Executable file
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
prop_picker.hxx
|
||||
|
||||
*/
|
||||
|
||||
#include <plib/pu.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include "gui.h"
|
||||
|
||||
void prop_pickerInit();
|
||||
void prop_pickerView( puObject * );
|
||||
void prop_pickerRefresh();
|
||||
void prop_editInit(char * name, char * value );
|
||||
void prop_editOpen( char * name, char * value );
|
||||
|
||||
class fgPropPicker ;
|
||||
class fgPropEdit ;
|
||||
|
||||
class fgPropPicker : public puDialogBox
|
||||
{
|
||||
|
||||
static void handle_select ( puObject *b ) ;
|
||||
static void input_entered ( puObject *b ) ;
|
||||
static void fgPropPickerHandleSlider ( puObject * slider );
|
||||
static void fgPropPickerHandleArrow ( puObject *arrow );
|
||||
static void fgPropPickerHandleOk ( puObject* b );
|
||||
|
||||
char** files ;
|
||||
char** names ;
|
||||
char** values ;
|
||||
char* dflag ;
|
||||
int num_files ;
|
||||
int arrow_count ;
|
||||
char startDir [ PUSTRING_MAX * 2 ] ;
|
||||
|
||||
/* puInput *input ; */
|
||||
|
||||
protected:
|
||||
|
||||
puFrame *frame ;
|
||||
puListBox *list_box ;
|
||||
puSlider *slider ;
|
||||
puOneShot *cancel_button ;
|
||||
puOneShot *ok_button ;
|
||||
|
||||
|
||||
public:
|
||||
puText *proppath ;
|
||||
void find_props () ;
|
||||
fgPropPicker ( int x, int y, int w, int h, int arrows,
|
||||
const char *dir, const char *title = "Pick a file" ) ;
|
||||
|
||||
~fgPropPicker () {;}
|
||||
|
||||
static void go_up_one_directory ( char *fname ) ;
|
||||
static void chop_file ( char *fname ) ;
|
||||
|
||||
} ;
|
||||
|
||||
class fgPropEdit : public puDialogBox
|
||||
{
|
||||
|
||||
static void fgPropEditHandleCancel ( puObject *b ) ;
|
||||
static void fgPropEditHandleOK ( puObject* b );
|
||||
|
||||
protected:
|
||||
|
||||
puFrame *frame ;
|
||||
puOneShot *cancel_button ;
|
||||
puOneShot *ok_button ;
|
||||
|
||||
public:
|
||||
puText *propname ;
|
||||
puInput *propinput ;
|
||||
char propPath [ PUSTRING_MAX * 2 ] ;
|
||||
|
||||
fgPropEdit ( char *name, char *value, char *proppath ) ;
|
||||
|
||||
~fgPropEdit () {;}
|
||||
|
||||
static void go_up_one_directory ( char *fname ) ;
|
||||
static void chop_file ( char *fname ) ;
|
||||
|
||||
} ;
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
*/
|
||||
|
||||
#include "sgVec3Slider.hxx"
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <simgear/sg_inlines.h>
|
||||
|
||||
class FloatSlider : public puSlider
|
||||
|
@ -20,6 +21,7 @@ class FloatSlider : public puSlider
|
|||
|
||||
protected:
|
||||
float maxValue;
|
||||
float minValue;
|
||||
float origValue;
|
||||
float Adjust;
|
||||
float MyValue;
|
||||
|
@ -30,7 +32,7 @@ protected:
|
|||
char _text[16];
|
||||
public:
|
||||
FloatSlider ( int x, int y, int sz, float f, const char *title,
|
||||
float max = 90.0f );
|
||||
float max = 100.0f, float min = 0.0f);
|
||||
|
||||
~FloatSlider () {;}
|
||||
|
||||
|
@ -41,15 +43,21 @@ public:
|
|||
}
|
||||
|
||||
float get() { return( MyValue ); }
|
||||
void set() { MyValue = ((2.0*maxValue) * (TmpValue - 0.5f)) - maxValue; }
|
||||
|
||||
// calc actual "setting" by multiplying the pui fraction by highest value setable
|
||||
void set() { MyValue = maxValue * TmpValue; }
|
||||
|
||||
float *getTmp() { return( &TmpValue ); }
|
||||
void setTmp() { TmpValue += 0.5f; }
|
||||
|
||||
// double the range from -max <-> max
|
||||
// adjust the TmpValue back to 0 to 1 range of pui widget
|
||||
void setTmp() { TmpValue += 0.0f; }
|
||||
|
||||
// adjust actual "setting" value back to fraction for pui widget
|
||||
void init( float f ) {
|
||||
Adjust = 0.5f / maxValue;
|
||||
setValue((f * Adjust) + 0.5f);
|
||||
if (f > maxValue) f = maxValue;
|
||||
if (f < minValue) f = minValue;
|
||||
Adjust = 1.0f / maxValue;
|
||||
setValue(f * Adjust);
|
||||
adj( this );
|
||||
}
|
||||
|
||||
|
@ -69,10 +77,92 @@ void FloatSlider::adj( puObject *hs )
|
|||
}
|
||||
|
||||
FloatSlider::FloatSlider ( int x, int y, int sz, float f, const char *title,
|
||||
float max ) : puSlider( x, y, sz, FALSE )
|
||||
float max, float min ) : puSlider( x, y, sz, FALSE )
|
||||
{
|
||||
setUserData( this );
|
||||
maxValue = max;
|
||||
minValue = min;
|
||||
origValue = f;
|
||||
init(f);
|
||||
setDelta ( 0.01 );
|
||||
setCBMode ( PUSLIDER_DELTA ) ;
|
||||
setCallback ( adj ) ;
|
||||
strcpy ( _title, title);
|
||||
setLabel ( _title );
|
||||
setLabelPlace ( PUPLACE_LEFT );
|
||||
setLegend(_text);
|
||||
// setLegendPlace( PUPLACE_RIGHT );
|
||||
}
|
||||
|
||||
|
||||
class FloatDial : public puDial
|
||||
{
|
||||
|
||||
protected:
|
||||
float maxValue;
|
||||
float minValue;
|
||||
float origValue;
|
||||
float Adjust;
|
||||
float MyValue;
|
||||
float TmpValue;
|
||||
float SaveValue;
|
||||
char buf[8];
|
||||
char _title[32];
|
||||
char _text[16];
|
||||
public:
|
||||
FloatDial ( int x, int y, int sz, float f, const char *title,
|
||||
float max = 180.0f, float min = -180.0f );
|
||||
|
||||
~FloatDial () {;}
|
||||
|
||||
static void adj( puObject *);
|
||||
|
||||
void updateText() {
|
||||
sprintf( _text, "%05.2f", MyValue );
|
||||
}
|
||||
|
||||
float get() { return( MyValue ); }
|
||||
|
||||
// calc actual "setting" by multiplying the pui fraction by highest value setable
|
||||
// in this case we're also turning a 0 to 1 range into a -.05 to +.05 before converting
|
||||
void set() { MyValue = ((2.0*maxValue) * (TmpValue - 0.5f)) - maxValue; }
|
||||
|
||||
float *getTmp() { return( &TmpValue ); }
|
||||
|
||||
// adjust the TmpValue back to 0 to 1 range of pui widget
|
||||
void setTmp() { TmpValue += 0.5f; }
|
||||
|
||||
// adjust actual "setting" value back to fraction for pui widget
|
||||
// double the range from -max <-> max
|
||||
void init( float f ) {
|
||||
if (f > maxValue) f = maxValue;
|
||||
if (f < minValue) f = minValue;
|
||||
Adjust = 0.5f / maxValue;
|
||||
setValue((f * Adjust) + 0.5f);
|
||||
adj( this );
|
||||
}
|
||||
|
||||
void reinit() { init( origValue ); }
|
||||
void cancel() { MyValue = TmpValue; }
|
||||
void reset () { init( origValue ); }
|
||||
|
||||
};
|
||||
|
||||
void FloatDial::adj( puObject *hs )
|
||||
{
|
||||
FloatDial *dial = (FloatDial *)hs->getUserData();
|
||||
dial->getValue ( dial->getTmp() );
|
||||
dial->setTmp();
|
||||
dial->set();
|
||||
dial->updateText();
|
||||
}
|
||||
|
||||
FloatDial::FloatDial ( int x, int y, int sz, float f, const char *title,
|
||||
float max, float min ) : puDial( x, y, sz )
|
||||
{
|
||||
setUserData( this );
|
||||
maxValue = max;
|
||||
minValue = min;
|
||||
origValue = f;
|
||||
init(f);
|
||||
setDelta ( 0.01 );
|
||||
|
@ -96,9 +186,10 @@ class sgVec3Slider : public puDialogBox
|
|||
|
||||
protected:
|
||||
char Label[64];
|
||||
FloatSlider *HS0;
|
||||
FloatSlider *HS1;
|
||||
FloatDial *HS0;
|
||||
FloatDial *HS1;
|
||||
FloatSlider *HS2;
|
||||
puText *TitleText;
|
||||
puOneShot *OkButton;
|
||||
puOneShot *ResetButton;
|
||||
puOneShot *CancelButton;
|
||||
|
@ -114,17 +205,23 @@ public:
|
|||
|
||||
~sgVec3Slider () {;}
|
||||
|
||||
// ???
|
||||
// calc the property Vec with the actual point on sphere
|
||||
void setVec()
|
||||
{
|
||||
Vec3FromHeadingPitchRadius( Vec,
|
||||
(HS0->get() + 90) * 2,
|
||||
HS0->get(),
|
||||
HS1->get(),
|
||||
HS2->get() );
|
||||
HS2->get());
|
||||
}
|
||||
|
||||
sgVec3 *getVec() { setVec(); return &Vec; };
|
||||
// return the offset vector according to current widget values
|
||||
sgVec3 *getVec()
|
||||
{
|
||||
setVec();
|
||||
return &Vec;
|
||||
};
|
||||
|
||||
// save the Vector before pushing dialog (for cancel button)
|
||||
sgVec3 *getStashVec() { return &SaveVec; }
|
||||
void stashVec() {
|
||||
SaveVec[2] = HS0->get();
|
||||
|
@ -132,13 +229,15 @@ public:
|
|||
SaveVec[0] = HS2->get();
|
||||
}
|
||||
|
||||
FloatSlider *getHS0() { return HS0; }
|
||||
FloatSlider *getHS1() { return HS1; }
|
||||
// functions to return pointers to protected pui widget instances
|
||||
FloatDial *getHS0() { return HS0; }
|
||||
FloatDial *getHS1() { return HS1; }
|
||||
FloatSlider *getHS2() { return HS2; }
|
||||
|
||||
static void adjust(puObject *p_obj);
|
||||
};
|
||||
|
||||
// class constructor
|
||||
sgVec3Slider::sgVec3Slider ( int x, int y, sgVec3 vec, const char *title,
|
||||
const char *Xtitle,
|
||||
const char *Ytitle,
|
||||
|
@ -153,7 +252,6 @@ sgVec3Slider::sgVec3Slider ( int x, int y, sgVec3 vec, const char *title,
|
|||
labelW = SG_MAX2( labelW, LabelFont.getStringWidth(Ytitle));
|
||||
labelW = SG_MAX2( labelW, LabelFont.getStringWidth(Ztitle));
|
||||
|
||||
int DialogWidth = 300 + fudge + labelW;
|
||||
|
||||
sgCopyVec3(SaveVec, vec);
|
||||
sgCopyVec3(Vec, vec);
|
||||
|
@ -161,44 +259,53 @@ sgVec3Slider::sgVec3Slider ( int x, int y, sgVec3 vec, const char *title,
|
|||
|
||||
int nSliders = 3;
|
||||
int slider_x = 70+fudge;
|
||||
int slider_y = 55;
|
||||
int slider_width = 240;
|
||||
int slider_y = 75;
|
||||
int slider_width = 270;
|
||||
int dialer_x = 70+fudge;
|
||||
int dialer_y = 115;
|
||||
int dialer_size = 100;
|
||||
|
||||
int horiz_slider_height = LabelFont.getStringHeight()
|
||||
+ LabelFont.getStringDescender()
|
||||
+ PUSTR_TGAP + PUSTR_BGAP + 5;
|
||||
|
||||
int DialogWidth = slider_width + 20 + fudge + labelW;
|
||||
int DialogHeight = dialer_size + 115 + nSliders * horiz_slider_height;
|
||||
|
||||
// HACKS
|
||||
setUserData( this );
|
||||
horiz_slider_height += 10;
|
||||
|
||||
new puFrame ( 0, 0,
|
||||
DialogWidth,
|
||||
85 + nSliders * horiz_slider_height );
|
||||
new puFrame ( 0, 0, DialogWidth, DialogHeight );
|
||||
|
||||
setLabelPlace( PUPLACE_DEFAULT /*PUPLACE_CENTERED*/ );
|
||||
setLabel( Label );
|
||||
|
||||
HS2 = new FloatSlider ( slider_x, slider_y, slider_width, vec[2], Ztitle );
|
||||
slider_y += horiz_slider_height;
|
||||
/* heading */
|
||||
HS0 = new FloatDial ( dialer_x, dialer_y, dialer_size, vec[0], Xtitle, 180.0f, -180.0f );
|
||||
dialer_x = dialer_x + 170;
|
||||
|
||||
HS1 = new FloatSlider ( slider_x, slider_y, slider_width, vec[1], Ytitle );
|
||||
slider_y += horiz_slider_height;
|
||||
/* pitch */
|
||||
HS1 = new FloatDial ( dialer_x, dialer_y, dialer_size, vec[1], Ytitle, 89.99f, -89.99f );
|
||||
|
||||
HS0 = new FloatSlider ( slider_x, slider_y, slider_width, vec[0], Xtitle );
|
||||
/* radius */
|
||||
HS2 = new FloatSlider ( slider_x, slider_y, slider_width, vec[2], Ztitle, 100.0f, 0.0f );
|
||||
|
||||
OkButton = new puOneShot ( 70+fudge, 10, 120+fudge, 50 );
|
||||
TitleText = new puText( 130, DialogHeight - 40);
|
||||
TitleText->setLabel("Pilot Offset");
|
||||
|
||||
OkButton = new puOneShot ( 70+fudge, 20, 120+fudge, 50 );
|
||||
OkButton-> setUserData( this );
|
||||
OkButton-> setLegend ( gui_msg_OK );
|
||||
OkButton-> makeReturnDefault ( TRUE );
|
||||
OkButton-> setCallback ( goAway );
|
||||
|
||||
CancelButton = new puOneShot ( 130+fudge, 10, 210+fudge, 50 );
|
||||
CancelButton = new puOneShot ( 130+fudge, 20, 210+fudge, 50 );
|
||||
CancelButton-> setUserData( this );
|
||||
CancelButton-> setLegend ( gui_msg_CANCEL );
|
||||
CancelButton-> setCallback ( cancel );
|
||||
|
||||
ResetButton = new puOneShot ( 220+fudge, 10, 280+fudge, 50 );
|
||||
ResetButton = new puOneShot ( 220+fudge, 20, 280+fudge, 50 );
|
||||
ResetButton-> setUserData( this );
|
||||
ResetButton-> setLegend ( gui_msg_RESET );
|
||||
ResetButton-> setCallback ( reset );
|
||||
|
@ -206,7 +313,6 @@ sgVec3Slider::sgVec3Slider ( int x, int y, sgVec3 vec, const char *title,
|
|||
FG_FINALIZE_PUI_DIALOG( this );
|
||||
}
|
||||
|
||||
|
||||
void sgVec3Slider::goAway(puObject *p_obj)
|
||||
{
|
||||
sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
|
||||
|
@ -255,7 +361,11 @@ static puObject *PO_vec = 0;
|
|||
|
||||
void PilotOffsetInit() {
|
||||
sgVec3 v;
|
||||
sgSetVec3(v,0.0,0.0,20.0);
|
||||
sgSetVec3(v,
|
||||
fgGetFloat("/sim/view[1]/default/pilot-offset/heading-deg"),
|
||||
fgGetFloat("/sim/view[1]/default/pilot-offset/pitch-deg"),
|
||||
fgGetFloat("/sim/view[1]/default/pilot-offset/radius-m")
|
||||
);
|
||||
PilotOffsetInit(v);
|
||||
}
|
||||
|
||||
|
@ -279,6 +389,7 @@ void PilotOffsetAdjust( puObject * )
|
|||
FG_PUSH_PUI_DIALOG( me );
|
||||
}
|
||||
|
||||
// external to get pilot offset vector for viewer
|
||||
sgVec3 *PilotOffsetGet()
|
||||
{
|
||||
if( PO_vec == 0 ) {
|
||||
|
@ -288,10 +399,37 @@ sgVec3 *PilotOffsetGet()
|
|||
return( me -> getVec() );
|
||||
}
|
||||
|
||||
// external function used to tie to FG properties
|
||||
float PilotOffsetGetSetting(int opt)
|
||||
{
|
||||
float setting;
|
||||
if( PO_vec == 0 ) {
|
||||
PilotOffsetInit();
|
||||
}
|
||||
sgVec3Slider *me = (sgVec3Slider *)PO_vec -> getUserData();
|
||||
if( opt == 0 ) setting = me -> getHS0() -> get();
|
||||
if( opt == 1 ) setting = me -> getHS1() -> get();
|
||||
if( opt == 2 ) setting = me-> getHS2() -> get();
|
||||
return( setting );
|
||||
}
|
||||
|
||||
// Heading == longitude of point on sphere
|
||||
// Pitch == latitude of point on sphere
|
||||
// Radius == radius of sphere
|
||||
// external function used to tie to FG properties
|
||||
void PilotOffsetSet(int opt, float setting)
|
||||
{
|
||||
if( PO_vec == 0 ) {
|
||||
PilotOffsetInit();
|
||||
}
|
||||
sgVec3Slider *me = (sgVec3Slider *)PO_vec -> getUserData();
|
||||
if( opt == 0 ) me -> getHS0() -> init( setting );
|
||||
if( opt == 1 ) me -> getHS1() -> init( setting );
|
||||
if( opt == 2 ) me-> getHS2() -> init( setting );
|
||||
}
|
||||
|
||||
|
||||
// Calculate vector of point on sphere:
|
||||
// input Heading == longitude of point on sphere
|
||||
// input Pitch == latitude of point on sphere
|
||||
// input Radius == radius of sphere
|
||||
|
||||
#define MIN_VIEW_OFFSET 5.0
|
||||
void Vec3FromHeadingPitchRadius ( sgVec3 vec3, float heading, float pitch,
|
||||
|
|
|
@ -20,5 +20,7 @@ void PilotOffsetAdjust( puObject * );
|
|||
void Vec3FromHeadingPitchRadius( sgVec3 vec3, float heading, float pitch, float radius );
|
||||
//void PilotOffsetGet( float *po );
|
||||
sgVec3 *PilotOffsetGet();
|
||||
void PilotOffsetSet( int opt, float setting);
|
||||
float PilotOffsetGetSetting( int opt );
|
||||
|
||||
#endif // _VEC3_SLIDER_H
|
||||
|
|
Loading…
Add table
Reference in a new issue