diff -r ffa851df0825 -r 2fb8b9db1c86 symbian-qemu-0.9.1-12/python-2.6.1/Mac/Demo/textedit.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/symbian-qemu-0.9.1-12/python-2.6.1/Mac/Demo/textedit.html Fri Jul 31 15:01:17 2009 +0100 @@ -0,0 +1,150 @@ +Using FrameWork and TextEdit + +

Using FrameWork and TextEdit

+
+ +In this document we use the FrameWork and TextEdit +modules to create a simple text editor. The functionality +of the editor is very basic: you can open multiple files, type text and use +cut/copy/paste. The main intention is to explain the use of FrameWork, really.

+ +

FrameWork

+ +The FrameWork module provides you with a skeleton application. It declares a +number of classes suitable for subclassing in your application, thereby +releaving you of the burden of doing all event handling, etc. yourself. For a +real understanding you will have to browse the source. Here is a short overview +of the classes and what functionality they provide. + +
+
Application +
+This is the toplevel class you will override. It maintains the menu bar and contains +the main event handling code. Normal use is to override the __init__ routine +to do your own initializations and override makeusermenus to create your menus +(your menu callback routines may be here too, but this is by no means necessary). +The event handling code can be overridden at various levels, from very low-level (the +dispatch method) to intermedeate level (do_keyDown, for instance) +to high-level (do_key). The application class knows about the Window +objects you create, and will forward events to the appropriate window (So, normally you +would have a do_key method in your window object, not your application object). + +
MenuBar, Menu and MenuItem +
+These classes (and a few friends like SubMenu) handle your menus. You would not +normally override them but use them as-is. The idiom for creating menus is a bit strange, +see the test code at the bottom of FrameWork for sample use. The apple menu is handled for you +by MenuBar and Application. + +
Window +
+The basic window. Again, a class that you normally subclass in your application, possibly +multiple times if you have different types of windows. The init call instantiates the data +structure but actually opening the window is delayed until you call open. Your +open method should call do_postopen to let the base class handle linking in to +the application object. Similarly with close and do_postclose. The +rest of the code is mainly event-oriented: you override do_postresize, +do_contentclick, do_update, do_activate +and do_key to "do your thing". When these methods are called the relevant environment +has been setup (like BeginDrawing has been called for updates, etc). + +
windowbounds +
+Not a class but a function: you pass it a width and height and it will return you a rectangle +you can use to create your window. It will take care of staggering windows and it will try +to fit the window on the screen (but the resulting rect will always have the size you +specify). + +
ControlsWindow +
+A subclass of Window which automatically handles drawing and clicking for controls. You override +the same methods as for Window (if you need to: control-related things are done automatically) and +do_controlhit. + +
ScrolledWindow +
+A subclass of ControlsWindow, a window with optional scrollbars. If you override do_activate +or do_postresize you must call the ScrolledWindow methods at the end of your override. +You call scrollbars to enable/disable scrollbars and updatescrollbars to +update them. You provide getscrollbarvalues to return the current x/y values (a helper +method scalebarvalues is available) and scrollbarcallback to update your +display after the user has used the scrollbars. + +
DialogWindow +
+A modeless dialog window initialized from a DLOG resource. See the +second Interslip example for its useage. +
+ +

A sample text editor

+ +Let us have a look at ped.py (in the Demo:textedit folder), the Pathetic +EDitor. It has multiple windows, cut/copy/paste and keyboard input, but that is about all. It looks +as if you can resize the window but it does not work. Still, it serves as an example. + +Ped creates two classes, TEWindow and Ped. Let us start with the latter one, +which is a subclass of FrameWork.Application and our main application. The init function +has little to do aside from the standard init: it remembers a window sequence number (for untitled windows), +and sets things up for menu disable to work. Remember, the makeusermenus is called +automatically.

+ +Makeusermenus creates the File and Edit menus. It also initializes +a couple of lists that are used later to correctly enable and disable menu items (and complete menus) depending +on whether a window is open, text is selected, etc. The callback functions for the menu items are +all methods of this class.

+ +Updatemenubar handles greying out (and re-enabling) of menu items depending on whether there +is a current window and its state.

+ +The rest of the methods are all callbacks and simple to understand. They check whether there is an active +window (and complain loudly if there is none: the corresponding menu entry should have been disabled +in that case!) and call the appropriate window method. Only the _open method (the common code +for Open and New) deserves some mention. It instantiates a TEWindow +object and opens it with the title, filename and contents of the file to edit. Note that FrameWork takes +care of remembering the window object. A minor note on opening the file in binary mode: this is because +TextEdit expects MacOS style carriage-return terminated lines, not python/unix/C style newline-terminated +lines.

+ +Oh yes: the quit callback does a little magic too. It closes all windows, and only if this +succeeds it actually quits. This gives the user a chance to cancel the operation if some files are unsaved. +

+ +Lastly, there is the idle method, called by the Application base class when no event +is available. It is forwarded to the active window, so it can blink the text caret.

+ +The TEWindow object handles a single window. Due to this structuring it is absolutely no +problem to have multiple windows open at the same time (although a real application should exercise care when +two windows refer to the same document). TEWindow uses the standard init code inherited from +ScrolledWindow, and sets itself up at the time of the open call. It obtains screen +coordinates, opens the window, creates rectangles for TextEdit to work in (the magical number 15 +here is the size of a normal scroll bar: unfortunately there is no symbolic constant for it), +creates the TextEdit object and initializes it with our data. Finally, the scroll bars are created (the +initial values will be obtained automatically through getscrollbarvalues) and we activate +ourselves (this is unfortunately not done automatically by the MacOS event handling code).

+ +Do_idle simply calls the TextEdit routine that blinks the cursor. Getscrollbarvalues +returns the current X and Y scrollbar values, scaled to 0..32767. For X we return None, +which means "no scrollbar, please", for Y we use the scaler provided by ScrolledWindow.

+ +Scrollbar_callback is called when the user uses the scrollbar. It is passed a string 'x' +or 'y', one of 'set', '-', '--', '+', '++' and (for set) an absolute +value. Note that the sign of the value passed to TEPinScroll is counter-intuitive.

+ +do_activate (de)activates the scrollbars and calls the relevant TextEdit routine. Moreover, it +tells the application object if we are now the active window, and updates the menubar. The next few methods +are update and menu callbacks, and pretty straightforward. Note that do_close can +return without closing the window (if the document is changed and the users cancels out of the operation). +Also note the "magic" in menu_save_as +that set the correct window title.

+ +Things get moderately interesting again at the cut/copy/paste handling, since the TextEdit scrap is +separate from the desktop scrap. For that reason there are various calls to routines that move the scrap +back and forth. Have_selection is called by the menubar update code to determine whether cut and +copy should be enabled.

+ +Understanding the main program is left as an exercise to the reader.

+ +


+That's all for this example, you could now continue with the next example, where we use WASTE, a more-or-less +TextEdit compatible library with more functionality, to rebuild our editor. Or you can +return to the table of contents to pick another topic.