diff options
Diffstat (limited to 'app/bin/chotbar.c')
-rw-r--r-- | app/bin/chotbar.c | 485 |
1 files changed, 485 insertions, 0 deletions
diff --git a/app/bin/chotbar.c b/app/bin/chotbar.c new file mode 100644 index 0000000..b430f61 --- /dev/null +++ b/app/bin/chotbar.c @@ -0,0 +1,485 @@ +/* + * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/bin/chotbar.c,v 1.4 2009-10-15 03:54:32 dspagnol Exp $ + * + * HOT BAR + * + */ + +/* XTrkCad - Model Railroad CAD + * Copyright (C) 2005 Dave Bullis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <ctype.h> +#include "track.h" +#include "compound.h" + +#include <stdint.h> + +EXPORT DIST_T curBarScale = -1; +EXPORT long hotBarLabels = 0; + +#include "bitmaps/hotbarl.xbm" +#include "bitmaps/hotbarr.xbm" + +static wButton_p hotBarLeftB = NULL; +static wButton_p hotBarRightB = NULL; +static wMenu_p hotbarPopupM; +static wMenuList_p hotBarML = NULL; +static wIndex_t hotBarMLcnt = 0; +static drawCmd_t hotBarD = { + NULL, + &screenDrawFuncs, + 0, + 1.0, + 0.0, + {0.0, 0.0}, {0.0, 0.0}, + Pix2CoOrd, CoOrd2Pix }; +static wPos_t hotBarDrawHeight = 28; +static wPos_t hotBarHeight = 28; +typedef struct { + DIST_T x; + DIST_T w; + DIST_T objectW; + DIST_T labelW; + coOrd size; + coOrd orig; + BOOL_T isTrack; + void * context; + hotBarProc_t proc; + DIST_T barScale; + } hotBarMap_t; +static dynArr_t hotBarMap_da; +#define hotBarMap(N) DYNARR_N( hotBarMap_t, hotBarMap_da, N ) +static int hotBarCurrSelects[2] = { -1, -1 }; +static int hotBarCurrStarts[2] = { -1, -1 }; +static int hotBarCurrEnds[2] = { -1, -1 }; +#define hotBarCurrSelect (hotBarCurrSelects[programMode]) +#define hotBarCurrStart (hotBarCurrStarts[programMode]) +#define hotBarCurrEnd (hotBarCurrEnds[programMode]) +static DIST_T hotBarWidth = 0.0; + +static void HotBarHighlight( int inx ) +{ + wPos_t x0; + if ( inx >= hotBarCurrStart && inx < hotBarCurrEnd ) { + x0 = (wPos_t)((hotBarMap(inx).x-hotBarMap((int)hotBarCurrStart).x)*hotBarD.dpi+2); + wDrawFilledRectangle( hotBarD.d, x0, 0, (wPos_t)(hotBarMap(inx).w*hotBarD.dpi-2), hotBarHeight, wDrawColorBlack, wDrawOptTemp ); + } +} + + +static wFont_p hotBarFp = NULL; +static wFontSize_t hotBarFs = 8; + +static void RedrawHotBar( wDraw_p dd, void * data, wPos_t w, wPos_t h ) +{ + DIST_T hh = (double)hotBarDrawHeight/hotBarD.dpi; + coOrd orig; + int inx; + hotBarMap_t * tbm; + DIST_T barHeight = (DIST_T)(wControlGetHeight( (wControl_p)hotBarD.d ) - 2)/hotBarD.dpi; + DIST_T barWidth = (DIST_T)(wControlGetWidth( (wControl_p)hotBarD.d ) - 2)/hotBarD.dpi; + DIST_T barScale; + DIST_T x; + + wDrawClear( hotBarD.d ); + wControlActive( (wControl_p)hotBarLeftB, hotBarCurrStart > 0 ); + if (hotBarCurrStart < 0) { + wControlActive( (wControl_p)hotBarRightB, FALSE ); + return; + } + if ( hotBarLabels && !hotBarFp ) + hotBarFp = wStandardFont( F_HELV, FALSE, FALSE ); + for ( inx=hotBarCurrStart; inx < hotBarMap_da.cnt; inx++ ) { + tbm = &hotBarMap(inx); + barScale = tbm->barScale; + x = tbm->x - hotBarMap(hotBarCurrStart).x + 2.0/hotBarD.dpi; + if ( x + tbm->w > barWidth ) { + break; + } + orig.y = hh/2.0*barScale - tbm->size.y/2.0 - tbm->orig.y; + if ( hotBarLabels ) { + orig.y += 8/hotBarD.dpi*barScale; + if ( tbm->labelW > tbm->objectW ) { + x += (tbm->labelW-tbm->objectW)/2; + } + } + x *= barScale; + orig.x = x - tbm->orig.x; + hotBarD.scale = barScale; + hotBarD.size.x = barWidth*barScale; + hotBarD.size.y = barHeight*barScale; + tbm->proc( HB_DRAW, tbm->context, &hotBarD, &orig ); + if ( hotBarLabels ) { + orig.x = x - (tbm->labelW-tbm->objectW)/2*barScale; + orig.y = 2*barScale/hotBarD.dpi; + DrawString( &hotBarD, orig, 0.0, tbm->proc( HB_BARTITLE, tbm->context, NULL, NULL ), hotBarFp, hotBarFs*barScale, drawColorBlack ); + } + } + hotBarCurrEnd = inx; + if (hotBarCurrSelect >= hotBarCurrStart && hotBarCurrSelect < hotBarCurrEnd ) + HotBarHighlight( hotBarCurrSelect ); +/* else + hotBarCurrSelect = -1;*/ + wControlActive( (wControl_p)hotBarRightB, hotBarCurrEnd < hotBarMap_da.cnt ); + wPrefSetInteger( "misc", "hotbar-start", hotBarCurrStart ); +} + + +static void DoHotBarRight( void * data ) +{ + DIST_T barWidth = ((DIST_T)wControlGetWidth( (wControl_p)hotBarD.d ) - 2.0)/hotBarD.dpi; + int inx = hotBarCurrStart; + DIST_T lastX = hotBarMap(hotBarMap_da.cnt-1).x + hotBarMap(hotBarMap_da.cnt-1).w + 2.0/hotBarD.dpi; + if (MyGetKeyState()&WKEY_SHIFT) { + inx += hotBarMap_da.cnt/8; + } else { + inx++; + } + if ( inx >= hotBarMap_da.cnt ) + inx = hotBarMap_da.cnt-1; + while ( inx > 1 && lastX - hotBarMap(inx-1).x <= barWidth ) + inx--; + if ( inx != hotBarCurrStart ) { + hotBarCurrStart = inx; + RedrawHotBar( hotBarD.d, NULL, 0, 0 ); + } +} + + +static void DoHotBarLeft( void * data ) +{ + int inx = hotBarCurrStart; + if (MyGetKeyState()&WKEY_SHIFT) { + inx -= hotBarMap_da.cnt/8; + } else { + inx --; + } + if ( inx < 0 ) + inx = 0; + if ( inx != hotBarCurrStart ) { + hotBarCurrStart = inx; + RedrawHotBar( hotBarD.d, NULL, 0, 0 ); + } +} + + +static void DoHotBarJump( int inx ) +{ + DIST_T x, barWidth; + + inx -= '0'; + if (inx < 0 || inx > 9) + return; + if (inx == 0) + inx = 9; + else + inx--; + barWidth = (DIST_T)wControlGetWidth( (wControl_p)hotBarD.d )/hotBarD.dpi; + x = (inx*(hotBarWidth-barWidth))/9.0; + for ( inx=0; inx<hotBarMap_da.cnt; inx++ ) { + if (x <= hotBarMap(inx).x) + break; + } + if ( hotBarCurrStart != inx ) { + hotBarCurrStart = inx; + RedrawHotBar( NULL, NULL, 0, 0 ); + } +} + + +static void SelectHotBar( wDraw_p d, void * context, wAction_t action, wPos_t w, wPos_t h ) +{ + int inx; + coOrd pos; + DIST_T x; + wPos_t px; + hotBarMap_t * tbm; + char * titleP; + + if ( hotBarMap_da.cnt <= 0 ) + return; +#if 0 + if ( !CommandEnabled( hotBarCmdInx ) ) + return; +#endif + if ( (action&0xFF) == wActionRUp ) { + wMenuPopupShow( hotbarPopupM ); + return; + } + x = w/hotBarD.dpi + hotBarMap(hotBarCurrStart).x; + for ( inx=hotBarCurrStart; inx<hotBarCurrEnd; inx++ ) { + if ( x < hotBarMap(inx).x + hotBarMap(inx).w ) { + break; + } + } + if (inx >= hotBarCurrEnd) + return; + tbm = &hotBarMap(inx); + px = (wPos_t)((tbm->x-hotBarMap(hotBarCurrStart).x)*hotBarD.dpi); + px += (wPos_t)(tbm->w*hotBarD.dpi/2); + titleP = tbm->proc( HB_LISTTITLE, tbm->context, NULL, NULL ); + px -= wLabelWidth( titleP ) / 2; + wControlSetBalloon( (wControl_p)hotBarD.d, px, -5, titleP ); + switch (action & 0xff) { + case wActionLDown: + pos.x = mainD.size.x+mainD.orig.x; + pos.y = mainD.size.y+mainD.orig.y; + if ( hotBarCurrSelect >= 0 ) { + HotBarHighlight( hotBarCurrSelect ); + hotBarCurrSelect = -1; + } + tbm->proc( HB_SELECT, tbm->context, NULL, NULL ); + hotBarCurrSelect = inx; + HotBarHighlight( hotBarCurrSelect ); + if (recordF) { + fprintf( recordF, "HOTBARSELECT %s\n", tbm->proc( HB_FULLTITLE, tbm->context, NULL, NULL ) ); + } + FakeDownMouseState(); + break; + case wActionExtKey: + switch ((wAccelKey_e)(action>>8)) { + case wAccelKey_Right: + DoHotBarRight(NULL); + break; + case wAccelKey_Left: + DoHotBarLeft(NULL); + break; + case wAccelKey_Up: + break; + case wAccelKey_Down: + break; + default: + break; + } + break; + case wActionText: + switch (action >> 8) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + DoHotBarJump( action >> 8 ); + break; + case 0x1B: + ConfirmReset(FALSE); + break; + } + break; + } +} + + +EXPORT void HotBarCancel( void ) +{ + if ( hotBarCurrSelect >= 0 ) + HotBarHighlight( hotBarCurrSelect ); + hotBarCurrSelect = -1; +} + + +static BOOL_T HotBarSelectPlayback( char * line ) +{ + int inx; + hotBarMap_t * tbm; + while (*line && isspace(*line) ) line++; + for ( inx=0; inx<hotBarMap_da.cnt; inx++ ) { + tbm = &hotBarMap(inx); + if ( strcmp( tbm->proc( HB_FULLTITLE, tbm->context, NULL, NULL ), line) == 0) { + if ( hotBarCurrSelect >= 0 ) { + HotBarHighlight( hotBarCurrSelect ); + } + hotBarCurrSelect = inx; + if ( hotBarCurrSelect < hotBarCurrStart || hotBarCurrSelect > hotBarCurrEnd ) { + hotBarCurrStart = hotBarCurrSelect; + RedrawHotBar( hotBarD.d, NULL, 0, 0 ); + } + HotBarHighlight( hotBarCurrSelect ); + hotBarMap(inx).proc( HB_SELECT, hotBarMap(inx).context, NULL, NULL ); + FakeDownMouseState(); + return TRUE; + } + } + return FALSE; +} + + +static void HotbarJump( int inx, const char * name, void * arg ) +{ + hotBarCurrStart = (int)(long)arg; + RedrawHotBar( hotBarD.d, NULL, 0, 0 ); +} + + +static BOOL_T SetHotBarScale( char * line ) +{ + curBarScale = atof( line + 9 ); + return TRUE; +} + + +static char curContentsLabel[STR_SHORT_SIZE]; +EXPORT void AddHotBarElement( + char * contentsLabel, + coOrd size, + coOrd orig, + BOOL_T isTrack, + DIST_T barScale, + void * context, + hotBarProc_t proc_p ) +{ + hotBarMap_t * tbm; + coOrd textsize; + + if ( contentsLabel && strncmp(contentsLabel, curContentsLabel, sizeof curContentsLabel) != 0 ) { + wMenuListAdd( hotBarML, hotBarMLcnt++, contentsLabel, (void*)(intptr_t)hotBarMap_da.cnt ); + strncpy( curContentsLabel, contentsLabel, sizeof curContentsLabel ); + } + + if (barScale <= 0) { + if (isTrack) + barScale = (trackGauge>0.1)?trackGauge*24:10; + else + barScale = size.y/((double)hotBarDrawHeight/hotBarD.dpi-0.07); + } + DYNARR_APPEND( hotBarMap_t, hotBarMap_da, 10 ); + tbm = &hotBarMap(hotBarMap_da.cnt-1); + if (barScale < 1) + barScale = 1; + if (size.x > barScale) + barScale = size.x; + tbm->context = context; + tbm->size = size; + tbm->orig = orig; + tbm->proc = proc_p; + tbm->barScale = barScale; + tbm->w = tbm->objectW = size.x/barScale + 5.0/hotBarD.dpi; + tbm->labelW = 0; + tbm->x = hotBarWidth; + if ( hotBarLabels ) { + DrawTextSize( &hotBarD, proc_p( HB_BARTITLE, context, NULL, NULL), hotBarFp, hotBarFs, FALSE, &textsize ); + tbm->labelW = textsize.x+5/hotBarD.dpi; + if ( tbm->labelW > tbm->w ) { + tbm->w = tbm->labelW; + } + } + hotBarWidth += tbm->w; +} + + +static void ChangeHotBar( long changes ) +{ +#ifdef LATER + int curFileIndex = -3; + char * name; +#endif + static long programModeOld = 0; + + if ( (changes&(CHANGE_SCALE|CHANGE_PARAMS|CHANGE_TOOLBAR)) == 0 ) + return; + if ( hotBarLabels && !hotBarFp ) + hotBarFp = wStandardFont( F_HELV, FALSE, FALSE ); + if (hotBarLeftB != NULL && curScaleName) { + hotBarWidth = 0.0; + hotBarMLcnt = 0; + wMenuListClear( hotBarML ); + DYNARR_RESET( hotBarMap_t, hotBarMap_da ); + curContentsLabel[0] = '\0'; + if ( programMode == MODE_DESIGN ) { + AddHotBarTurnouts(); + AddHotBarStructures(); + } else { + AddHotBarCarDesc(); + } + + if ( programModeOld != programMode ) { + hotBarCurrSelects[0] = hotBarCurrSelects[1] = -1; + programModeOld = programMode; + } + if (hotBarMap_da.cnt > 0 && (hotBarCurrStart >= hotBarMap_da.cnt||hotBarCurrStart < 0)) + hotBarCurrStart = 0; + RedrawHotBar( NULL, NULL, 0, 0 ); + } +} + + +EXPORT void InitHotBar( void ) +{ + long v; + + AddParam( "BARSCALE", SetHotBarScale ); + AddPlaybackProc( "HOTBARSELECT", (playbackProc_p)HotBarSelectPlayback, NULL ); + RegisterChangeNotification( ChangeHotBar ); + wPrefGetInteger( "misc", "hotbar-start", &v, hotBarCurrStart ); + hotBarCurrStart = (int)v; + hotbarPopupM = MenuRegister( "Hotbar Select" ); + hotBarML = wMenuListCreate( hotbarPopupM, "", -1, HotbarJump ); +} + +EXPORT void LayoutHotBar( void ) +{ + wPos_t buttonWidth, winWidth, winHeight; + BOOL_T initialize = FALSE; + + wWinGetSize( mainW, &winWidth, &winHeight ); + hotBarHeight = hotBarDrawHeight; + if ( hotBarLabels) + hotBarHeight += 8; + if (hotBarLeftB == NULL) { + wIcon_p bm_p; + if (winWidth < 50) + return; + bm_p = wIconCreateBitMap( 16, 16, turnbarl_bits, wDrawColorBlack ); + hotBarLeftB = wButtonCreate( mainW, 0, 0, "hotBarLeft", (char*)bm_p, BO_ICON, 0, DoHotBarLeft, NULL ); + bm_p = wIconCreateBitMap( 16, 16, turnbarr_bits, wDrawColorBlack ); + hotBarRightB = wButtonCreate( mainW, 0, 0, "hotBarRight", (char*)bm_p, BO_ICON, 0, DoHotBarRight, NULL ); + hotBarD.d = wDrawCreate( mainW, 0, 0, NULL, BD_NOCAPTURE, 100, hotBarHeight, NULL, RedrawHotBar, SelectHotBar ); + hotBarD.dpi = wDrawGetDPI( hotBarD.d ); + hotBarD.scale = 1.0; + initialize = TRUE; + } + buttonWidth = wControlGetWidth((wControl_p)hotBarLeftB); + wControlSetPos( (wControl_p)hotBarLeftB, 0, toolbarHeight ); + wControlSetPos( (wControl_p)hotBarRightB, winWidth-buttonWidth, toolbarHeight ); + wControlSetPos( (wControl_p)hotBarD.d, buttonWidth, toolbarHeight ); + wDrawSetSize( hotBarD.d, winWidth-buttonWidth*2, hotBarHeight+2 ); + hotBarD.size.x = ((double)(winWidth-buttonWidth*2))/hotBarD.dpi*hotBarD.scale; + hotBarD.size.y = (double)hotBarHeight/hotBarD.dpi*hotBarD.scale; + wControlShow( (wControl_p)hotBarLeftB, TRUE ); + wControlShow( (wControl_p)hotBarRightB, TRUE ); + wControlShow( (wControl_p)hotBarD.d, TRUE ); + if (initialize) + ChangeHotBar( CHANGE_PARAMS ); + else + RedrawHotBar( NULL, NULL, 0, 0 ); + toolbarHeight += hotBarHeight+3; +} + +void HideHotBar( void ) +{ + if (hotBarLeftB != NULL) { + wControlShow( (wControl_p)hotBarLeftB, FALSE ); + wControlShow( (wControl_p)hotBarRightB, FALSE ); + wControlShow( (wControl_p)hotBarD.d, FALSE ); + } +} |