summaryrefslogtreecommitdiff
path: root/documentation/editor.html
diff options
context:
space:
mode:
Diffstat (limited to 'documentation/editor.html')
-rw-r--r--documentation/editor.html673
1 files changed, 361 insertions, 312 deletions
diff --git a/documentation/editor.html b/documentation/editor.html
index 236bc8162..565ba5ee0 100644
--- a/documentation/editor.html
+++ b/documentation/editor.html
@@ -1,25 +1,35 @@
-<HTML><BODY>
-<H1 ALIGN=RIGHT><A NAME=editor>4 - Designing a Simple Text Editor</A></H1>
-This chapter takes you through the design of a simple FLTK-based text
-editor.
+<HTML>
+<BODY>
+
+<H1 ALIGN="RIGHT"><A NAME="editor">4 - Designing a Simple Text Editor</A></H1>
+
+<P>This chapter takes you through the design of a simple
+FLTK-based text editor.
+
<H2>Determining the Goals of the Text Editor</H2>
- Since this will be the first big project you'll be doing with FLTK,
-lets define what we want our text editor to do:
+
+<P>Since this will be the first big project you'll be doing with FLTK,
+lets define what we want our text editor to do:
+
<OL>
-<LI>Menubar/menus for all functions. </LI>
-<LI>Edit a single text file. </LI>
-<LI>Load from a file. </LI>
-<LI>Save to a file. </LI>
-<LI>Cut/copy/delete/paste functions. </LI>
-<LI>Search and replace functions. </LI>
-<LI>Keep track of when the file has been changed. </LI>
+
+ <LI>Provide a menubar/menus for all functions.</LI>
+ <LI>Edit a single text file, possibly with multiple views.</LI>
+ <LI>Load from a file.</LI>
+ <LI>Save to a file.</LI>
+ <LI>Cut/copy/delete/paste functions.</LI>
+ <LI>Search and replace functions.</LI>
+ <LI>Keep track of when the file has been changed.</LI>
+
</OL>
+
<H2>Designing the Main Window</H2>
-Now that we've outlined the goals for our editor, we can begin with
-the design of our GUI. Obviously the first thing that we need is a
-window:
-<UL>
-<PRE>
+
+<P>Now that we've outlined the goals for our editor, we can begin with
+the design of our GUI. Obviously the first thing that we need is a
+window, which we'll place inside a class called <TT>EditorWindow</TT>:
+
+<UL><PRE>
class EditorWindow : public Fl_Double_Window {
public:
EditorWindow(int w, int h, const char* t);
@@ -35,29 +45,31 @@ class EditorWindow : public Fl_Double_Window {
Fl_Text_Editor *editor;
char search[256];
};
-</PRE>
-</UL>
+</PRE></UL>
+
<H2>Variables</H2>
-Our text editor will need some global variables to keep track of
-things:
-<UL>
-<PRE>
-int changed = 0;
-char filename[1024] = &quot;&quot;;
-char search[256] = &quot;&quot;;
-Fl_Text_Buffer *textbuf;
-</PRE>
-</UL>
-The <TT>textbuf</TT> variable is the text editor buffer for our
-window described previously. We'll cover the other variables as
-we build the application.
+
+<P>Our text editor will need some global variables to keep track of
+things:
+
+<UL><PRE>
+int changed = 0;
+char filename[256] = &quot;&quot;;
+Fl_Text_Buffer *textbuf;
+</PRE></UL>
+
+<P>The <TT>textbuf</TT> variable is the text editor buffer for
+our window class described previously. We'll cover the other
+variables as we build the application.</P>
+
<H2>Menubars and Menus</H2>
-The first goal requires us to use a menubar and menus that define each
-function the editor needs to perform. The <A href=Fl_Menu_Item.html#Fl_Menu_Item>
-<TT>Fl_Menu_Item</TT></A> structure is used to define the menus and
-items in a menubar:
-<UL>
-<PRE>
+
+<P>The first goal requires us to use a menubar and menus that
+define each function the editor needs to perform. The <A
+href="Fl_Menu_Item.html"><TT>Fl_Menu_Item</TT></A> structure is
+used to define the menus and items in a menubar:</P>
+
+<UL><PRE>
Fl_Menu_Item menuitems[] = {
{ "&amp;File", 0, 0, 0, FL_SUBMENU },
{ "&amp;New File", 0, (Fl_Callback *)new_cb },
@@ -87,237 +99,262 @@ Fl_Menu_Item menuitems[] = {
{ 0 }
};
-</PRE>
-</UL>
-Once we have the menus defined we can create the <TT>Fl_Menu_Bar</TT>
-widget and assign the menus to it with:
-<UL>
-<PRE>
+</PRE></UL>
+
+<P>Once we have the menus defined we can create the
+<TT>Fl_Menu_Bar</TT> widget and assign the menus to it with:</P>
+
+<UL><PRE>
Fl_Menu_Bar *m = new Fl_Menu_Bar(0, 0, 512, 30);
m-&gt;copy(menuitems);
-</PRE>
-</UL>
-We'll define the callback functions later.
+</PRE></UL>
+
+<P>We'll define the callback functions later.
+
<H2>Editing the Text</H2>
-To keep things simple our text editor will use the
-<A HREF="Fl_Text_Editor.html#Fl_Text_Editor"><TT>Fl_Text_Editor</TT></A>
-widget to edit the text:
-<UL>
-<PRE>
+
+<P>To keep things simple our text editor will use the
+<A HREF="Fl_Text_Editor.html"><TT>Fl_Text_Editor</TT></A>
+widget to edit the text:
+
+<UL><PRE>
w->editor = new Fl_Text_Editor(0, 30, 512, 354);
w->editor->buffer(textbuf);
-</PRE>
-</UL>
-So that we can keep track of changes to the file, we also want to add
-a &quot;modify&quot; callback:
-<UL>
-<PRE>
+</PRE></UL>
+
+<P>So that we can keep track of changes to the file, we also want to add
+a &quot;modify&quot; callback:</P>
+
+<UL><PRE>
textbuf->add_modify_callback(changed_cb, w);
textbuf->call_modify_callbacks();
-</PRE>
-</UL>
-Finally, we want to use a mono-spaced font like <TT>FL_COURIER</TT>:
-<UL>
-<PRE>
+</PRE></UL>
+
+<P>Finally, we want to use a mono-spaced font like <TT>FL_COURIER</TT>:
+
+<UL><PRE>
w->editor->textfont(FL_COURIER);
-</PRE>
-</UL>
+</PRE></UL>
+
<H2>The Replace Dialog</H2>
-We can use the FLTK convenience functions for many of the editor's
-dialogs, however the replace dialog needs its own custom window. To
-keep things simple we will have a &quot;find&quot; string, a &quot;replace&quot; string,
-and &quot;replace all&quot;, &quot;replace next&quot;, and &quot;cancel&quot; buttons. The strings
-are just <TT>Fl_Input</TT> widgets, the &quot;replace all&quot; and &quot;cancel&quot;
-buttons are <TT>Fl_Button</TT> widgets, and the &quot;replace next &quot; button
-is a <TT>Fl_Return_Button</TT> widget:
-<P ALIGN=CENTER><IMG src="editor-replace.gif" ALT="The search and replace dialog."></P>
-<UL>
-<PRE>
+
+<P>We can use the FLTK convenience functions for many of the
+editor's dialogs, however the replace dialog needs its own
+custom window. To keep things simple we will have a
+&quot;find&quot; string, a &quot;replace&quot; string, and
+&quot;replace all&quot;, &quot;replace next&quot;, and
+&quot;cancel&quot; buttons. The strings are just
+<TT>Fl_Input</TT> widgets, the &quot;replace all&quot; and
+&quot;cancel&quot; buttons are <TT>Fl_Button</TT> widgets, and
+the &quot;replace next &quot; button is a
+<TT>Fl_Return_Button</TT> widget:</P>
+
+<P ALIGN="CENTER"><IMG src="editor-replace.gif" ALT="The search and replace dialog."><BR>
+<I>Figure 4-1: The search and replace dialog.</I></P>
+
+<UL><PRE>
Fl_Window *replace_dlg = new Fl_Window(300, 105, &quot;Replace&quot;);
Fl_Input *replace_find = new Fl_Input(70, 10, 200, 25, &quot;Find:&quot;);
Fl_Input *replace_with = new Fl_Input(70, 40, 200, 25, &quot;Replace:&quot;);
Fl_Button *replace_all = new Fl_Button(10, 70, 90, 25, &quot;Replace All&quot;);
Fl_Button *replace_next = new Fl_Button(105, 70, 120, 25, &quot;Replace Next&quot;);
Fl_Button *replace_cancel = new Fl_Button(230, 70, 60, 25, &quot;Cancel&quot;);
-</PRE>
-</UL>
+</PRE></UL>
+
<H2>Callbacks</H2>
-Now that we've defined the GUI components of our editor, we need to
-define our callback functions.
+
+<P>Now that we've defined the GUI components of our editor, we
+need to define our callback functions.</P>
+
<H3>changed_cb()</H3>
- This function will be called whenever the user changes any text in the <TT>
-input</TT> widget:
-<UL>
-<PRE>
-void changed_cb(void) {
- set_changed(1);
+
+<P>This function will be called whenever the user changes any text in the
+<TT>editor</TT> widget:
+
+<UL><PRE>
+void changed_cb(int, int nInserted, int nDeleted,int, const char*, void* v) {
+ if ((nInserted || nDeleted) && !loading) changed = 1;
+ EditorWindow *w = (EditorWindow *)v;
+ set_title(w);
+ if (loading) w->editor->show_insert_position();
}
-</PRE>
-</UL>
- The <TT>set_changed()</TT> function is one that we will write to set
-the changed status on the current file. We're doing it this way
-because some of the other callbacks will set the changed status to 0,
-and also because we want to show the changed status in the window's
-title bar.
+</PRE></UL>
+
+<P>The <TT>set_title()</TT> function is one that we will write to set
+the changed status on the current file. We're doing it this way
+because we want to show the changed status in the window's
+title bar.
+
<H3>copy_cb()</H3>
- This callback function will call <A href=Fl_Input_.html#Fl_Input_.copy><TT>
-input-&gt;copy()</TT></A> to copy the currently selected text to the
-clipboard:
-<UL>
-<PRE>
-void copy_cb(void) {
- input-&gt;copy();
+
+<P>This callback function will call <A
+href="Fl_Text_Editor.html#Fl_Text_Editor.kf_copy"><TT>kf_copy()</TT></A>
+to copy the currently selected text to the clipboard:</P>
+
+<UL><PRE>
+void copy_cb(Fl_Widget*, void* v) {
+ EditorWindow* e = (EditorWindow*)v;
+ Fl_Text_Editor::kf_copy(0, e->editor);
}
-</PRE>
-</UL>
+</PRE></UL>
+
<H3>cut_cb()</H3>
- This callback function will call <A href=Fl_Input_.html#Fl_Input_.copy><TT>
-input-&gt;copy()</TT></A> to copy the currently selected text to the
-clipboard and then <A href=Fl_Input_.html#Fl_Input_.cut><TT>input-&gt;cut()</TT>
-</A> to delete it:
-<UL>
-<PRE>
-void cut_cb(void) {
- input-&gt;copy();
- input-&gt;cut();
+
+<P>This callback function will call <A
+href="Fl_Text_Editor.html#Fl_Text_Editor.kf_cut"><TT>kf_cut()</TT></A>
+to cut the currently selected text to the clipboard:</P>
+
+<UL><PRE>
+void cut_cb(Fl_Widget*, void* v) {
+ EditorWindow* e = (EditorWindow*)v;
+ Fl_Text_Editor::kf_cut(0, e->editor);
}
-</PRE>
-</UL>
+</PRE></UL>
+
<H3>delete_cb()</H3>
- This callback function will call <A href=Fl_Input_.html#Fl_Input_.cut><TT>
-input-&gt;cut()</TT></A> to delete the selected text:
-<UL>
-<PRE>
-void delete_cb(void) {
- input-&gt;cut();
+
+<P>This callback function will call <A
+href="Fl_Text_Buffer.html#Fl_Text_Buffer.remove_selection"><TT>remove_selection()</TT></A>
+to delete the currently selected text to the clipboard:</P>
+
+<UL><PRE>
+void delete_cb(Fl_Widget*, void* v) {
+ textbuf->remove_selection();
}
-</PRE>
-</UL>
+</PRE></UL>
+
<H3>find_cb()</H3>
- This callback function asks for a search string using the <A href=functions.html#fl_input2>
-<TT>fl_input()</TT></A> convenience function and then calls the <TT>
-find2_cb()</TT> function to find the string:
-<UL>
-<PRE>
-void find_cb(void) {
+
+<P>This callback function asks for a search string using the <A
+href="functions.html#fl_input2"><TT>fl_input()</TT></A>
+convenience function and then calls the <TT>find2_cb()</TT>
+function to find the string:
+
+<UL><PRE>
+void find_cb(Fl_Widget* w, void* v) {
+ EditorWindow* e = (EditorWindow*)v;
const char *val;
- val = fl_input(&quot;Search String:&quot;, search);
+ val = fl_input("Search String:", e->search);
if (val != NULL) {
// User entered a string - go find it!
- strcpy(search, val);
- find2_cb();
+ strcpy(e->search, val);
+ find2_cb(w, v);
}
-}
-</PRE>
-</UL>
+</PRE></UL>
+
<H3>find2_cb()</H3>
- This function will find the next occurrence of the search string. If
-the search string is blank then we want to pop up the search dialog:
-<UL>
-<PRE>
-void find2_cb(void) {
- const char *val, *found;
- int pos;
-
- if (search[0] == '\0') {
+
+<P>This function will find the next occurrence of the search
+string. If the search string is blank then we want to pop up the
+search dialog:
+
+<UL><PRE>
+void find2_cb(Fl_Widget* w, void* v) {
+ EditorWindow* e = (EditorWindow*)v;
+ if (e->search[0] == '\0') {
// Search string is blank; get a new one...
- find_cb();
+ find_cb(w, v);
return;
}
- val = input-&gt;value() + input-&gt;mark();
- found = strstr(val, search);
-
- if (found != NULL) {
- // Found a match; update the position and mark...
- pos = input-&gt;mark() + found - val;
- input-&gt;position(pos, pos + strlen(search));
+ int pos = e->editor->insert_position();
+ int found = textbuf->search_forward(pos, e->search, &pos);
+ if (found) {
+ // Found a match; select and update the position...
+ textbuf->select(pos, pos+strlen(e->search));
+ e->editor->insert_position(pos+strlen(e->search));
+ e->editor->show_insert_position();
}
- else fl_alert(&quot;No occurrences of \'%s\' found!&quot;, search);
+ else fl_alert("No occurrences of \'%s\' found!", e->search);
}
-</PRE>
-</UL>
- If the search string cannot be found we use the <A href="functions.html#fl_alert"><TT>
-fl_alert()</TT></A> convenience function to display a message to that
-effect.
+</PRE></UL>
+
+<P>If the search string cannot be found we use the <A
+href="functions.html#fl_alert"><TT>fl_alert()</TT></A>
+convenience function to display a message to that effect.
+
<H3>new_cb()</H3>
- This callback function will clear the input widget and current
-filename. It also calls the <TT>check_save()</TT> function to give the
-user the opportunity to save the current file first as needed:
-<UL>
-<PRE>
-void new_cb(void) {
- if (changed)
- if (!check_save()) return;
+<P>This callback function will clear the editor widget and current
+filename. It also calls the <TT>check_save()</TT> function to give the
+user the opportunity to save the current file first as needed:
+
+<UL><PRE>
+void new_cb(Fl_Widget*, void*) {
+ if (!check_save()) return;
filename[0] = '\0';
- input-&gt;value(&quot;&quot;);
- set_changed(0);
+ textbuf->select(0, textbuf->length());
+ textbuf->remove_selection();
+ changed = 0;
+ textbuf->call_modify_callbacks();
}
-</PRE>
-</UL>
+</PRE></UL>
+
<H3>open_cb()</H3>
- This callback function will ask the user for a filename and then load
-the specified file into the input widget and current filename. It also
-calls the <TT>check_save()</TT> function to give the user the
-opportunity to save the current file first as needed:
-<UL>
-<PRE>
-void open_cb(void) {
- char *newfile;
- if (changed)
- if (!check_save()) return;
+<P>This callback function will ask the user for a filename and then load
+the specified file into the input widget and current filename. It also
+calls the <TT>check_save()</TT> function to give the user the
+opportunity to save the current file first as needed:
+
+<UL><PRE>
+void open_cb(Fl_Widget*, void*) {
+ if (!check_save()) return;
- newfile = fl_file_chooser(&quot;Open File?&quot;, &quot;*&quot;, filename);
- if (newfile != NULL) load_file(newfile);
+ char *newfile = fl_file_chooser("Open File?", "*", filename);
+ if (newfile != NULL) load_file(newfile, -1);
}
-</PRE>
-</UL>
- We call the <TT>load_file()</TT> function to actually load the file.
+</PRE></UL>
+
+<P>We call the <TT>load_file()</TT> function to actually load the file.
+
<H3>paste_cb()</H3>
- This callback function will send a FL_PASTE message to the <TT>input</TT>
- widget using the <A href=functions.html#paste><TT>Fl::paste()</TT></A>
- method:
-<UL>
-<PRE>
-void paste_cb(void) {
- Fl::paste(*input);
+
+<P>This callback function will call <A
+href="Fl_Text_Editor.html#Fl_Text_Editor.kf_paste"><TT>kf_paste()</TT></A>
+to paste the clipboard at the current position:</P>
+
+<UL><PRE>
+void paste_cb(Fl_Widget*, void* v) {
+ EditorWindow* e = (EditorWindow*)v;
+ Fl_Text_Editor::kf_paste(0, e->editor);
}
-</PRE>
-</UL>
+</PRE></UL>
+
<H3>quit_cb()</H3>
- The quit callback will first see if the current file has been
-modified, and if so give the user a chance to save it. It then hides
-the main window:
-<UL>
-<PRE>
-void quit_cb(void) {
- if (changed)
- if (!check_save())
- return;
-
- window-&gt;hide();
+
+<P>The quit callback will first see if the current file has been
+modified, and if so give the user a chance to save it. It then exits
+from the program:
+
+<UL><PRE>
+void quit_cb(Fl_Widget*, void*) {
+ if (changed && !check_save())
+ return;
+
+ exit(0);
}
-</PRE>
-</UL>
+</PRE></UL>
+
<H3>replace_cb()</H3>
- The replace callback just shows the replace dialog:
-<UL>
-<PRE>
+
+<P>The replace callback just shows the replace dialog:
+
+<UL><PRE>
void replace_cb(Fl_Widget*, void* v) {
EditorWindow* e = (EditorWindow*)v;
e-&gt;replace_dlg-&gt;show();
}
-</PRE>
-</UL>
+</PRE></UL>
+
<H3>replace2_cb()</H3>
-This callback will replace the next occurence of the replacement
-string. If nothing has been entered for the replacement string, then
-the replace dialog is displayed instead:
-<UL>
-<PRE>
+
+<P>This callback will replace the next occurence of the replacement
+string. If nothing has been entered for the replacement string, then
+the replace dialog is displayed instead:
+
+<UL><PRE>
void replace2_cb(Fl_Widget*, void* v) {
EditorWindow* e = (EditorWindow*)v;
const char *find = e-&gt;replace_find-&gt;value();
@@ -345,13 +382,14 @@ void replace2_cb(Fl_Widget*, void* v) {
}
else fl_alert(&quot;No occurrences of \'%s\' found!&quot;, find);
}
-</PRE>
-</UL>
+</PRE></UL>
+
<H3>replall_cb()</H3>
-This callback will replace all occurences of the search string in the
-file:
-<UL>
-<PRE>
+
+<P>This callback will replace all occurences of the search
+string in the file:
+
+<UL><PRE>
void replall_cb(Fl_Widget*, void* v) {
EditorWindow* e = (EditorWindow*)v;
const char *find = e-&gt;replace_find-&gt;value();
@@ -388,23 +426,25 @@ void replall_cb(Fl_Widget*, void* v) {
if (times) fl_message(&quot;Replaced %d occurrences.&quot;, times);
else fl_alert(&quot;No occurrences of \'%s\' found!&quot;, find);
}
-</PRE>
-</UL>
+</PRE></UL>
+
<H3>replcan_cb()</H3>
-This callback just hides the replace dialog:
-<UL>
-<PRE>
+
+<P>This callback just hides the replace dialog:
+
+<UL><PRE>
void replcan_cb(Fl_Widget*, void* v) {
EditorWindow* e = (EditorWindow*)v;
e-&gt;replace_dlg-&gt;hide();
}
-</PRE>
-</UL>
+</PRE></UL>
+
<H3>save_cb()</H3>
-This callback saves the current file. If the current filename is
-blank it calls the &quot;save as&quot; callback:
-<UL>
-<PRE>
+
+<P>This callback saves the current file. If the current filename is
+blank it calls the &quot;save as&quot; callback:
+
+<UL><PRE>
void save_cb(void) {
if (filename[0] == '\0') {
// No filename - get one!
@@ -413,42 +453,38 @@ void save_cb(void) {
}
else save_file(filename);
}
-</PRE>
-</UL>
- The <TT>save_file()</TT> function saves the current file to the
-specified filename.
+</PRE></UL>
+
+<P>The <TT>save_file()</TT> function saves the current file to the
+specified filename.
+
<H3>saveas_cb()</H3>
- This callback asks the user for a filename and saves the current file:
-<UL>
-<PRE>
+
+<P>This callback asks the user for a filename and saves the current file:
+
+<UL><PRE>
void saveas_cb(void) {
char *newfile;
newfile = fl_file_chooser(&quot;Save File As?&quot;, &quot;*&quot;, filename);
if (newfile != NULL) save_file(newfile);
}
-</PRE>
-</UL>
- The <TT>save_file()</TT> function saves the current file to the
-specified filename.
-<H3>undo_cb()</H3>
- The undo callback just calls the <A href=Fl_Input_.html#Fl_Input_.undo><TT>
-undo()</TT></A> method:
-<UL>
-<PRE>
-void undo_cb(void) {
- input-&gt;undo();
-}
-</PRE>
-</UL>
+</PRE></UL>
+
+<P>The <TT>save_file()</TT> function saves the current file to the
+specified filename.
+
<H2>Other Functions</H2>
- Now that we've defined the callback functions, we need our support
-functions to make it all work:
+
+<P>Now that we've defined the callback functions, we need our support
+functions to make it all work:
+
<H3>check_save()</H3>
- This function checks to see if the current file needs to be saved. If
-so, it asks the user if they want to save it:
-<UL>
-<PRE>
+
+<P>This function checks to see if the current file needs to be saved. If
+so, it asks the user if they want to save it:
+
+<UL><PRE>
int check_save(void) {
if (!changed) return 1;
@@ -463,12 +499,13 @@ int check_save(void) {
return (r == 2) ? 1 : 0;
}
-</PRE>
-</UL>
+</PRE></UL>
+
<H3>load_file()</H3>
- This function loads the specified file into the <TT>input</TT> widget:
-<UL>
-<PRE>
+
+<P>This function loads the specified file into the <TT>textbuf</TT> class:
+
+<UL><PRE>
int loading = 0;
void load_file(char *newfile, int ipos) {
loading = 1;
@@ -485,15 +522,19 @@ void load_file(char *newfile, int ipos) {
loading = 0;
textbuf-&gt;call_modify_callbacks();
}
-</PRE>
-</UL>
-When loading the file we use the
-<A href="Fl_Text_Buffer.html#Fl_Text_Buffer.insertfile"><TT>loadfile()</TT></A>
-method to &quot;replace&quot; the text in the buffer.
+</PRE></UL>
+
+<P>When loading the file we use the <A
+href="Fl_Text_Buffer.html#Fl_Text_Buffer.loadfile"><TT>loadfile()</TT></A>
+method to &quot;replace&quot; the text in the buffer, or the <A
+href="Fl_Text_Buffer.html#Fl_Text_Buffer.insertfile"><TT>insertfile()</TT></A>
+method to insert text in the buffer from the named file.
+
<H3>save_file()</H3>
-This function saves the current buffer to the specified file:
-<UL>
-<PRE>
+
+<P>This function saves the current buffer to the specified file:
+
+<UL><PRE>
void save_file(char *newfile) {
if (textbuf-&gt;savefile(newfile))
fl_alert(&quot;Error writing to file \'%s\':\n%s.&quot;, newfile, strerror(errno));
@@ -502,52 +543,60 @@ void save_file(char *newfile) {
changed = 0;
textbuf-&gt;call_modify_callbacks();
}
-</PRE>
-</UL>
-<H3>set_changed()</H3>
- This function sets the <TT>changed</TT> variable and updates the
-window label accordingly:
-<UL>
-<PRE>
-void set_changed(int c) {
- if (c != changed) {
- char title[1024];
- char *slash;
-
- changed = c;
+</PRE></UL>
- if (filename[0] == '\0') strcpy(title, &quot;Untitled&quot;);
- else {
- slash = strrchr(filename, '/');
- if (slash == NULL) slash = strrchr(filename, '\\');
+<H3>set_title()</H3>
- if (slash != NULL) strcpy(title, slash + 1);
- else strcpy(title, filename);
- }
+<P>This function checks the <TT>changed</TT> variable and updates the
+window label accordingly:
+<UL><PRE>
+void set_title(Fl_Window* w) {
+ if (filename[0] == '\0') strcpy(title, "Untitled");
+ else {
+ char *slash;
+ slash = strrchr(filename, '/');
+#ifdef WIN32
+ if (slash == NULL) slash = strrchr(filename, '\\');
+#endif
+ if (slash != NULL) strcpy(title, slash + 1);
+ else strcpy(title, filename);
+ }
- if (changed) strcat(title, &quot; (modified)&quot;);
+ if (changed) strcat(title, " (modified)");
- window-&gt;label(title);
- }
+ w->label(title);
}
-</PRE>
-</UL>
+</PRE></UL>
+
<H2>Compiling the Editor</H2>
- The complete source for our text editor can be found in the <TT>
-test/editor.cxx</TT> source file. Both the Makefile and Visual C++
-workspace include the necessary rules to build the editor. You can
-also compile it using a standard compiler with:
-<UL>
-<PRE>
+
+<P>The complete source for our text editor can be found in the <TT>test/editor.cxx</TT> source file. Both the Makefile and Visual C++
+workspace include the necessary rules to build the editor. You can
+also compile it using a standard compiler with:
+
+<UL><PRE>
CC -o editor editor.cxx -lfltk -lXext -lX11 -lm
-</PRE>
-</UL>
- As noted in <A href=basics.html#basics>Chapter 1</A>, you may need to
-include compiler and linker options to tell them where to find the FLTK
+</PRE></UL>
+
+<P>or by using the <TT>fltk-config</TT> script with:
+
+<UL><PRE>
+fltk-config --compile editor.cxx
+</PRE></UL>
+
+<P>As noted in <A href="basics.html">Chapter 1</A>, you may need to
+include compiler and linker options to tell them where to find the FLTK
library. Also, the <TT>CC</TT> command may also be called <TT>gcc</TT>
- or <TT>c++</TT> on your system.
-<P>Congratulations, you've just built your own text editor! </P>
+or <TT>c++</TT> on your system.
+
+<P>Congratulations, you've just built your own text editor!</P>
+
<H2>The Final Product</H2>
- The final editor window should look like the image on the next page.
-<P ALIGN=CENTER><IMG src="editor.gif" ALT="The completed editor window."></P>
-</BODY></HTML>
+
+The final editor window should look like the image in Figure 4-2.
+
+<P ALIGN="CENTER"><IMG src="editor.gif" ALT="The completed editor window."><BR>
+<I>Figure 4-2: The completed editor window</I></P>
+
+</BODY>
+</HTML>