GRIDPLUS2 - Example 7 | ![]() |
||||||
|
Example Of a Complete Simple Application |
This is an example of a complete text editor application. This example is mainly intended to demonstrate the GRIDPLUS entry/text clipboard commands, text find facilities, enhanced menu options, window resizing and using (ICONS) icon image files.
This example assumes familiarity with the previous/earlier examples. The more basic GRIDPLUS usage is not described here in full.
Note: PNG icon images require Tcl/Tk 8.6.0 or later. GIF images are supported for Tcl/Tk 8.3 or greater.
User Guide |
Main Window:
The toolbar contains six buttons, each has appropriate pop-up/balloon help:-
![]() | Start a New file. |
![]() | Open an existing file. |
![]() | Save file. |
![]() | Cut selected text. |
![]() | Copy selected text. |
![]() | Paste text from clipboard. |
![]() | Find text matching string entered into entry to the right of this button. |
The following menus are available from the menubar:-
![]() |
![]() |
![]() |
The function of the various options follow general conventions and will not be described here.
The Status shown at the bottom right of the display can have the following values:-
New | New edit - Not yet saved. |
Opened | File opened - Not yet modified. |
Modified | New edit or Opened file - Modified but not saved since modification. |
Saved | Modifications have been saved. |
When a file is opened/saved a screen similar to the following will be displayed:-
The display can be resized in the normal way. A limit is set for the minimum size to which he display can be re-sized (See Comments below) - However, the window can be resized to the maximum allowed by the display.
When the window is reszied to the minimum a screen similar to the following will be displayed:-
If an attempt to Quit the editor, Start a new edit -or- Open a new file while there is a Modified (Unsaved) edit, a dialog similar to the following will be displayed:-
Source Code |
#==========Create/display GUI. proc main {} { gridplus menu . { _File { {_New ~new} {_Open ~openfile} {_Save ~save} {"Save _As" ~saveas} = {_Quit ~quit} } _Edit { {Cu_t ~gpcut} {_Copy ~gpcopy} {_Paste ~gppaste} {_Delete ~gpclear} = {_Find "~gpfind_dialog .text"} = {"_Select All" ~selectall} } _Help { {_About ~about} } } gridplus button .toolbar -style Toolbutton -padding 0 -space 0 -takefocus 0 { {.new :page_add ?New ~new} \ {.open :folder_page ?Open ~openfile} \ {.save :disk ?Save ~save} \ | \ {.cut :cut ?Cut ~gpcut} \ {.copy :page_copy ?Copy ~gpcopy} \ {.paste :page_paste ?Paste ~gppaste} \ | \ {.find :page_find ?Find ~find} \ {&e .find-string 20 # ?Find ~find} } gridplus text .text -command modified -font {courier 8} -scroll xy -width 80 -height 25 -wrap none gridplus widget .statusbar -relief groove -stretch 0 { {"^File: " .file |>| "^Status: " .status} } gridplus layout .main -wtitle gpEdit { v .toolbar:w > .text:nsew .statusbar:ew } gpset { .statusbar,file Untitled .statusbar,status New } gridplus pack .main -resize xy -minx 75 -miny 50 } #==========Clear/initialise for new edit. proc new {} { savemodified gpset { .text {} .statusbar,file Untitled .statusbar,status New } } #==========Open file for editing. proc openfile {} { savemodified set filename [tk_getOpenFile -title "gpEdit: Open File"] if {$filename ne ""} { set file [open $filename r] gpset .text [read $file] close $file gpset .statusbar,file $filename gpset .statusbar,status Opened } } #==========Save text to current file. proc save {} { global {} if {$(.statusbar,file) != "Untitled"} { set file [open $(.statusbar,file) w] puts $file $(.text) close $file } else { saveas } gpset .statusbar,status Saved } #==========Save text to a new file. proc saveas {} { global {} set filename [tk_getSaveFile -title "gpEdit: Save File"] if {$filename ne ""} { set file [open $filename w] puts $file $(.text) close $file gpset .statusbar,file $filename gpset .statusbar,status Saved } } #==========Ask if file to be saved if it is modified. proc savemodified {} { global {} if {$(.statusbar,status) eq "Modified"} { set action [tk_messageBox -message "Save the changes to [file tail $(.statusbar,file)]?" -icon warning -type yesnocancel -title gpEdit] switch -- $action { yes {save} cancel {return -level 2} } } } #==========Find next occurance of specified string in text. proc find {} { global {} gpfind .text $(.toolbar,find-string) } #==========Select all text. proc selectall {} { .text.text tag add sel 1.0 end } #==========Display "About" dialog. proc about {} { tk_messageBox -icon info -title "gpEdit: About" -message "gpEdit - Adrian Davis 2014" -type ok } #==========Set "Modified" status. proc modified {} { global {} gpset .statusbar,status Modified } #==========Quit proc quit {} { savemodified exit } #==========Start application. gpoptions iconFile Icons main
Comments |
proc main {} {
gridplus menu . { _File { {_New ~new} {_Open ~openfile} {_Save ~save} {"Save _As" ~saveas} = {_Quit ~exit} } _Edit { {Cu_t ~gpcut} {_Copy ~gpcopy} {_Paste ~gppaste} {_Delete ~gpclear} = {_Find "~gpfind_dialog .text"} = {"_Select All" ~selectall} } _Help { {_About ~about} } }
The underline characters are used to specify that the character following the underline will be displayed as underlined. The menu option can be selected by pressing the indicated character.
Pressing the "Alt" key will activate menu keyboard traversal.
The gpcut/gpcopy/gppaste/gpclear procudures are GRIDPLUS clipboard/edit commands. As the name of the item to which the command applies is not specified, the commands will operate on the widget which current has focus (if it is either an entry or a text widget). In this case either the ".text" text widget or the ".find,string" entry.
The gpfind_dialog procedure invokes the GRIDPLUS "Find" dialog.
gridplus button .toolbar -style Toolbutton -padding 0 -space 0 -takefocus 0 { {.new :page_add ?New ~new} \ {.open :folder_page ?Open ~openfile} \ {.save :disk ?Save ~save} \ | \ {.cut :cut ?Cut ~gpcut} \ {.copy :page_copy ?Copy ~gpcopy} \ {.paste :page_paste ?Paste ~gppaste} \ | \ {.find :page_find ?Find ~find} \ {&e .find-string 20 # ?Find ~find} }
For Example: "{.new :page_add ?New ~new}".
This button, named ".new", will have the ICONS (FamFamFam) image called "page_add", "New" as the pop-up/balloon help and will invoke a procedure called "new".
Next to the "Find" button is an entry grid called ".find-string" which is "20" characters wide. This content of this entry can be accessed as "$(.toolbar,find-string)". The "~find" option causes the "find" procedure to be invoked if the Enter/Return key is pressed while the entry has keyboard focus. The "#" widget option specifies the style to be used for the entry. In this case the name is null, which causes the default style to be used instead of "Toolbutton".
The gpcut/gpcopy/gppaste procudures are GRIDPLUS clipboard/edit commands. As the name of the item to which the command applies is not specified, the commands will operate on the widget which current has focus (if it is either an entry or a text widget). In this case either the ".text" text widget or the ".find,string" entry.
gridplus text .text -command modified -font {courier 8} -scroll xy -width 80 -height 25 -wrap none
The GRIDPLUS text widget, which by default is editable, has a right-click pop-up Cut/Copy/Paste/Find menu.
gridplus grid .statusbar -relief groove { {"^File: " .file} {} } gridplus widget .statusbar -relief groove -stretch 0 { {"^File: " .file |>| "^Status: " .status} }
An Embedded Grid is created with two columns. The colums are separated by a vertical bar ("|>|") which is attached to the right hand column. The first column has a text label "File". The caret character prefix causes the label to be displayed in bold text. To the right of the label is a another label called ".file" - the value of this label (.statusbar,file) can be set using the GRIDPLUS gpset command. The second column also has bold label text "Status:" and another label called ".status" - the value of this label (.statusbar,status) can be set using the GRIDPLUS gpset command.
The "-stretch 0" option specifies that the first column (column "0") in the ".statusbar" grid can stretch. As the Embedded Grid is created in the first column, this means that the contents of the Embedded Grid can stretch.
gridplus layout .main -wtitle gpEdit { v .toolbar:w > .text:nsew .statusbar:ew } gpset { .statusbar,file Untitled .statusbar,status New } gridplus pack .main -resize xy -minx 75 -miny 50
The ".statusbar,file" text is set to "Untitled" and ".statusbar,status" set to "New".
The gridplus pack must be used instead of the Tk pack command to pack a resizable window. The "-resize xy" option specifies that the window can be streched in both "x" (horizontal) and "y" (vertical) directions. The "-minx 75" option specifies that the minimum size to which the window can be resized in the "x" direction is to 75% of its initial size. The "-miny 50" option specifies that the minimum size to which the window can be resized in the "y" direction is to 50% of its initial size.
proc new {} { savemodified gpset { .text {} .statusbar,file Untitled .statusbar,status New } }
proc openfile {} { savemodified set filename [tk_getOpenFile -title "gpEdit: Open File"] if {$filename ne ""} { set file [open $filename r] gpset .text [read $file] close $file gpset .statusbar,file $filename gpset .statusbar,status Opened } }
proc save {} { global {} if {$(.statusbar,file) != "Untitled"} { set file [open $(.statusbar,file) w] puts $file $(.text) close $file } else { saveas } gpset .statusbar,status Saved }
If the data hasn't been been read from a file the statusbar filename will be "Untitled", in this case the "saveas" procedure will be called.
The statusbar status is set to "Saved".
proc saveas {} { global {} set filename [tk_getSaveFile -title "gpEdit: Save File"] if {$filename ne ""} { set file [open $filename w] puts $file $(.text) close $file gpset .statusbar,file $filename gpset .statusbar,status Saved } }
proc savemodified {} { global {} if {$(.statusbar,status) eq "Modified"} { set action [tk_messageBox -message "Save the changes to [file tail $(.statusbar,file)]?" -icon warning -type yesnocancel -title gpEdit] switch -- $action { yes {save} cancel {return -level 2} } } }
proc find {} { global {} gpfind .text $(.find,string) }
The GRIDPLUS gpfind command is used to find the next occurance of ".find,string" in ".text".
proc selectall {} { .text.text tag add sel 1.0 end }
proc about {} { tk_messageBox -icon info -title "gpEdit: About" -message "gpEdit - Adrian Davis 2014" -type ok }
proc modified {} { global {} gpset .statusbar,status Modified }
proc quit {} { savemodified exit }
gpoptions iconFile Icons
main