diff options
Diffstat (limited to 'app/bin/draw.c')
-rw-r--r-- | app/bin/draw.c | 684 |
1 files changed, 458 insertions, 226 deletions
diff --git a/app/bin/draw.c b/app/bin/draw.c index 92814e0..3f25830 100644 --- a/app/bin/draw.c +++ b/app/bin/draw.c @@ -1,7 +1,5 @@ /** \file draw.c * Basic drawing functions. - * - * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/bin/draw.c,v 1.17 2009-12-12 17:20:59 m_fischer Exp $ */ /* XTrkCad - Model Railroad CAD @@ -24,6 +22,8 @@ #include <stdlib.h> #include <stdio.h> +#include <string.h> + #ifdef HAVE_MALLOC_C #include <malloc.h> #endif @@ -40,12 +40,16 @@ #include <sys/timeb.h> #endif -#include "track.h" -#include "utility.h" -#include "misc.h" +#include "cselect.h" +#include "custom.h" #include "draw.h" -#include "i18n.h" #include "fileio.h" +#include "i18n.h" +#include "messages.h" +#include "misc.h" +#include "param.h" +#include "track.h" +#include "utility.h" static void DrawRoomWalls( wBool_t ); EXPORT void DrawMarkers( void ); @@ -57,6 +61,8 @@ static int log_mouse = 0; static wFontSize_t drawMaxTextFontSize = 100; +extern long zoomCorner; + /**************************************************************************** * * EXPORTED VARIABLES @@ -67,6 +73,7 @@ static wFontSize_t drawMaxTextFontSize = 100; #define INIT_MAP_SCALE (64.0) #define MAX_MAIN_SCALE (256.0) #define MIN_MAIN_SCALE (1.0) +#define MIN_MAIN_MACRO (0.10) // static char FAR message[STR_LONG_SIZE]; @@ -94,6 +101,7 @@ EXPORT DIST_T pixelBins = 80; */ static wPos_t infoHeight; +static wPos_t textHeight; EXPORT wWin_p mapW; EXPORT BOOL_T mapVisible; @@ -111,11 +119,11 @@ EXPORT wDrawColor exceptionColor; static wFont_p rulerFp; static struct { - wMessage_p scale_m; - wMessage_p count_m; - wMessage_p posX_m; - wMessage_p posY_m; - wMessage_p info_m; + wStatus_p scale_m; + wStatus_p count_m; + wStatus_p posX_m; + wStatus_p posY_m; + wStatus_p info_m; wPos_t scale_w; wPos_t count_w; wPos_t pos_w; @@ -462,33 +470,55 @@ EXPORT void DrawMultiString( coOrd * hi) { char * cp; + char * cp1; POS_T lineH, lineW; - coOrd size, textsize; + coOrd size, textsize, posl, orig; POS_T descent; + char *line; - DrawTextSize2( &mainD, "Aqjlp", fp, fs, TRUE, &textsize, &descent ); - lineH = textsize.y+descent; + if (!text || !*text) { + return; //No string or blank + } + line = malloc(strlen(text) + 1); + + DrawTextSize2( &mainD, "Aqjlp", fp, fs, TRUE, &textsize, &descent); + POS_T ascent = textsize.y-descent; + lineH = ascent+descent*1.5; size.x = 0.0; size.y = 0.0; - while (1) { - cp = message; + orig.x = pos.x; + orig.y = pos.y; + cp = line; // Build up message to hold all of the strings separated by nulls + while (*text) { + cp1 = cp; while (*text != '\0' && *text != '\n') *cp++ = *text++; *cp = '\0'; - DrawTextSize2( &mainD, message, fp, fs, TRUE, &textsize, &descent ); + DrawTextSize2( &mainD, cp1, fp, fs, TRUE, &textsize, &descent); lineW = textsize.x; if (lineW>size.x) size.x = lineW; - DrawString( d, pos, 0.0, message, fp, fs, color ); + posl.x = pos.x; + posl.y = pos.y; + Rotate( &posl, orig, a); + DrawString( d, posl, a, cp1, fp, fs, color ); pos.y -= lineH; size.y += lineH; - if (*text) + if (*text == '\0') break; text++; + cp++; + } + if (lo) { + lo->x = posl.x; + lo->y = posl.y-descent; + } + if (hi) { + hi->x = posl.x+size.x; + hi->y = posl.y+ascent; } - *lo = pos; - hi->x = pos.x; - hi->y = pos.y+size.y; + + free(line); } @@ -613,6 +643,52 @@ EXPORT void DrawTextSize( DrawTextSize2( dp, text, fp, fs, relative, size, &descent ); } +EXPORT void DrawMultiLineTextSize( + drawCmd_p dp, + char * text, + wFont_p fp, + wFontSize_t fs, + BOOL_T relative, + coOrd * size, + coOrd * lastline ) +{ + POS_T descent, lineW, lineH; + coOrd textsize, blocksize; + + char *cp; + char *line = malloc(strlen(text) + 1); + + DrawTextSize2( &mainD, "Aqlip", fp, fs, TRUE, &textsize, &descent); + POS_T ascent = textsize.y-descent; + lineH = ascent+descent*1.5; + blocksize.x = 0; + blocksize.y = 0; + lastline->x = 0; + lastline->y = 0; + while (text && *text != '\0' ) { + cp = line; + while (*text != '\0' && *text != '\n') + *cp++ = *text++; + *cp = '\0'; + blocksize.y += lineH; + DrawTextSize2( &mainD, line, fp, fs, TRUE, &textsize, &descent); + lineW = textsize.x; + if (lineW>blocksize.x) + blocksize.x = lineW; + lastline->x = textsize.x; + if (*text =='\n') { + lastline->y -= lineH; + lastline->x = 0; + } + if (*text == '\0') + break; + text++; + } + size->x = blocksize.x; + size->y = blocksize.y; + free(line); +} + static void DDrawBitMap( drawCmd_p d, coOrd p, wDrawBitMap_p bm, wDrawColor color) { @@ -689,7 +765,7 @@ static void TempSegString( tempSegs(tempSegs_da.cnt-1).u.t.angle = a; tempSegs(tempSegs_da.cnt-1).u.t.fontP = fp; tempSegs(tempSegs_da.cnt-1).u.t.fontSize = fontSize; - tempSegs(tempSegs_da.cnt-1).u.t.string = s; + tempSegs(tempSegs_da.cnt-1).u.t.string = MyStrdup(s); } @@ -792,6 +868,8 @@ static wPos_t info_yb_offset = 2; static wPos_t info_ym_offset = 3; static wPos_t six = 2; static wPos_t info_xm_offset = 2; +static wPos_t messageOrControlX = 0; +static wPos_t messageOrControlY = 0; #define NUM_INFOCTL (4) static wControl_p curInfoControl[NUM_INFOCTL]; static wPos_t curInfoLabelWidth[NUM_INFOCTL]; @@ -827,9 +905,9 @@ static wPos_t GetInfoPosWidth( void ) dist = 9.0*12.0+11.0+3.0/4.0-1.0/64.0; } - labelWidth = (wLabelWidth( xLabel ) > wLabelWidth( yLabel ) ? wLabelWidth( xLabel ):wLabelWidth( yLabel )); + labelWidth = (wStatusGetWidth( xLabel ) > wStatusGetWidth( yLabel ) ? wStatusGetWidth( xLabel ):wStatusGetWidth( yLabel )); - return wLabelWidth( FormatDistance(dist) ) + labelWidth; + return wStatusGetWidth( FormatDistance(dist) ) + labelWidth; } /** @@ -841,35 +919,43 @@ EXPORT void InitInfoBar( void ) { wPos_t width, height, y, yb, ym, x, boxH; wWinGetSize( mainW, &width, &height ); - infoHeight = 3 + wMessageGetHeight( 0L ) + 3; - y = height - infoHeight; + infoHeight = 3 + wStatusGetHeight( COMBOBOX ) + 3; + textHeight = wStatusGetHeight(0L); + y = height - max(infoHeight,textHeight)-10; + +#ifdef WINDOWS y -= 19; /* Kludge for MSW */ - infoD.pos_w = GetInfoPosWidth() + 2; - infoD.scale_w = wLabelWidth( "999:1" ) + wLabelWidth( zoomLabel ) + 6; - /* we do not use the count label for the moment */ - infoD.count_w = 0; - infoD.info_w = width - infoD.pos_w*2 - infoD.scale_w - infoD.count_w - 45; +#endif + + infoD.pos_w = GetInfoPosWidth() + 2; + infoD.scale_w = wStatusGetWidth( "999:1" ) + wStatusGetWidth( zoomLabel ) + 6; + /* we do not use the count label for the moment */ + infoD.count_w = 0; + infoD.info_w = width - 20 - infoD.pos_w*2 - infoD.scale_w - infoD.count_w - 45; // Allow Window to resize down if (infoD.info_w <= 0) { infoD.info_w = 10; } yb = y+info_yb_offset; - ym = y+info_ym_offset; - boxH = infoHeight-5; - x = 0; + ym = y+(infoHeight-textHeight)/2; + boxH = infoHeight; + x = 2; infoD.scale_b = wBoxCreate( mainW, x, yb, NULL, wBoxBelow, infoD.scale_w, boxH ); - infoD.scale_m = wMessageCreate( mainW, x+info_xm_offset, ym, "infoBarScale", infoD.scale_w-six, zoomLabel ); + infoD.scale_m = wStatusCreate( mainW, x+info_xm_offset, ym, "infoBarScale", infoD.scale_w-six, zoomLabel); x += infoD.scale_w + 10; infoD.posX_b = wBoxCreate( mainW, x, yb, NULL, wBoxBelow, infoD.pos_w, boxH ); - infoD.posX_m = wMessageCreate( mainW, x+info_xm_offset, ym, "infoBarPosX", infoD.pos_w-six, xLabel ); + infoD.posX_m = wStatusCreate( mainW, x+info_xm_offset, ym, "infoBarPosX", infoD.pos_w-six, xLabel ); x += infoD.pos_w + 5; infoD.posY_b = wBoxCreate( mainW, x, yb, NULL, wBoxBelow, infoD.pos_w, boxH ); - infoD.posY_m = wMessageCreate( mainW, x+info_xm_offset, ym, "infoBarPosY", infoD.pos_w-six, yLabel ); + infoD.posY_m = wStatusCreate( mainW, x+info_xm_offset, ym, "infoBarPosY", infoD.pos_w-six, yLabel ); x += infoD.pos_w + 10; + messageOrControlX = x+info_xm_offset; //Remember Position + messageOrControlY = ym; infoD.info_b = wBoxCreate( mainW, x, yb, NULL, wBoxBelow, infoD.info_w, boxH ); - infoD.info_m = wMessageCreate( mainW, x+info_xm_offset, ym, "infoBarStatus", infoD.info_w-six, "" ); + infoD.info_m = wStatusCreate( mainW, x+info_xm_offset, ym, "infoBarStatus", infoD.info_w-six, "" ); } + static void SetInfoBar( void ) { wPos_t width, height, y, yb, ym, x, boxH; @@ -877,23 +963,23 @@ static void SetInfoBar( void ) static long oldDistanceFormat = -1; long newDistanceFormat; wWinGetSize( mainW, &width, &height ); - y = height - infoHeight; + y = height - max(infoHeight,textHeight)-10; newDistanceFormat = GetDistanceFormat(); if ( newDistanceFormat != oldDistanceFormat ) { infoD.pos_w = GetInfoPosWidth() + 2; wBoxSetSize( infoD.posX_b, infoD.pos_w, infoHeight-5 ); - wMessageSetWidth( infoD.posX_m, infoD.pos_w-six ); + wStatusSetWidth( infoD.posX_m, infoD.pos_w-six ); wBoxSetSize( infoD.posY_b, infoD.pos_w, infoHeight-5 ); - wMessageSetWidth( infoD.posY_m, infoD.pos_w-six ); + wStatusSetWidth( infoD.posY_m, infoD.pos_w-six ); } - infoD.info_w = width - infoD.pos_w*2 - infoD.scale_w - infoD.count_w - 40 + 4; + infoD.info_w = width - 20 - infoD.pos_w*2 - infoD.scale_w - infoD.count_w - 40 + 4; if (infoD.info_w <= 0) { infoD.info_w = 10; } yb = y+info_yb_offset; - ym = y+info_ym_offset; - boxH = infoHeight-5; - wWinClear( mainW, 0, y, width, infoHeight ); + ym = y+(infoHeight-textHeight)/2; + boxH = infoHeight; + wWinClear( mainW, 0, y, width-20, infoHeight ); x = 0; wControlSetPos( (wControl_p)infoD.scale_b, x, yb ); wControlSetPos( (wControl_p)infoD.scale_m, x+info_xm_offset, ym ); @@ -907,18 +993,18 @@ static void SetInfoBar( void ) wControlSetPos( (wControl_p)infoD.info_b, x, yb ); wControlSetPos( (wControl_p)infoD.info_m, x+info_xm_offset, ym ); wBoxSetSize( infoD.info_b, infoD.info_w, boxH ); - wMessageSetWidth( infoD.info_m, infoD.info_w-six ); + wStatusSetWidth( infoD.info_m, infoD.info_w-six ); + messageOrControlX = x+info_xm_offset; + messageOrControlY = ym; if (curInfoControl[0]) { - x = wControlGetPosX( (wControl_p)infoD.info_m ); -#ifndef WINDOWS - yb -= 2; -#endif for ( inx=0; curInfoControl[inx]; inx++ ) { x += curInfoLabelWidth[inx]; - wControlSetPos( curInfoControl[inx], x, yb ); + int y_this = ym + (textHeight/2) - (wControlGetHeight( curInfoControl[inx] )/2); + wControlSetPos( curInfoControl[inx], x, y_this ); x += wControlGetWidth( curInfoControl[inx] )+3; wControlShow( curInfoControl[inx], TRUE ); } + wControlSetPos( (wControl_p)infoD.info_m, x+info_xm_offset, ym ); //Move to end } } @@ -929,7 +1015,7 @@ static void InfoScale( void ) sprintf( message, "%s%0.0f:1", zoomLabel, mainD.scale ); else sprintf( message, "%s1:%0.0f", zoomLabel, floor(1/mainD.scale+0.5) ); - wMessageSetValue( infoD.scale_m, message ); + wStatusSetValue( infoD.scale_m, message ); } EXPORT void InfoCount( wIndex_t count ) @@ -942,38 +1028,13 @@ EXPORT void InfoCount( wIndex_t count ) EXPORT void InfoPos( coOrd pos ) { -#ifdef LATER - wPos_t ww, hh; - DIST_T w, h; -#endif - wPos_t x, y; - + DrawMarkers(); sprintf( message, "%s%s", xLabel, FormatDistance(pos.x) ); - wMessageSetValue( infoD.posX_m, message ); + wStatusSetValue( infoD.posX_m, message ); sprintf( message, "%s%s", yLabel, FormatDistance(pos.y) ); - wMessageSetValue( infoD.posY_m, message ); -#ifdef LATER - wDrawGetSize( mainD.d, &ww, &hh ); - w = (DIST_T)(ww/mainD.dpi); - h = (DIST_T)(hh/mainD.dpi); - /*wDrawClip( mainD.d, 0, 0, w, h );*/ -#endif - mainD.CoOrd2Pix(&mainD,oldMarker,&x,&y); - wDrawLine( mainD.d, 0, y, (wPos_t)(LBORDER), y, - 0, wDrawLineSolid, markerColor, wDrawOptTemp ); - wDrawLine( mainD.d, x, 0, x, (wPos_t)(BBORDER), - 0, wDrawLineSolid, markerColor, wDrawOptTemp ); - - mainD.CoOrd2Pix(&mainD,pos,&x,&y); - wDrawLine( mainD.d, 0, y, (wPos_t)(LBORDER), y, - 0, wDrawLineSolid, markerColor, wDrawOptTemp ); - wDrawLine( mainD.d, x, 0, x, (wPos_t)(BBORDER), - 0, wDrawLineSolid, markerColor, wDrawOptTemp ); -#ifdef LATER - /*wDrawClip( mainD.d, LBORDER, BBORDER, - w-(LBORDER+RBORDER), h-(BBORDER+TBORDER) );*/ -#endif + wStatusSetValue( infoD.posY_m, message ); oldMarker = pos; + DrawMarkers(); } static wControl_p deferSubstituteControls[NUM_INFOCTL+1]; @@ -998,94 +1059,34 @@ EXPORT void InfoSubstituteControls( memcpy( deferSubstituteLabels, labels, sizeof deferSubstituteLabels ); } if ( inError || controls == NULL || controls[0]==NULL ) { + wControlSetPos( (wControl_p)infoD.info_m, messageOrControlX, messageOrControlY); wControlShow( (wControl_p)infoD.info_m, TRUE ); return; } - x = wControlGetPosX( (wControl_p)infoD.info_m ); - y = wControlGetPosY( (wControl_p)infoD.info_m ); -#ifndef WINDOWS - y -= 3; -#endif - wMessageSetValue( infoD.info_m, "" ); + //x = wControlGetPosX( (wControl_p)infoD.info_m ); + x = messageOrControlX; + y = messageOrControlY; + wStatusSetValue( infoD.info_m, "" ); wControlShow( (wControl_p)infoD.info_m, FALSE ); for ( inx=0; controls[inx]; inx++ ) { curInfoLabelWidth[inx] = wLabelWidth(_(labels[inx])); x += curInfoLabelWidth[inx]; - wControlSetPos( controls[inx], x, y ); + int y_this = y + (textHeight/2) - (wControlGetHeight( controls[inx] )/2); + wControlSetPos( controls[inx], x, y_this ); x += wControlGetWidth( controls[inx] ); wControlSetLabel( controls[inx], _(labels[inx]) ); wControlShow( controls[inx], TRUE ); curInfoControl[inx] = controls[inx]; x += 3; } + wControlSetPos( (wControl_p)infoD.info_m, x, y ); curInfoControl[inx] = NULL; deferSubstituteControls[0] = NULL; } - -#ifdef LATER -EXPORT void InfoSubstituteControl( - wControl_p control1, - char * label1, - wControl_p control2, - char * label2 ) -{ - wControl_p controls[3]; - wPos_t widths[2]; - - if (control1 == NULL) { - InfoSubstituteControls( NULL, NULL ); - } else { - controls[0] = control1; - controls[1] = control2; - controls[2] = NULL; - widths[0] = wLabelWidth( label1 ); - if (label2) - widths[1] = wLabelWidth( label2 ); - else - widths[1] = 0; - InfoSubstituteControls( controls, widths ); -#ifdef LATER - if (curInfoControl[0]) { - wControlShow( curInfoControl[0], FALSE ); - curInfoControl[0] = NULL; - } - if (curInfoControl[1]) { - wControlShow( curInfoControl[1], FALSE ); - curInfoControl[1] = NULL; - } - wControlShow( (wControl_p)infoD.info_m, TRUE ); - } else { - if (curInfoControl[0]) - wControlShow( curInfoControl[0], FALSE ); - if (curInfoControl[1]) - wControlShow( curInfoControl[1], FALSE ); - x = wControlGetPosX( (wControl_p)infoD.info_m ); - y = wControlGetPosY( (wControl_p)infoD.info_m ); - curInfoLabelWidth[0] = wLabelWidth( label1 ); - x += curInfoLabelWidth[0]; - wControlShow( (wControl_p)infoD.info_m, FALSE ); - wControlSetPos( control1, x, y ); - wControlShow( control1, TRUE ); - curInfoControl[0] = control1; - curInfoControl[1] = NULL; - if (control2 != NULL) { - curInfoLabelWidth[1] = wLabelWidth( label2 ); - x = wControlBeside( curInfoControl[0] ) + 10; - x += curInfoLabelWidth[1]+10; - wControlSetPos( control2, x, y ); - wControlShow( control2, TRUE ); - curInfoControl[1] = control2; - } -#endif - } -} -#endif - - EXPORT void SetMessage( char * msg ) { - wMessageSetValue( infoD.info_m, msg ); + wStatusSetValue( infoD.info_m, msg ); } @@ -1289,8 +1290,15 @@ lprintf("mainRedraw\n"); wDrawDelayUpdate( mainD.d, FALSE ); } +/** + * The wlib event handler for the main window. + * + * \param win wlib window information + * \param e the wlib event + * \param data additional data (unused) + */ -EXPORT void MainProc( wWin_p win, winProcEvent e, void * data ) +void MainProc( wWin_p win, winProcEvent e, void * data ) { wPos_t width, height; switch( e ) { @@ -1300,31 +1308,28 @@ EXPORT void MainProc( wWin_p win, winProcEvent e, void * data ) DrawMapBoundingBox( FALSE ); wWinGetSize( mainW, &width, &height ); LayoutToolBar(); - height -= (toolbarHeight+infoHeight); + height -= (toolbarHeight+max(infoHeight,textHeight)+10); if (height >= 0) { - wDrawSetSize( mainD.d, width, height ); + wDrawSetSize( mainD.d, width-20, height ); wControlSetPos( (wControl_p)mainD.d, 0, toolbarHeight ); SetMainSize(); ConstraintOrig( &mainD.orig, mainD.size ); tempD.orig = mainD.orig; SetInfoBar(); MainRedraw(); + MapRedraw(); wPrefSetInteger( "draw", "mainwidth", width ); wPrefSetInteger( "draw", "mainheight", height ); - } - DrawMapBoundingBox( TRUE ); + } else DrawMapBoundingBox( TRUE ); + break; + case wState_e: + wPrefSetInteger( "draw", "maximized", wWinIsMaximized(win) ); break; case wQuit_e: - if (changed && - NoticeMessage( MSG_SAVE_CHANGES, _("Save"), _("Quit"))) - DoSave(NULL); - - CleanupFiles(); - SaveState(); CleanupCustom(); break; case wClose_e: - /* shutdown the application */ + /* shutdown the application via "close window" button */ DoQuit(); break; default: @@ -1380,9 +1385,7 @@ static void DrawRoomWalls( wBool_t t ) if (mainD.d == NULL) return; -#ifdef LATER - wDrawGetDim( mainD.d, &w, &h ); -#endif + DrawTicks( &mainD, mapD.size ); p01.x = p10.y = 0.0; @@ -1390,10 +1393,7 @@ static void DrawRoomWalls( wBool_t t ) p01.y = p11.y = mapD.size.y; DrawLine( &mainD, p01, p11, 3, t?borderColor:wDrawColorWhite ); DrawLine( &mainD, p11, p10, 3, t?borderColor:wDrawColorWhite ); -#ifdef LATER - /*wDrawClip( mainD.d, LBORDER, BBORDER, - w-(LBORDER+RBORDER), h-(BBORDER+TBORDER) );*/ -#endif + } @@ -1591,6 +1591,7 @@ EXPORT void DrawTicks( drawCmd_p d, coOrd size ) DIST_T offset; offset = 0.0; + if ( d->orig.x<0.0 ) offset = d->orig.x; p0.x = 0.0/*d->orig.x*/; p1.x = size.x; @@ -1599,6 +1600,7 @@ EXPORT void DrawTicks( drawCmd_p d, coOrd size ) p0.y = p1.y = min(d->orig.y + d->size.y, size.y); DrawRuler( d, p0, p1, offset, FALSE, TRUE, borderColor ); offset = 0.0; + if ( d->orig.y<0.0 ) offset = d->orig.y; p0.y = 0.0/*d->orig.y*/; p1.y = max(size.y,0.0); @@ -1630,6 +1632,7 @@ static void ConstraintOrig( coOrd * orig, coOrd size ) LOG( log_pan, 2, ( "ConstraintOrig [ %0.3f, %0.3f ] RoomSize(%0.3f %0.3f), WxH=%0.3fx%0.3f", orig->x, orig->y, mapD.size.x, mapD.size.y, size.x, size.y ) ) + if (orig->x+size.x > mapD.size.x ) { orig->x = mapD.size.x-size.x; orig->x += (units==UNITS_ENGLISH?1.0:(1.0/2.54)); @@ -1639,17 +1642,26 @@ LOG( log_pan, 2, ( "ConstraintOrig [ %0.3f, %0.3f ] RoomSize(%0.3f %0.3f), WxH=% if (orig->y+size.y > mapD.size.y ) { orig->y = mapD.size.y-size.y; orig->y += (units==UNITS_ENGLISH?1.0:1.0/2.54); - + } if (orig->y < 0) orig->y = 0; + if (mainD.scale >= 1.0) { if (units == UNITS_ENGLISH) { - orig->x = floor(orig->x); - orig->y = floor(orig->y); + orig->x = floor(orig->x*4)/4; //>1:1 = 1/4 inch + orig->y = floor(orig->y*4)/4; } else { - orig->x = floor(orig->x*2.54)/2.54; - orig->y = floor(orig->y*2.54)/2.54; + orig->x = floor(orig->x*2.54*2)/(2.54*2); //>1:1 = 0.5 cm + orig->y = floor(orig->y*2.54*2)/(2.54*2); + } + } else { + if (units == UNITS_ENGLISH) { + orig->x = floor(orig->x*64)/64; //<1:1 = 1/64 inch + orig->y = floor(orig->y*64)/64; + } else { + orig->x = floor(orig->x*25.4*2)/(25.4*2); //>1:1 = 0.5 mm + orig->y = floor(orig->y*25.4*2)/(25.4*2); } } orig->x = (long)(orig->x*pixelBins+0.5)/pixelBins; @@ -1719,11 +1731,27 @@ static int ScaleInx( DIST_T scale ) for ( inx=0; inx<sizeof zoomList/sizeof zoomList[0]; inx++ ) { if( scale == zoomList[inx].value ) { return inx; - } + } } return -1; } +/* + * Find Nearest Scale + */ + +static int NearestScaleInx ( DIST_T scale, BOOL_T larger ) { + int inx; + + for ( inx=0; inx<sizeof zoomList/sizeof zoomList[0]; inx++ ) { + if( scale == zoomList[inx].value ) { + return inx; + } + if (scale < zoomList[inx].value) return inx; + } + return inx-1; +} + /** * Set up for new drawing scale. After the scale was changed, eg. via zoom button, everything * is set up for the new scale. @@ -1739,10 +1767,6 @@ static void DoNewScale( DIST_T scale ) scale = MAX_MAIN_SCALE; DrawHilight( &mapD, mainD.orig, mainD.size ); -#ifdef LATER - center.x = mainD.orig.x + mainD.size.x/2.0; - center.y = mainD.orig.y + mainD.size.y/2.0; -#endif tempD.scale = mainD.scale = scale; mainD.dpi = wDrawGetDPI( mainD.d ); if ( mainD.dpi == 75 ) { @@ -1754,9 +1778,14 @@ static void DoNewScale( DIST_T scale ) SetZoomRadio( scale ); InfoScale(); - SetMainSize(); - mainD.orig.x = mainCenter.x - mainD.size.x/2.0; - mainD.orig.y = mainCenter.y - mainD.size.y/2.0; + SetMainSize(); + if (zoomCorner) { + mainCenter.x = mainD.orig.x + mainD.size.x/2.0; + mainCenter.y = mainD.orig.y + mainD.size.y/2.0; + } else { + mainD.orig.x = mainCenter.x - mainD.size.x/2.0; + mainD.orig.y = mainCenter.y - mainD.size.y/2.0; + } ConstraintOrig( &mainD.orig, mainD.size ); MainRedraw(); tempD.orig = mainD.orig; @@ -1783,22 +1812,32 @@ EXPORT void DoZoomUp( void * mode ) long newScale; int i; - if ( mode != NULL || (MyGetKeyState()&WKEY_SHIFT) == 0 ) { + if ( mode != NULL || (MyGetKeyState()&WKEY_SHIFT) == 0) { i = ScaleInx( mainD.scale ); + if (i < 0) i = NearestScaleInx(mainD.scale, TRUE); /* * Zooming into macro mode happens when we are at scale 1:1. * To jump into macro mode, the CTRL-key has to be pressed and held. */ if( mainD.scale != 1.0 || (mainD.scale == 1.0 && (MyGetKeyState()&WKEY_CTRL))) { - if( i ) + if( i ) { + if (mainD.scale <=1.0) + InfoMessage(_("Macro Zoom Mode")); + else + InfoMessage(_("Use Shift+PageDwn to jump to preset Zoom In")); DoNewScale( zoomList[ i - 1 ].value ); + + } else InfoMessage("Min Macro Zoom"); + } else { + InfoMessage(_("Scale 1:1 - Use Ctrl+PageDwn to go to Macro Zoom Mode")); } } else if ( (MyGetKeyState()&WKEY_CTRL) == 0 ) { wPrefGetInteger( "misc", "zoomin", &newScale, 4 ); + InfoMessage(_("Preset Zoom In Value selected. Shift+Ctrl+PageDwn to reset value")); DoNewScale( newScale ); } else { wPrefSetInteger( "misc", "zoomin", (long)mainD.scale ); - InfoMessage( _("Zoom In Program Value %ld:1"), (long)mainD.scale ); + InfoMessage( _("Zoom In Program Value %ld:1, Shift+PageDwn to use"), (long)mainD.scale ); } } @@ -1816,15 +1855,21 @@ EXPORT void DoZoomDown( void * mode) if ( mode != NULL || (MyGetKeyState()&WKEY_SHIFT) == 0 ) { i = ScaleInx( mainD.scale ); - if( i>= 0 && i < ( sizeof zoomList/sizeof zoomList[0] - 1 )) - DoNewScale( zoomList[ i + 1 ].value ); + if (i < 0) i = NearestScaleInx(mainD.scale, TRUE); + if( i>= 0 && i < ( sizeof zoomList/sizeof zoomList[0] - 1 )) { + InfoMessage(_("Use Shift+PageUp to jump to preset Zoom Out")); + DoNewScale( zoomList[ i + 1 ].value ); + } else + InfoMessage(_("At Maximum Zoom Out")); + } else if ( (MyGetKeyState()&WKEY_CTRL) == 0 ) { wPrefGetInteger( "misc", "zoomout", &newScale, 16 ); + InfoMessage(_("Preset Zoom Out Value selected. Shift+Ctrl+PageUp to reset value")); DoNewScale( newScale ); } else { wPrefSetInteger( "misc", "zoomout", (long)mainD.scale ); - InfoMessage( _("Zoom Out Program Value %ld:1"), (long)mainD.scale ); + InfoMessage( _("Zoom Out Program Value %ld:1 set, Shift+PageUp to use"), (long)mainD.scale ); } } @@ -1911,12 +1956,6 @@ LOG( log_pan, 2, ( "NEW = [ %0.3f, %0.3f ] \n", pos.x, pos.y ) ) if (!liveMap) MainRedraw(); LOG( log_pan, 1, ( "FINAL = [ %0.3f, %0.3f ]\n", pos.x, pos.y ) ) -#ifdef LATER - if (recordF) { - fprintf( recordF, "ORIG %0.3f %0.3f %0.3f\n", - mainD.scale, mainD.orig.x, mainD.orig.y ); - } -#endif mode = noPan; break; @@ -1928,11 +1967,6 @@ LOG( log_pan, 1, ( "FINAL = [ %0.3f, %0.3f ]\n", pos.x, pos.y ) ) DrawHilight( &mapD, mainD.orig, mainD.size ); newOrig = pos; oldOrig = newOrig; -#ifdef LATER - xscale = INIT_MAP_SCALE; - size.x = mapD.size.x/xscale; - size.y = mapD.size.y/xscale; -#endif xscale = 1; size.x = mainD.size.x/mainD.scale; size.y = mainD.size.y/mainD.scale; @@ -2001,43 +2035,48 @@ LOG( log_pan, 1, ( "FINAL = [ %0.3f, %0.3f ]\n", pos.x, pos.y ) ) return; case wAccelKey_F5: MainRedraw(); + MapRedraw(); return; #endif case wAccelKey_Right: - DrawHilight( &mapD, mainD.orig, mainD.size ); + //DrawHilight( &mapD, mainD.orig, mainD.size ); mainD.orig.x += mainD.size.x/2; ConstraintOrig( &mainD.orig, mainD.size ); mainCenter.x = mainD.orig.x + mainD.size.x/2.0; mainCenter.y = mainD.orig.y + mainD.size.y/2.0; MainRedraw(); - DrawHilight( &mapD, mainD.orig, mainD.size ); + MapRedraw(); + //DrawHilight( &mapD, mainD.orig, mainD.size ); break; case wAccelKey_Left: - DrawHilight( &mapD, mainD.orig, mainD.size ); + //DrawHilight( &mapD, mainD.orig, mainD.size ); mainD.orig.x -= mainD.size.x/2; ConstraintOrig( &mainD.orig, mainD.size ); mainCenter.x = mainD.orig.x + mainD.size.x/2.0; mainCenter.y = mainD.orig.y + mainD.size.y/2.0; MainRedraw(); - DrawHilight( &mapD, mainD.orig, mainD.size ); + MapRedraw(); + //DrawHilight( &mapD, mainD.orig, mainD.size ); break; case wAccelKey_Up: - DrawHilight( &mapD, mainD.orig, mainD.size ); + //DrawHilight( &mapD, mainD.orig, mainD.size ); mainD.orig.y += mainD.size.y/2; ConstraintOrig( &mainD.orig, mainD.size ); mainCenter.x = mainD.orig.x + mainD.size.x/2.0; mainCenter.y = mainD.orig.y + mainD.size.y/2.0; MainRedraw(); - DrawHilight( &mapD, mainD.orig, mainD.size ); + MapRedraw(); + //DrawHilight( &mapD, mainD.orig, mainD.size ); break; case wAccelKey_Down: - DrawHilight( &mapD, mainD.orig, mainD.size ); + //DrawHilight( &mapD, mainD.orig, mainD.size ); mainD.orig.y -= mainD.size.y/2; ConstraintOrig( &mainD.orig, mainD.size ); mainCenter.x = mainD.orig.x + mainD.size.x/2.0; mainCenter.y = mainD.orig.y + mainD.size.y/2.0; MainRedraw(); - DrawHilight( &mapD, mainD.orig, mainD.size ); + MapRedraw(); + //DrawHilight( &mapD, mainD.orig, mainD.size ); break; default: return; @@ -2167,6 +2206,12 @@ static void DoMouse( wAction_t action, coOrd pos ) break; case wActionExtKey: mainD.CoOrd2Pix(&mainD,pos,&x,&y); + if ((MyGetKeyState() & + (WKEY_SHIFT | WKEY_CTRL)) == (WKEY_SHIFT | WKEY_CTRL)) break; //Allow SHIFT+CTRL for Move + if (((action>>8)&0xFF) == wAccelKey_LineFeed) { + action = C_TEXT+((int)(0x0A<<8)); + break; + } switch ((wAccelKey_e)(action>>8)) { case wAccelKey_Del: SelectDelete(); @@ -2180,40 +2225,56 @@ static void DoMouse( wAction_t action, coOrd pos ) break; #endif case wAccelKey_Right: - DrawHilight( &mapD, mainD.orig, mainD.size ); - mainD.orig.x += mainD.size.x/2; + //DrawHilight( &mapD, mainD.orig, mainD.size ); + if ((MyGetKeyState() & WKEY_SHIFT) != 0) + mainD.orig.x += 0.25*mainD.scale; //~1cm in 1::1, 1ft in 30:1, 1mm in 10:1 + else + mainD.orig.x += mainD.size.x/2; ConstraintOrig( &mainD.orig, mainD.size ); mainCenter.x = mainD.orig.x + mainD.size.x/2.0; mainCenter.y = mainD.orig.y + mainD.size.y/2.0; MainRedraw(); - DrawHilight( &mapD, mainD.orig, mainD.size ); + MapRedraw(); + //DrawHilight( &mapD, mainD.orig, mainD.size ); break; case wAccelKey_Left: - DrawHilight( &mapD, mainD.orig, mainD.size ); - mainD.orig.x -= mainD.size.x/2; + //DrawHilight( &mapD, mainD.orig, mainD.size ); + if ((MyGetKeyState() & WKEY_SHIFT) != 0) + mainD.orig.x -= 0.25*mainD.scale; + else + mainD.orig.x -= mainD.size.x/2; ConstraintOrig( &mainD.orig, mainD.size ); mainCenter.x = mainD.orig.x + mainD.size.x/2.0; mainCenter.y = mainD.orig.y + mainD.size.y/2.0; MainRedraw(); - DrawHilight( &mapD, mainD.orig, mainD.size ); + MapRedraw(); + //DrawHilight( &mapD, mainD.orig, mainD.size ); break; case wAccelKey_Up: - DrawHilight( &mapD, mainD.orig, mainD.size ); - mainD.orig.y += mainD.size.y/2; + //DrawHilight( &mapD, mainD.orig, mainD.size ); + if ((MyGetKeyState() & WKEY_SHIFT) != 0) + mainD.orig.y += 0.25*mainD.scale; + else + mainD.orig.y += mainD.size.x/2; ConstraintOrig( &mainD.orig, mainD.size ); mainCenter.x = mainD.orig.x + mainD.size.x/2.0; mainCenter.y = mainD.orig.y + mainD.size.y/2.0; MainRedraw(); - DrawHilight( &mapD, mainD.orig, mainD.size ); + MapRedraw(); + //DrawHilight( &mapD, mainD.orig, mainD.size ); break; case wAccelKey_Down: - DrawHilight( &mapD, mainD.orig, mainD.size ); - mainD.orig.y -= mainD.size.y/2; + //DrawHilight( &mapD, mainD.orig, mainD.size ); + if ((MyGetKeyState() & WKEY_SHIFT) != 0) + mainD.orig.y -= 0.25*mainD.scale; + else + mainD.orig.y -= mainD.size.x/2; ConstraintOrig( &mainD.orig, mainD.size ); mainCenter.x = mainD.orig.x + mainD.size.x/2.0; mainCenter.y = mainD.orig.y + mainD.size.y/2.0; MainRedraw(); - DrawHilight( &mapD, mainD.orig, mainD.size ); + MapRedraw(); + //DrawHilight( &mapD, mainD.orig, mainD.size ); break; default: return; @@ -2222,9 +2283,9 @@ static void DoMouse( wAction_t action, coOrd pos ) InfoPos( pos ); return; case C_TEXT: - if ((action>>8) == 0x0D) + if ((action>>8) == 0x0D) { action = C_OK; - else if ((action>>8) == 0x1B) { + } else if ((action>>8) == 0x1B) { ConfirmReset( TRUE ); return; } @@ -2321,11 +2382,12 @@ static void DoMousew( wDraw_p d, void * context, wAction_t action, wPos_t x, wPo } ConstraintOrig( &orig, mainD.size ); if ( orig.x != mainD.orig.x || orig.y != mainD.orig.y ) { - DrawMapBoundingBox( FALSE ); + //DrawMapBoundingBox( FALSE ); mainD.orig = orig; MainRedraw(); + MapRedraw(); /*DrawSegs( &tempD, zero, 0.0, &tempSegs(0), tempSegs_da.cnt, trackGauge, wDrawColorBlack );*/ - DrawMapBoundingBox( TRUE ); + //DrawMapBoundingBox( TRUE ); wFlush(); } } @@ -2384,8 +2446,10 @@ static void MapDlgUpdate( static void DrawChange( long changes ) { - if (changes & CHANGE_MAIN) + if (changes & CHANGE_MAIN) { MainRedraw(); + MapRedraw(); + } if (changes &CHANGE_UNITS) SetInfoBar(); if (changes & CHANGE_MAP) @@ -2397,9 +2461,10 @@ EXPORT void DrawInit( int initialZoom ) { wPos_t w, h; + wWinGetSize( mainW, &w, &h ); /*LayoutToolBar();*/ - h -= toolbarHeight+infoHeight; + h = h - (toolbarHeight+max(textHeight,infoHeight)+10); if ( w <= 0 ) w = 1; if ( h <= 0 ) h = 1; tempD.d = mainD.d = wDrawCreate( mainW, 0, toolbarHeight, "", BD_TICKS, @@ -2454,3 +2519,170 @@ EXPORT void DrawInit( int initialZoom ) wAttachAccelKey( wAccelKey_Pgdn, 0, (wAccelKeyCallBack_p)doZoomDown, NULL ); #endif } + +#include "bitmaps/pan.xpm" + +static STATUS_T CmdPan( + wAction_t action, + coOrd pos ) +{ + static enum { PAN, ZOOM, NONE } panmode; + + static coOrd base, size; + + DIST_T scale_x,scale_y; + + static coOrd start_pos; + if ( action == C_DOWN ) { + panmode = PAN; + } else if ( action == C_RDOWN) { + panmode = ZOOM; + } + + switch (action&0xFF) { + case C_START: + start_pos = zero; + panmode = NONE; InfoMessage(_("Left Drag to Pan, Right Drag to Zoom, 0 to set Origin to 0,0, 1-9 to Zoom#, e to set to Extent")); + break; + case C_DOWN: + panmode = PAN; + start_pos = pos; + InfoMessage(_("Pan Mode - drag point to new position")); + break; + case C_RDOWN: + panmode = ZOOM; + start_pos = pos; + base = pos; + size = zero; + InfoMessage(_("Zoom Mode - drag Area to Zoom")); + break; + case C_MOVE: + if (panmode == PAN) { + double min_inc; + if (mainD.scale >= 1.0) { + if (units == UNITS_ENGLISH) { + min_inc = 1/4; //>1:1 = 1/4 inch + } else { + min_inc = 1/(2.54*2); //>1:1 = 0.5 cm + } + } else { + if (units == UNITS_ENGLISH) { + min_inc = 1/64; //<1:1 = 1/64 inch + } else { + min_inc = 1/(25.4*2); //>1:1 = 0.5 mm + } + } + if ((fabs(pos.x-start_pos.x) > min_inc) || (fabs(pos.y-start_pos.y) > min_inc)) { + DrawMapBoundingBox( TRUE ); + mainD.orig.x -= (pos.x - start_pos.x); + mainD.orig.y -= (pos.y - start_pos.y); + ConstraintOrig( &mainD.orig, mainD.size ); + tempD.orig = mainD.orig; + mainCenter.x = mainD.orig.x + mainD.size.x/2.0; + mainCenter.y = mainD.orig.y + mainD.size.y/2.0; + DrawMapBoundingBox( TRUE ); + } + } + MainRedraw(); + break; + case C_RMOVE: + if (panmode == ZOOM) { + base = start_pos; + size.x = pos.x - base.x; + if (size.x < 0) { + size.x = - size.x ; + base.x = pos.x; + } + size.y = pos.y - base.y; + if (size.y < 0) { + size.y = - size.y; + base.y = pos.y; + } + } + MainRedraw(); + break; + case C_RUP: + + scale_x = size.x/mainD.size.x*mainD.scale; + scale_y = size.y/mainD.size.y*mainD.scale; + + if (scale_x<scale_y) + scale_x = scale_y; + if (scale_x>1) scale_x = ceil( scale_x ); + else scale_x = 1/(ceil(1/scale_x)); + + if (scale_x > MAX_MAIN_SCALE) scale_x = MAX_MAIN_SCALE; + if (scale_x < MIN_MAIN_MACRO) scale_x = MIN_MAIN_MACRO; + + mainCenter.x = base.x + size.x/2.0; //Put center for scale in center of square + mainCenter.y = base.y + size.y/2.0; + mainD.orig.x = base.x; + mainD.orig.y = base.y; + + panmode = NONE; + DoNewScale(scale_x); + MapRedraw(); + break; + case C_UP: + panmode = NONE; + break; + case C_REDRAW: + if (panmode == ZOOM) { + if (base.x && base.y && size.x && size.y) + DrawHilight( &mainD, base, size ); + } + break; + case C_CANCEL: + base = zero; + return C_TERMINATE; + case C_TEXT: + panmode = NONE; + if ((action>>8) == 0x65) { //"e" + scale_x = mapD.size.x/(mainD.size.x/mainD.scale); + scale_y = mapD.size.y/(mainD.size.y/mainD.scale); + if (scale_x<scale_y) + scale_x = scale_y; + scale_x = ceil(scale_x); + if (scale_x < 1) scale_x = 1; + if (scale_x > MAX_MAIN_SCALE) scale_x = MAX_MAIN_SCALE; + mainD.orig = zero; + mainCenter.x = mainD.orig.x + mapD.size.x/2.0; + mainCenter.y = mainD.orig.y + mapD.size.y/2.0; + DoNewScale(scale_x); + ConstraintOrig( &mainD.orig, mainD.size ); + mainCenter.x = mainD.orig.x + mainD.size.x/2.0; + mainCenter.y = mainD.orig.y + mainD.size.y/2.0; + MapRedraw(); + MainRedraw(); + } + if ((action>>8) == 0x30) { //"0" + mainD.orig = zero; + ConstraintOrig( &mainD.orig, mainD.size ); + mainCenter.x = mainD.orig.x + mainD.size.x/2.0; + mainCenter.y = mainD.orig.y + mainD.size.y/2.0; + MapRedraw(); + MainRedraw(); + } + if ((action>>8) >= 0x31 && (action>>8) <= 0x39) { //"1" to "9" + scale_x = (action>>8)&0x0F; + DoNewScale(scale_x); + MapRedraw(); + MainRedraw(); + } + if ((action>>8) == 0x0D) { + return C_TERMINATE; + } + else if ((action>>8) == 0x1B) { + return C_TERMINATE; + } + break; + } + + return C_CONTINUE; +} + +EXPORT void InitCmdPan( wMenu_p menu ) +{ + panCmdInx = AddMenuButton( menu, CmdPan, "cmdPan", _("Pan/Zoom"), wIconCreatePixMap(pan_xpm), + LEVEL0, IC_CANCEL|IC_POPUP|IC_LCLICK|IC_RCLICK|IC_CMDMENU, ACCL_PAN, NULL ); +} |