symbian-qemu-0.9.1-12/python-2.6.1/Mac/Demo/textedit.html
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 <HTML><HEAD><TITLE>Using FrameWork and TextEdit</TITLE></HEAD>
       
     2 <BODY>
       
     3 <H1>Using FrameWork and TextEdit</H1>
       
     4 <HR>
       
     5 
       
     6 In this document we use the <CODE>FrameWork</CODE> and <CODE>TextEdit</CODE>
       
     7 modules to create a simple text editor. The functionality
       
     8 of the editor is very basic: you can open multiple files, type text and use
       
     9 cut/copy/paste. The main intention is to explain the use of FrameWork, really. <p>
       
    10 
       
    11 <H2>FrameWork</H2>
       
    12 
       
    13 The FrameWork module provides you with a skeleton application. It declares a
       
    14 number of classes suitable for subclassing in your application, thereby
       
    15 releaving you of the burden of doing all event handling, etc. yourself. For a
       
    16 real understanding you will have to browse the source. Here is a short overview
       
    17 of the classes and what functionality they provide.
       
    18 
       
    19 <dl>
       
    20 <dt> <CODE>Application</CODE>
       
    21 <dd>
       
    22 This is the toplevel class you will override. It maintains the menu bar and contains
       
    23 the main event handling code. Normal use is to override the <code>__init__</code> routine
       
    24 to do your own initializations and override <code>makeusermenus</code> to create your menus
       
    25 (your menu callback routines may be here too, but this is by no means necessary).
       
    26 The event handling code can be overridden at various levels, from very low-level (the
       
    27 <code>dispatch</code> method) to intermedeate level (<code>do_keyDown</code>, for instance)
       
    28 to high-level (<code>do_key</code>). The application class knows about the <code>Window</code>
       
    29 objects you create, and will forward events to the appropriate window (So, normally you
       
    30 would have a <code>do_key</code> method in your window object, not your application object).
       
    31 
       
    32 <dt> <CODE>MenuBar</CODE>, <CODE>Menu</CODE> and <CODE>MenuItem</CODE>
       
    33 <dd>
       
    34 These classes (and a few friends like <CODE>SubMenu</CODE>) handle your menus. You would not
       
    35 normally override them but use them as-is. The idiom for creating menus is a bit strange,
       
    36 see the test code at the bottom of FrameWork for sample use. The apple menu is handled for you
       
    37 by <CODE>MenuBar</CODE> and <CODE>Application</CODE>.
       
    38 
       
    39 <dt> <CODE>Window</CODE>
       
    40 <dd>
       
    41 The basic window. Again, a class that you normally subclass in your application, possibly
       
    42 multiple times if you have different types of windows. The init call instantiates the data
       
    43 structure but actually opening the window is delayed until you call <code>open</code>. Your
       
    44 open method should call <code>do_postopen</code> to let the base class handle linking in to
       
    45 the application object. Similarly with <code>close</code> and <code>do_postclose</code>. The
       
    46 rest of the code is mainly event-oriented: you override <code>do_postresize</code>,
       
    47 <code>do_contentclick</code>, <code>do_update</code>, <code>do_activate</code>
       
    48 and <code>do_key</code> to "do your thing". When these methods are called the relevant environment
       
    49 has been setup (like <code>BeginDrawing</code> has been called for updates, etc).
       
    50 
       
    51 <dt> <CODE>windowbounds</CODE>
       
    52 <dd>
       
    53 Not a class but a function: you pass it a width and height and it will return you a rectangle
       
    54 you can use to create your window. It will take care of staggering windows and it will try
       
    55 to fit the window on the screen (but the resulting rect will <em>always</em> have the size you
       
    56 specify).
       
    57 
       
    58 <dt> <CODE>ControlsWindow</CODE>
       
    59 <dd>
       
    60 A subclass of Window which automatically handles drawing and clicking for controls. You override
       
    61 the same methods as for Window (if you need to: control-related things are done automatically) and
       
    62 <code>do_controlhit</code>.
       
    63 
       
    64 <dt> <CODE>ScrolledWindow</CODE>
       
    65 <dd>
       
    66 A subclass of ControlsWindow, a window with optional scrollbars. If you override <code>do_activate</code>
       
    67 or <code>do_postresize</code> you must call the ScrolledWindow methods at the end of your override.
       
    68 You call <code>scrollbars</code> to enable/disable scrollbars and <code>updatescrollbars</code> to
       
    69 update them. You provide <code>getscrollbarvalues</code> to return the current x/y values (a helper
       
    70 method <code>scalebarvalues</code> is available) and <code>scrollbarcallback</code> to update your
       
    71 display after the user has used the scrollbars.
       
    72 
       
    73 <dt> <CODE>DialogWindow</CODE>
       
    74 <dd>
       
    75 A modeless dialog window initialized from a DLOG resource. See the
       
    76 <A HREF="example2.html">second Interslip example</A> for its useage.
       
    77 </dl>
       
    78 
       
    79 <H2>A sample text editor</H2>
       
    80 
       
    81 Let us have a look at <A HREF="textedit/ped.py">ped.py</A> (in the Demo:textedit folder), the Pathetic
       
    82 EDitor. It has multiple windows, cut/copy/paste and keyboard input, but that is about all. It looks
       
    83 as if you can resize the window but it does not work. Still, it serves as an example. 
       
    84 
       
    85 Ped creates two classes, <code>TEWindow</code> and <code>Ped</code>. Let us start with the latter one,
       
    86 which is a subclass of <code>FrameWork.Application</code> and our main application. The init function
       
    87 has little to do aside from the standard init: it remembers a window sequence number (for untitled windows),
       
    88 and sets things up for menu disable to work. Remember, the <code>makeusermenus</code> is called
       
    89 automatically. <p>
       
    90 
       
    91 <code>Makeusermenus</code> creates the <code>File</code> and <code>Edit</code> menus. It also initializes
       
    92 a couple of lists that are used later to correctly enable and disable menu items (and complete menus) depending
       
    93 on whether a window is open, text is selected, etc. The callback functions for the menu items are
       
    94 all methods of this class. <p>
       
    95 
       
    96 <code>Updatemenubar</code> handles greying out (and re-enabling) of menu items depending on whether there
       
    97 is a current window and its state. <p>
       
    98 
       
    99 The rest of the methods are all callbacks and simple to understand. They check whether there is an active
       
   100 window (and complain loudly if there is none: the corresponding menu entry should have been disabled
       
   101 in that case!) and call the appropriate window method. Only the <code>_open</code> method (the common code
       
   102 for <code>Open</code> and <code>New</code>) deserves some mention. It instantiates a <code>TEWindow</code>
       
   103 object and opens it with the title, filename and contents of the file to edit. Note that FrameWork takes
       
   104 care of remembering the window object. A minor note on opening the file in binary mode: this is because
       
   105 TextEdit expects MacOS style carriage-return terminated lines, not python/unix/C style newline-terminated
       
   106 lines. <p>
       
   107 
       
   108 Oh yes: the <code>quit</code> callback does a little magic too. It closes all windows, and only if this
       
   109 succeeds it actually quits. This gives the user a chance to cancel the operation if some files are unsaved.
       
   110 <p>
       
   111 
       
   112 Lastly, there is the <code>idle</code> method, called by the Application base class when no event
       
   113 is available. It is forwarded to the active window, so it can blink the text caret. <p>
       
   114 
       
   115 The <code>TEWindow</code> object handles a single window. Due to this structuring it is absolutely no
       
   116 problem to have multiple windows open at the same time (although a real application should exercise care when
       
   117 two windows refer to the same document). TEWindow uses the standard init code inherited from
       
   118 <code>ScrolledWindow</code>, and sets itself up at the time of the <code>open</code> call. It obtains screen
       
   119 coordinates, opens the window, creates rectangles for TextEdit to work in (the magical number <code>15</code>
       
   120 here is the size of a normal scroll bar: unfortunately there is no symbolic constant for it),
       
   121 creates the TextEdit object and initializes it with our data. Finally, the scroll bars are created (the
       
   122 initial values will be obtained automatically through <code>getscrollbarvalues</code>) and we activate
       
   123 ourselves (this is unfortunately not done automatically by the MacOS event handling code). <p>
       
   124 
       
   125 <code>Do_idle</code> simply calls the TextEdit routine that blinks the cursor. <code>Getscrollbarvalues</code>
       
   126 returns the current X and Y scrollbar values, scaled to <code>0..32767</code>. For X we return <code>None</code>,
       
   127 which means "no scrollbar, please", for Y we use the scaler provided by <code>ScrolledWindow</code>. <p>
       
   128 
       
   129 <code>Scrollbar_callback</code> is called when the user uses the scrollbar. It is passed a string <code>'x'</code>
       
   130 or <code>'y'</code>, one of <code>'set', '-', '--', '+', '++'</code> and (for <code>set</code>) an absolute
       
   131 value. Note that the sign of the value passed to <code>TEPinScroll</code> is counter-intuitive. <p>
       
   132 
       
   133 <code>do_activate</code> (de)activates the scrollbars and calls the relevant TextEdit routine. Moreover, it
       
   134 tells the application object if we are now the active window, and updates the menubar. The next few methods
       
   135 are update and menu callbacks, and pretty straightforward. Note that <code>do_close</code> can
       
   136 return without closing the window (if the document is changed and the users cancels out of the operation).
       
   137 Also note the "magic" in <code>menu_save_as</code>
       
   138 that set the correct window title. <p>
       
   139 
       
   140 Things get moderately interesting again at the cut/copy/paste handling, since the TextEdit scrap is
       
   141 separate from the desktop scrap. For that reason there are various calls to routines that move the scrap
       
   142 back and forth. <code>Have_selection</code> is called by the menubar update code to determine whether cut and
       
   143 copy should be enabled. <p>
       
   144 
       
   145 Understanding the main program is left as an exercise to the reader. <p>
       
   146 
       
   147 <hr>
       
   148 That's all for this example, you could now continue with the <A HREF="waste.html">next example</A>, where we use WASTE, a more-or-less
       
   149 TextEdit compatible library with more functionality, to rebuild our editor. Or you can
       
   150 return to the <A HREF="index.html">table of contents</A> to pick another topic. <p>