summaryrefslogtreecommitdiff
path: root/app/bin/draw.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/bin/draw.c')
-rw-r--r--app/bin/draw.c684
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 );
+}