diff options
Diffstat (limited to 'app/bin/cmisc.c')
-rw-r--r-- | app/bin/cmisc.c | 451 |
1 files changed, 451 insertions, 0 deletions
diff --git a/app/bin/cmisc.c b/app/bin/cmisc.c new file mode 100644 index 0000000..fe8beea --- /dev/null +++ b/app/bin/cmisc.c @@ -0,0 +1,451 @@ +/** \file cmisc.c + * Handlimg of the 'Describe' dialog + * + * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/bin/cmisc.c,v 1.7 2009-07-08 18:40:27 m_fischer Exp $ + */ + +/* 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 "track.h" +#include "common.h" +#include "i18n.h" + +/***************************************************************************** + * + * DESCRIPTION WINDOW + * + */ + + +EXPORT wIndex_t describeCmdInx; +EXPORT BOOL_T inDescribeCmd; + +static track_p descTrk; +static descData_p descData; +static descUpdate_t descUpdateFunc; +static coOrd descOrig, descSize; +static POS_T descBorder; +static wDrawColor descColor = 0; +static BOOL_T descUndoStarted; +static BOOL_T descNeedDrawHilite; +static wPos_t describeW_posy; +static wPos_t describeCmdButtonEnd; + + +static paramFloatRange_t rdata = { 0, 0, 100, PDO_NORANGECHECK_HIGH|PDO_NORANGECHECK_LOW }; +static paramIntegerRange_t idata = { 0, 0, 100, PDO_NORANGECHECK_HIGH|PDO_NORANGECHECK_LOW }; +static paramTextData_t tdata = { 300, 150 }; +static char * pivotLabels[] = { N_("First"), N_("Middle"), N_("Second"), NULL }; +static paramData_t describePLs[] = { +#define I_FLOAT_0 (0) + { PD_FLOAT, NULL, "F1", 0, &rdata }, + { PD_FLOAT, NULL, "F2", 0, &rdata }, + { PD_FLOAT, NULL, "F3", 0, &rdata }, + { PD_FLOAT, NULL, "F4", 0, &rdata }, + { PD_FLOAT, NULL, "F5", 0, &rdata }, + { PD_FLOAT, NULL, "F6", 0, &rdata }, + { PD_FLOAT, NULL, "F7", 0, &rdata }, + { PD_FLOAT, NULL, "F8", 0, &rdata }, + { PD_FLOAT, NULL, "F9", 0, &rdata }, + { PD_FLOAT, NULL, "F10", 0, &rdata }, + { PD_FLOAT, NULL, "F11", 0, &rdata }, + { PD_FLOAT, NULL, "F12", 0, &rdata }, + { PD_FLOAT, NULL, "F13", 0, &rdata }, + { PD_FLOAT, NULL, "F14", 0, &rdata }, + { PD_FLOAT, NULL, "F15", 0, &rdata }, + { PD_FLOAT, NULL, "F16", 0, &rdata }, + { PD_FLOAT, NULL, "F17", 0, &rdata }, + { PD_FLOAT, NULL, "F18", 0, &rdata }, + { PD_FLOAT, NULL, "F19", 0, &rdata }, + { PD_FLOAT, NULL, "F20", 0, &rdata }, +#define I_FLOAT_N I_FLOAT_0+20 + +#define I_LONG_0 I_FLOAT_N + { PD_LONG, NULL, "I1", 0, &idata }, + { PD_LONG, NULL, "I2", 0, &idata }, + { PD_LONG, NULL, "I3", 0, &idata }, + { PD_LONG, NULL, "I4", 0, &idata }, + { PD_LONG, NULL, "I5", 0, &idata }, +#define I_LONG_N I_LONG_0+5 + +#define I_STRING_0 I_LONG_N + { PD_STRING, NULL, "S1", 0, (void*)300 }, + { PD_STRING, NULL, "S2", 0, (void*)300 }, + { PD_STRING, NULL, "S3", 0, (void*)300 }, + { PD_STRING, NULL, "S4", 0, (void*)300 }, +#define I_STRING_N I_STRING_0+4 + +#define I_LAYER_0 I_STRING_N + { PD_DROPLIST, NULL, "Y1", 0, (void*)150, NULL, 0 }, +#define I_LAYER_N I_LAYER_0+1 + +#define I_COLOR_0 I_LAYER_N + { PD_COLORLIST, NULL, "C1", 0, NULL, N_("Color") }, +#define I_COLOR_N I_COLOR_0+1 + +#define I_LIST_0 I_COLOR_N + { PD_DROPLIST, NULL, "L1", 0, (void*)150, NULL, 0 }, + { PD_DROPLIST, NULL, "L2", 0, (void*)150, NULL, 0 }, +#define I_LIST_N I_LIST_0+2 + +#define I_EDITLIST_0 I_LIST_N + { PD_DROPLIST, NULL, "LE1", 0, (void*)150, NULL, BL_EDITABLE }, +#define I_EDITLIST_N I_EDITLIST_0+1 + +#define I_TEXT_0 I_EDITLIST_N + { PD_TEXT, NULL, "T1", 0, &tdata }, +#define I_TEXT_N I_TEXT_0+1 + +#define I_PIVOT_0 I_TEXT_N + { PD_RADIO, NULL, "P1", 0, pivotLabels, N_("Pivot"), BC_HORZ|BC_NOBORDER, 0 } +#define I_PIVOT_N I_PIVOT_0+1 + }; + +static paramGroup_t describePG = { "describe", 0, describePLs, sizeof describePLs/sizeof describePLs[0] }; + + +static void DrawDescHilite( void ) +{ + wPos_t x, y, w, h; + if ( descNeedDrawHilite == FALSE ) + return; + if (descColor==0) + descColor = wDrawColorGray(87); + w = (wPos_t)((descSize.x/mainD.scale)*mainD.dpi+0.5); + h = (wPos_t)((descSize.y/mainD.scale)*mainD.dpi+0.5); + mainD.CoOrd2Pix(&mainD,descOrig,&x,&y); + wDrawFilledRectangle( mainD.d, x, y, w, h, descColor, wDrawOptTemp ); +} + + + +static void DescribeUpdate( + paramGroup_p pg, + int inx, + void * data ) +{ + coOrd hi, lo; + descData_p ddp; + if ( inx < 0 ) + return; + ddp = (descData_p)pg->paramPtr[inx].context; + if ( (ddp->mode&(DESC_RO|DESC_IGNORE)) != 0 ) + return; + if ( ddp->type == DESC_PIVOT ) + return; + if ( (ddp->mode&DESC_NOREDRAW) == 0 ) + DrawDescHilite(); + if ( !descUndoStarted ) { + UndoStart( _("Change Track"), "Change Track" ); + descUndoStarted = TRUE; + } + UndoModify( descTrk ); + descUpdateFunc( descTrk, ddp-descData, descData, FALSE ); + if ( descTrk ) { + GetBoundingBox( descTrk, &hi, &lo ); + if ( OFF_D( mapD.orig, mapD.size, descOrig, descSize ) ) { + ErrorMessage( MSG_MOVE_OUT_OF_BOUNDS ); + } + } + if ( (ddp->mode&DESC_NOREDRAW) == 0 ) { + descOrig = lo; + descSize = hi; + descOrig.x -= descBorder; + descOrig.y -= descBorder; + descSize.x -= descOrig.x-descBorder; + descSize.y -= descOrig.y-descBorder; + DrawDescHilite(); + } + for ( inx = 0; inx < sizeof describePLs/sizeof describePLs[0]; inx++ ) { + if ( (describePLs[inx].option & PDO_DLGIGNORE) != 0 ) + continue; + ddp = (descData_p)describePLs[inx].context; + if ( (ddp->mode&DESC_IGNORE) != 0 ) + continue; + if ( (ddp->mode&DESC_CHANGE) == 0 ) + continue; + ddp->mode &= ~DESC_CHANGE; + ParamLoadControl( &describePG, inx ); + } +} + + +static void DescOk( void * junk ) +{ + wHide( describePG.win ); + if ( descTrk ) + DrawDescHilite(); + + descUpdateFunc( descTrk, -1, descData, !descUndoStarted ); + descTrk = NULL; + if (descUndoStarted) { + UndoEnd(); + descUndoStarted = FALSE; + } + descNeedDrawHilite = FALSE; + Reset(); +} + + +static struct { + parameterType pd_type; + long option; + int first; + int last; + } descTypeMap[] = { +/*NULL*/ { 0, 0 }, +/*POS*/ { PD_FLOAT, PDO_DIM, I_FLOAT_0, I_FLOAT_N }, +/*FLOAT*/ { PD_FLOAT, 0, I_FLOAT_0, I_FLOAT_N }, +/*ANGLE*/ { PD_FLOAT, PDO_ANGLE, I_FLOAT_0, I_FLOAT_N }, +/*LONG*/ { PD_LONG, 0, I_LONG_0, I_LONG_N }, +/*COLOR*/ { PD_LONG, 0, I_COLOR_0, I_COLOR_N }, +/*DIM*/ { PD_FLOAT, PDO_DIM, I_FLOAT_0, I_FLOAT_N }, +/*PIVOT*/ { PD_RADIO, 0, I_PIVOT_0, I_PIVOT_N }, +/*LAYER*/ { PD_DROPLIST,PDO_LISTINDEX, I_LAYER_0, I_LAYER_N }, +/*STRING*/ { PD_STRING,0, I_STRING_0, I_STRING_N }, +/*TEXT*/ { PD_TEXT, PDO_DLGNOLABELALIGN, I_TEXT_0, I_TEXT_N }, +/*LIST*/ { PD_DROPLIST, PDO_LISTINDEX, I_LIST_0, I_LIST_N }, +/*EDITABLELIST*/{ PD_DROPLIST, 0, I_EDITLIST_0, I_EDITLIST_N } }; + +static wControl_p AllocateButt( descData_p ddp, void * valueP, char * label, wPos_t sep ) +{ + int inx; + + for ( inx = descTypeMap[ddp->type].first; inx<descTypeMap[ddp->type].last; inx++ ) { + if ( (describePLs[inx].option & PDO_DLGIGNORE) != 0 ) { + describePLs[inx].option = descTypeMap[ddp->type].option; + if ( describeW_posy > describeCmdButtonEnd ) + describePLs[inx].option |= PDO_DLGUNDERCMDBUTT; + describeW_posy += wControlGetHeight( describePLs[inx].control ) + sep; + describePLs[inx].context = ddp; + describePLs[inx].valueP = valueP; + if ( label && ddp->type != DESC_TEXT ) { + wControlSetLabel( describePLs[inx].control, label ); + describePLs[inx].winLabel = label; + } + return describePLs[inx].control; + } + } + AbortProg( "allocateButt: can't find %d", ddp->type ); + return NULL; +} + + +static void DescribeLayout( + paramData_t * pd, + int inx, + wPos_t colX, + wPos_t * x, + wPos_t * y ) +{ + descData_p ddp; + wPos_t w, h; + + if ( inx < 0 ) + return; + if ( pd->context == NULL ) + return; + ddp = (descData_p)pd->context; + *y = ddp->posy; + if ( ddp->type == DESC_POS && + ddp->control0 != pd->control ) { + *y += wControlGetHeight( pd->control ) + 3; + } else if ( ddp->type == DESC_TEXT ) { + w = tdata.width; + h = tdata.height; + wTextSetSize( (wText_p)pd->control, w, h ); + } + wControlShow( pd->control, TRUE ); +} + + +/** + * Creation and modification of the Describe dialog box is handled here. As the number + * of values for a track element depends on the specific type, this dialog is dynamically + * updated to hsow the changable parameters only + * + * \param IN title Description of the selected part, shown in window title bar + * \param IN trk Track element to be described + * \param IN data + * \param IN update + * + */ +static wList_p setLayerL; +void DoDescribe( char * title, track_p trk, descData_p data, descUpdate_t update ) +{ + int inx; + descData_p ddp; + char * label; + int ro_mode; + + if (!inDescribeCmd) + return; + + descTrk = trk; + descData = data; + descUpdateFunc = update; + describeW_posy = 0; + if ( describePG.win == NULL ) { + /* SDB 5.13.2005 */ + ParamCreateDialog( &describePG, _("Description"), _("Done"), DescOk, + (paramActionCancelProc) DescribeCancel, + TRUE, DescribeLayout, F_RECALLPOS, + DescribeUpdate ); + describeCmdButtonEnd = wControlBelow( (wControl_p)describePG.helpB ); + } + for ( inx=0; inx<sizeof describePLs/sizeof describePLs[0]; inx++ ) { + describePLs[inx].option = PDO_DLGIGNORE; + wControlShow( describePLs[inx].control, FALSE ); + } + ro_mode = (GetLayerFrozen(GetTrkLayer(trk))?DESC_RO:0); + if (ro_mode) + for ( ddp=data; ddp->type != DESC_NULL; ddp++ ) { + if ( ddp->mode&DESC_IGNORE ) + continue; + ddp->mode |= ro_mode; + } + for ( ddp=data; ddp->type != DESC_NULL; ddp++ ) { + if ( ddp->mode&DESC_IGNORE ) + continue; + label = _(ddp->label); + + ddp->posy = describeW_posy; + ddp->control0 = AllocateButt( ddp, ddp->valueP, label, (ddp->type == DESC_POS?3:3) ); + wControlActive( ddp->control0, ((ddp->mode|ro_mode)&DESC_RO)==0 ); + switch (ddp->type) { + case DESC_POS: + ddp->control1 = AllocateButt( ddp, + &((coOrd*)(ddp->valueP))->y, + "Y", + 3 ); + wControlActive( ddp->control1, ((ddp->mode|ro_mode)&DESC_RO)==0 ); + break; + case DESC_LAYER: + wListClear(ddp->control0); // Rebuild list on each invovation + for ( inx = 0; inx<NUM_LAYERS; inx++ ) { + if (!GetLayerFrozen(inx)) // Avoid Frozen layers. + { + sprintf( message, "%2d : %s", inx+1, GetLayerName(inx) ); + wListAddValue( ddp->control0, message, NULL, (void*)inx ); + } + } + break; + default: + break; + } + } + ParamLayoutDialog( &describePG ); + ParamLoadControls( &describePG ); + sprintf( message, "%s (T%d)", title, GetTrkIndex(trk) ); + wWinSetTitle( describePG.win, message ); + wShow( describePG.win ); +} + + +static void DescChange( long changes ) +{ + if ( (changes&CHANGE_UNITS) && describePG.win && wWinIsVisible(describePG.win) ) + ParamLoadControls( &describePG ); +} + +/***************************************************************************** + * + * SIMPLE DESCRIPTION + * + */ + + +EXPORT void DescribeCancel( void ) +{ + if ( describePG.win && wWinIsVisible(describePG.win) ) { + if ( descTrk ) { + descUpdateFunc( descTrk, -1, descData, TRUE ); + descTrk = NULL; + DrawDescHilite(); + } + wHide( describePG.win ); + if ( descUndoStarted ) { + UndoEnd(); + descUndoStarted = FALSE; + } + } + descNeedDrawHilite = FALSE; +} + + +static STATUS_T CmdDescribe( wAction_t action, coOrd pos ) +{ + track_p trk; + char msg[STR_SIZE]; + + switch (action) { + case C_START: + InfoMessage( _("Select track to describe") ); + descUndoStarted = FALSE; + return C_CONTINUE; + + case C_DOWN: + if ((trk = OnTrack( &pos, FALSE, FALSE )) != NULL) { + if ( describePG.win && wWinIsVisible(describePG.win) && descTrk ) { + DrawDescHilite(); + descUpdateFunc( descTrk, -1, descData, TRUE ); + descTrk = NULL; + } + descBorder = mainD.scale*0.1; + if ( descBorder < trackGauge ) + descBorder = trackGauge; + inDescribeCmd = TRUE; + GetBoundingBox( trk, &descSize, &descOrig ); + descOrig.x -= descBorder; + descOrig.y -= descBorder; + descSize.x -= descOrig.x-descBorder; + descSize.y -= descOrig.y-descBorder; + descNeedDrawHilite = TRUE; + DrawDescHilite(); + DescribeTrack( trk, msg, 255 ); + inDescribeCmd = FALSE; + InfoMessage( msg ); + } else + InfoMessage( "" ); + return C_CONTINUE; + + case C_REDRAW: + if (describePG.win && wWinIsVisible(describePG.win) && descTrk) + DrawDescHilite(); + break; + + case C_CANCEL: + DescribeCancel(); + return C_CONTINUE; + } + return C_CONTINUE; +} + + + +#include "bitmaps/describe.xpm" + +void InitCmdDescribe( wMenu_p menu ) +{ + describeCmdInx = AddMenuButton( menu, CmdDescribe, "cmdDescribe", _("Properties"), wIconCreatePixMap(describe_xpm), + LEVEL0, IC_CANCEL|IC_POPUP, ACCL_DESCRIBE, NULL ); + RegisterChangeNotification( DescChange ); + ParamRegister( &describePG ); + /*AddPlaybackProc( "DESCRIBE", playbackDescribe, NULL );*/ +} |