summaryrefslogtreecommitdiff
path: root/app/bin/cnote.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/bin/cnote.c')
-rw-r--r--app/bin/cnote.c409
1 files changed, 409 insertions, 0 deletions
diff --git a/app/bin/cnote.c b/app/bin/cnote.c
new file mode 100644
index 0000000..88c9986
--- /dev/null
+++ b/app/bin/cnote.c
@@ -0,0 +1,409 @@
+/*
+ * $Header: /home/dmarkle/xtrkcad-fork-cvs/xtrkcad/app/bin/cnote.c,v 1.6 2008-03-10 18:59:53 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 "i18n.h"
+
+/*****************************************************************************
+ *
+ * NOTE
+ *
+ */
+
+static TRKTYP_T T_NOTE = -1;
+
+static wDrawBitMap_p note_bm;
+struct extraData {
+ coOrd pos;
+ char * text;
+ };
+
+extern BOOL_T inDescribeCmd;
+
+#define NOTEHIDE "CNOTE HIDE"
+#define NOTEDONE "CNOTE DONE"
+
+static char * mainText = NULL;
+static wWin_p noteW;
+
+static paramTextData_t noteTextData = { 300, 150 };
+static paramData_t notePLs[] = {
+#define I_NOTETEXT (0)
+#define noteT ((wText_p)notePLs[I_NOTETEXT].control)
+ { PD_TEXT, NULL, "text", PDO_DLGRESIZE, &noteTextData } };
+static paramGroup_t notePG = { "note", 0, notePLs, sizeof notePLs/sizeof notePLs[0] };
+
+
+static track_p NewNote( wIndex_t index, coOrd p, long size )
+{
+ track_p t;
+ struct extraData * xx;
+ t = NewTrack( index, T_NOTE, 0, sizeof *xx );
+ xx = GetTrkExtraData(t);
+ xx->pos = p;
+ xx->text = (char*)MyMalloc( (int)size + 2 );
+ SetBoundingBox( t, p, p );
+ return t;
+}
+
+void ClearNote( void )
+{
+ if (mainText) {
+ MyFree(mainText);
+ mainText = NULL;
+ }
+}
+
+static void NoteOk( void * junk )
+{
+ int len;
+ if ( wTextGetModified(noteT) ) {
+ ClearNote();
+ len = wTextGetSize( noteT );
+ mainText = (char*)MyMalloc( len+2 );
+ wTextGetText( noteT, mainText, len );
+ if (mainText[len-1] != '\n') {
+ mainText[len++] = '\n';
+ }
+ mainText[len] = '\0';
+ }
+ wHide( noteW );
+}
+
+
+void DoNote( void )
+{
+ if ( noteW == NULL ) {
+ noteW = ParamCreateDialog( &notePG, MakeWindowTitle(_("Note")), _("Ok"), NoteOk, NULL, FALSE, NULL, F_RESIZE, NULL );
+ }
+ wTextClear( noteT );
+ wTextAppend( noteT, mainText?mainText:_("Replace this text with your layout notes") );
+ wTextSetReadonly( noteT, FALSE );
+ wShow( noteW );
+}
+
+
+
+/*****************************************************************************
+ * NOTE OBJECT
+ */
+
+static void DrawNote( track_p t, drawCmd_p d, wDrawColor color )
+{
+ struct extraData *xx = GetTrkExtraData(t);
+ coOrd p[4];
+ DIST_T dist;
+ if (d->scale >= 16)
+ return;
+ if ( (d->funcs->options & wDrawOptTemp) == 0 ) {
+ DrawBitMap( d, xx->pos, note_bm, color );
+ } else {
+ dist = 0.1*d->scale;
+ p[0].x = p[1].x = xx->pos.x-dist;
+ p[2].x = p[3].x = xx->pos.x+dist;
+ p[1].y = p[2].y = xx->pos.y-dist;
+ p[3].y = p[0].y = xx->pos.y+dist;
+ DrawLine( d, p[0], p[1], 0, color );
+ DrawLine( d, p[1], p[2], 0, color );
+ DrawLine( d, p[2], p[3], 0, color );
+ DrawLine( d, p[3], p[0], 0, color );
+ }
+}
+
+static DIST_T DistanceNote( track_p t, coOrd * p )
+{
+ struct extraData *xx = GetTrkExtraData(t);
+ DIST_T d;
+ d = FindDistance( *p, xx->pos );
+ if (d < 1.0)
+ return d;
+ return 100000.0;
+}
+
+
+static struct {
+ coOrd pos;
+ } noteData;
+typedef enum { OR, LY, TX } noteDesc_e;
+static descData_t noteDesc[] = {
+/*OR*/ { DESC_POS, N_("Position"), &noteData.pos },
+/*LY*/ { DESC_LAYER, N_("Layer"), NULL },
+/*TX*/ { DESC_TEXT, NULL, NULL },
+ { DESC_NULL } };
+
+static void UpdateNote( track_p trk, int inx, descData_p descUpd, BOOL_T needUndoStart )
+{
+ struct extraData *xx = GetTrkExtraData(trk);
+ int len;
+
+ switch ( inx ) {
+ case OR:
+ UndrawNewTrack( trk );
+ xx->pos = noteData.pos;
+ SetBoundingBox( trk, xx->pos, xx->pos );
+ DrawNewTrack( trk );
+ break;
+ case -1:
+ if ( wTextGetModified((wText_p)noteDesc[TX].control0) ) {
+ if ( needUndoStart )
+ UndoStart( _("Change Track"), "Change Track" );
+ UndoModify( trk );
+ MyFree( xx->text );
+ len = wTextGetSize( (wText_p)noteDesc[TX].control0 );
+ xx->text = (char*)MyMalloc( len+2 );
+ wTextGetText( (wText_p)noteDesc[TX].control0, xx->text, len );
+ if (xx->text[len-1] != '\n') {
+ xx->text[len++] = '\n';
+ }
+ xx->text[len] = '\0';
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+
+static void DescribeNote( track_p trk, char * str, CSIZE_T len )
+{
+ struct extraData * xx = GetTrkExtraData(trk);
+
+ strcpy( str, _("Note: ") );
+ len -= strlen(_("Note: "));
+ str += strlen(_("Note: "));
+ strncpy( str, xx->text, len );
+ for (;*str;str++) {
+ if (*str=='\n')
+ *str = ' ';
+ }
+ noteData.pos = xx->pos;
+ noteDesc[TX].valueP = xx->text;
+ noteDesc[OR].mode = 0;
+ noteDesc[TX].mode = 0;
+ noteDesc[LY].mode = DESC_RO;
+ DoDescribe( _("Note"), trk, noteDesc, UpdateNote );
+}
+
+static void DeleteNote( track_p t )
+{
+ struct extraData *xx = GetTrkExtraData(t);
+ if (xx->text)
+ MyFree( xx->text );
+}
+
+static BOOL_T WriteNote( track_p t, FILE * f )
+{
+ struct extraData *xx = GetTrkExtraData(t);
+ int len;
+ BOOL_T addNL = FALSE;
+ BOOL_T rc = TRUE;
+ len = strlen(xx->text);
+ if ( xx->text[len-1] != '\n' ) {
+ len++;
+ addNL = TRUE;
+ }
+ rc &= fprintf(f, "NOTE %d %d 0 0 %0.6f %0.6f 0 %d\n", GetTrkIndex(t), GetTrkLayer(t),
+ xx->pos.x, xx->pos.y, len )>0;
+ rc &= fprintf(f, "%s%s", xx->text, addNL?"\n":"" )>0;
+ rc &= fprintf(f, " END\n")>0;
+ return rc;
+}
+
+
+static void ReadNote( char * line )
+{
+ coOrd pos;
+ DIST_T elev;
+ CSIZE_T size;
+ char * cp;
+ track_p t;
+ struct extraData *xx;
+ int len;
+ wIndex_t index;
+ wIndex_t layer;
+ int lineCount;
+
+ if ( strncmp( line, "NOTE MAIN", 9 ) == 0 ){
+ if ( !GetArgs( line+9, paramVersion<3?"d":"0000d", &size ) )
+ return;
+ if (mainText)
+ MyFree( mainText );
+ mainText = (char*)MyMalloc( size+2 );
+ cp = mainText;
+ } else {
+ if ( !GetArgs( line+5, paramVersion<3?"XXpYd":paramVersion<9?"dL00pYd":"dL00pfd",
+ &index, &layer, &pos, &elev, &size ) ) {
+ return;
+ }
+ t = NewNote( index, pos, size+2 );
+ SetTrkLayer( t, layer );
+ xx = GetTrkExtraData(t);
+ cp = xx->text;
+ }
+ lineCount = 0;
+ while (1) {
+ line = GetNextLine();
+ if (strncmp(line, " END", 7) == 0)
+ break;
+ len = strlen(line);
+ if (size > 0 && size < len) {
+ InputError( "NOTE text overflow", TRUE );
+ size = -1;
+ }
+ if (size > 0) {
+ if ( lineCount != 0 ) {
+ strcat( cp, "\n" );
+ cp++;
+ size--;
+ }
+ strcpy( cp, line );
+ cp += len;
+ size -= len;
+ }
+ lineCount++;
+ }
+ if (cp[-1] != '\n')
+ *cp++ = '\n';
+ *cp = '\0';
+}
+
+
+static void MoveNote( track_p trk, coOrd orig )
+{
+ struct extraData * xx = GetTrkExtraData( trk );
+ xx->pos.x += orig.x;
+ xx->pos.y += orig.y;
+ SetBoundingBox( trk, xx->pos, xx->pos );
+}
+
+
+static void RotateNote( track_p trk, coOrd orig, ANGLE_T angle )
+{
+ struct extraData * xx = GetTrkExtraData( trk );
+ Rotate( &xx->pos, orig, angle );
+ SetBoundingBox( trk, xx->pos, xx->pos );
+}
+
+static void RescaleNote( track_p trk, FLOAT_T ratio )
+{
+ struct extraData * xx = GetTrkExtraData( trk );
+ xx->pos.x *= ratio;
+ xx->pos.y *= ratio;
+}
+
+
+static trackCmd_t noteCmds = {
+ "NOTE",
+ DrawNote,
+ DistanceNote,
+ DescribeNote,
+ DeleteNote,
+ WriteNote,
+ ReadNote,
+ MoveNote,
+ RotateNote,
+ RescaleNote,
+ NULL, /* audit */
+ NULL, /* getAngle */
+ NULL, /* split */
+ NULL, /* traverse */
+ NULL, /* enumerate */
+ NULL /* redraw */ };
+
+
+BOOL_T WriteMainNote( FILE* f )
+{
+ BOOL_T rc = TRUE;
+ if (mainText && *mainText) {
+ rc &= fprintf(f, "NOTE MAIN 0 0 0 0 %d\n", strlen(mainText) )>0;
+ rc &= fprintf(f, "%s", mainText )>0;
+ rc &= fprintf(f, " END\n")>0;
+ }
+ return rc;
+}
+
+/*****************************************************************************
+ * NOTE COMMAND
+ */
+
+
+
+static STATUS_T CmdNote( wAction_t action, coOrd pos )
+{
+ static coOrd oldPos;
+ track_p trk;
+ struct extraData * xx;
+ const char* tmpPtrText;
+
+ switch (action) {
+ case C_START:
+ InfoMessage( _("Place a note on the layout") );
+ return C_CONTINUE;
+ case C_DOWN:
+ DrawBitMap( &tempD, pos, note_bm, normalColor );
+ oldPos = pos;
+ return C_CONTINUE;
+ case C_MOVE:
+ DrawBitMap( &tempD, oldPos, note_bm, normalColor );
+ DrawBitMap( &tempD, pos, note_bm, normalColor );
+ oldPos = pos;
+ return C_CONTINUE;
+ break;
+ case C_UP:
+ UndoStart( _("New Note"), "New Note" );
+ trk = NewNote( -1, pos, 2 );
+ DrawNewTrack( trk );
+ xx = GetTrkExtraData(trk);
+
+ tmpPtrText = _("Replace this text with your note");
+ xx->text = (char*)MyMalloc( strlen(tmpPtrText) + 1 );
+ strcpy( xx->text, tmpPtrText);
+
+ inDescribeCmd = TRUE;
+ DescribeNote( trk, message, sizeof message );
+ inDescribeCmd = FALSE;
+ return C_CONTINUE;
+ case C_REDRAW:
+ DrawBitMap( &tempD, oldPos, note_bm, normalColor );
+ return C_CONTINUE;
+ case C_CANCEL:
+ DescribeCancel();
+ return C_CONTINUE;
+ }
+ return C_INFO;
+}
+
+
+#include "bitmaps/note.xbm"
+#include "bitmaps/cnote.xpm"
+
+void InitCmdNote( wMenu_p menu )
+{
+ ParamRegister( &notePG );
+ AddMenuButton( menu, CmdNote, "cmdNote", _("Note"), wIconCreatePixMap(cnote_xpm), LEVEL0_50, IC_POPUP2, ACCL_NOTE, NULL );
+}
+
+void InitTrkNote( void )
+{
+ note_bm = wDrawBitMapCreate( mainD.d, note_width, note_width, 8, 8, note_bits );
+ T_NOTE = InitObject( &noteCmds );
+}