home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Languages / Mops 2.7 / Mops source / Module source / windowmod.txt < prev    next >
Encoding:
Text File  |  1995-12-05  |  10.9 KB  |  429 lines  |  [TEXT/MSET]

  1. \ Window class.
  2.  
  3. \  May 91 mrh    Added NonScrollWind.
  4. \    Default grow and drag limits set at grow and drag time.
  5. \    Also fixed a number of long-standing bugs in draw:, enable:, disable:
  6. \    etc.  New: deactivates current window.  Added PenIntoWind:.
  7.  
  8. \    Nov95 JRF    Option to not outline unused scroll bars
  9.  
  10.  
  11. \        ===================================
  12.  
  13. \ WINDOW is the basic window class, with no controls.
  14. \  For windows with controls, use Window+.
  15.  
  16. \        ===================================
  17.  
  18. :class    WINDOW  super{ grafPort }
  19. record
  20. {    $ 20    bytes    wind1            \ unmapped
  21.             handle    CTLLIST            \ 1st ctl
  22.     $ 0C    bytes    wind2            \ unmapped
  23.  
  24.             rect    CONTRECT        \ true content
  25.             rect    GROWRECT        \ grow size rectangle
  26.             rect    DRAGRECT        \ drag limits rect
  27.  
  28.             bool    GROWFLG            \ true if growable
  29.             bool    DRAGFLG            \ true if draggable
  30.             bool    ALIVE            \ true if space exists
  31.             bool    SCROLLFLG        \ true if scrollable
  32.             bool    COLOR?            \ true if this is a color window
  33.  
  34.             x-addr    IDLE            \ idle handler
  35.             x-addr    DEACT            \ deactivate event handler
  36.  
  37.             x-addr    CONTENT            \ content handler
  38.             x-addr    DRAW            \ draw handler
  39.             x-addr    ENACT            \ activate event handler
  40.             x-addr    CLOSE            \ close handler
  41.  
  42.             int        RESID            \ resource id
  43.             
  44.             bool    ClipGrowLeft    \ Nov95 JRF Option to not outline unused HScroll
  45.             bool    ClipGrowTop        \ ditto unused VScroll -- DrawGrowIcon normally
  46. }
  47. private
  48.  
  49. :m SETLIMITS:    \ Sets GrowRect and DragRect to reasonable default values
  50.                 \ according to the current screen size at the time the grow
  51.                 \ or drag is done.  Programs such as SteppingOut can change
  52.                 \ the screen size while a window is open!
  53.  
  54.     screenbits  put: dragRect
  55.     40 40 getBot: dragRect  put: growRect
  56.     4 4 inset: dragRect  ;m
  57.  
  58. :m ?SETFPRECT:    \ Sets fPrect if scrollFlg is true.  fPrect is needed by
  59.                 \ the nucleus for scrolling fWind, before proper window
  60.                 \ handling is loaded.  But it can be used for scrolling
  61.                 \ text in any other window as well, if scrolling is enabled
  62.                 \ for that window.
  63.  
  64.     get: scrollFlg IF  get: contRect  put: fPrect  THEN  ;m
  65.  
  66. :m ?DISABLE_ACTW:    \ Deactivates the currently active window before a New:
  67.                     \ or GetNew: call, if there is a currently active Mops 
  68.                     \ window.
  69.     actW  0EXIT
  70.     disable: [ actW ]  0 -> actW  ;m
  71.  
  72. :m InitNewWindow:
  73.     setContRect: [self]
  74.     set: self  initfont  true  put: alive
  75.     cls  ;m
  76.  
  77. :m PenIntoWind:    \ Moves the GrafPort pen back into the window area if
  78.                 \ necessary, after the window has been resized.
  79.                 \ Actually at the moment we only worry about the vertical
  80.                 \ direction.
  81.     @xy bottom min  gotoxy  ;m
  82.  
  83. public
  84.  
  85. \ Grow icon methods:
  86.  
  87. :m SETCLIPGROWLEFT:    put: clipgrowleft ;m    \ Nov95 JRF
  88. :m SETCLIPGROWTOP:    put: clipgrowtop ;m        \ Nov95 JRF
  89.  
  90. :m DRAWGROW:  { \ l t r b -- }                \ Nov95 JRF rev.
  91.     get: growFlg  0EXIT
  92.     get: clipgrowleft get: clipgrowtop OR
  93.     NIF    noClip
  94.         @xy   ^base  call DrawGrowIcon
  95.         gotoxy
  96.         EXIT
  97.     THEN
  98.     getRect: self  -> b -> r -> t -> l
  99.     get: clipgrowleft IF r 15 - ELSE 0 THEN
  100.     get: clipgrowtop  IF b 15 - ELSE 0 THEN
  101.     r b put: tempRect clip: tempRect
  102.     @xy     ^base  call DrawGrowIcon
  103.     gotoxy  noClip  ;m
  104.  
  105.  
  106. :m ERASEGROW:  { \ l t r b -- }
  107.     get: growFlg  0EXIT
  108.     noClip
  109.     getRect: self  -> b -> r -> t -> l
  110.     r 13 -  b 13 -  r  b  put: tempRect
  111.     clear: tempRect  ;m
  112.  
  113.  
  114.  
  115. :m SETCONTRECT:    \ Sets ContRect to the viewing area.  Must be public since 
  116.                 \ we late-bind to it, and it gets called from ObjInit anyway.
  117.  
  118.     get: portRect  get: growFlg
  119.     IF  swap 15 -  swap  15 -  THEN   put: contRect
  120.     ?setfPrect: self  ;m
  121.  
  122. :m CLOSE:
  123.     get: alive  0EXIT
  124.     ^base  call CloseWindow
  125.     ^base actW = IF  0 -> actW  THEN    \ If this was the active window, it
  126.                                         \  isn't any more
  127.     clear: alive   exec: close  ;m
  128.  
  129. :m RELEASE:    close: [self]  ;m    \ Standard destructor - same as close.
  130.  
  131. :m SET:        \ Makes this wind the current GrafPort.  It used
  132.             \ to call setContRect: but there's really no need.
  133.     set: super
  134.     ?setfPrect: self  ;m
  135.  
  136. :m UPDATE:    \ Generates an update event for the window with its
  137.             \  entire port rectangle as the update region.
  138.     pushPort  set: self
  139.     getRect: self  put: tempRect  update: tempRect
  140.     popPort  ;m
  141.  
  142.  
  143. :m NEW: { bndsRect tAddr tLen procID vis goAway \ s255 -- }
  144.  
  145.   \ Defines a new window on the heap with the specified features.
  146.   \ Not resource based.
  147.  
  148.     get: alive  ?EXIT                \ Out if already alive
  149.     bndsRect ->: contRect            \ save rect locally
  150.     ?disable_actW: self
  151.     tAddr tLen  str255  -> s255
  152.     ^base  addr: contRect  s255
  153.     vis 1 and
  154.     procID
  155.     inFront  goAway 1 and
  156.     0                                \ default is initially in front
  157.     get: color?
  158.     IF  NewCWindow  ELSE  NewWindow  THEN  drop
  159.     initNewWindow: self  ;m
  160.  
  161.  
  162. :m GETNEW:        \ ( resid -- )   Resource based new window.
  163.  
  164.     get: alive  IF  drop  EXIT  THEN    \ Out if already alive
  165.     ?disable_actW: self
  166.     dup  put: resid  ^base  inFront
  167.     get: color?
  168.     IF    GetNewCWindow  ELSE  GetNewWindow  THEN  drop
  169.     initNewWindow: self  ;m
  170.  
  171.  
  172. :m GETVSRECT:    \ ( l t r b -- l' t' r' b' )
  173.                 \ Returns the default vert. scroll bar rect.
  174.     get: portRect  >vrect  ;m
  175.  
  176. :m GETHSRECT:    \ ( l t r b -- l' t' r' b' )
  177.                 \ Returns the default horiz. scroll bar rect.
  178.     get: portRect  >hrect  ;m
  179.  
  180.  
  181. (*    The DRAW: method is called, late-bound, whenever a window is updated.
  182.     The implementation must begin with a BeginUpdate call and end with an
  183.     EndUpdate call.  We use the CallFirst/CallLast mechanism to ensure this,
  184.     and also to draw the grow icon if this is a growable window.  This means
  185.     that any redefinition of DRAW: in a subclass should not call DRAW: super,
  186.     since this would lead to BeginUpdate and EndUpdate being called more than
  187.     once.  So we define another method (DRAW): to do the actual work for DRAW:,
  188.     and subclasses which need their own versions of DRAW: may call (DRAW):
  189.     freely.
  190. *)
  191.  
  192. private
  193.  
  194. :m (DRAW):        \ Does the main work for DRAW:.
  195.     savePort  @xy  set: self        \ Save port and pen posn, reset to this 
  196.                                     \  window
  197.     exec: draw                        \ Call user draw routine
  198.     restport gotoxy  ;m                \ Restore pen posn, restore original port
  199.  
  200.  
  201. :m SETUP_DRAW:
  202.     get: fPrect                        \ Save fPrect as it might get changed
  203.     ^base  call BeginUpdate  ;m
  204.  
  205. :m WINDUP_DRAW:
  206.     drawGrow: self
  207.     ^base  call EndUpdate
  208.     put: fPrect  ;m                    \ Restore fPrect
  209.  
  210.  
  211. callFirst    setup_draw:
  212. callLast    windup_draw:
  213.  
  214. public
  215.  
  216. :m DRAW:    (draw): self  ;m
  217.  
  218.  
  219. :m SELECT:        \ Makes this the front window.
  220.     ^base  call SelectWindow
  221.     ?setfPrect: self  ;m
  222.  
  223.  
  224. (*    The idle: method is called for the frontmost window, whenever a null
  225.     event occurs.  NULL-EVT is the normal word which sends idle:.  In
  226.     subclasses we redefine this method to do things like calling TEidle,
  227.     which have to be done periodically.  The Idle handler is also called,
  228.     which allows a window-specific action to be taken.  In the class Window
  229.     itself, this is all we do.
  230. *)
  231.  
  232. :m IDLE:        exec: idle  ;m
  233.  
  234. :m SETIDLE:        put: idle  ;m
  235.  
  236.  
  237. :m ENABLE:        \ Handles an activate event.
  238.     set: self
  239.     drawGrow: self
  240.     exec: enact  ;m
  241.  
  242. :m DISABLE:        \ Handles a deactivate event.
  243.     eraseGrow: self
  244.     exec: deact  ;m
  245.  
  246.  
  247. :m ACTIONS:        \ ( close enact draw cont 4 -- )
  248.                 \ Sets up window event handler words.  We require
  249.                 \ an xt count as this is normal for actions: methods.
  250.     4 ?#xts
  251.     put: content  put: draw  put: enact  put: close  ;m
  252.  
  253.  
  254. :m SETACT:    \ ( enact deact -- )  Sets just the activate/deactivate
  255.             \ event handlers
  256.     put: deact  put: enact  ;m
  257.  
  258.  
  259. :m SETDRAW:        \ ( xt -- )  Sets the draw handler
  260.     put: draw  ;m
  261.  
  262.  
  263. :m SETCOLOR:    \ ( b -- )  Sets the color? flag.
  264.     put: color?  ;m
  265.  
  266.  
  267. :m ACTIVE:    \ ( -- b )  Is this window active ?
  268.     0  call FrontWindow  ^base  =  ;m
  269.  
  270.  
  271. :m ALIVE:    \ ( -- b )  Is this window alive?
  272.     get: alive  ;m
  273.  
  274.  
  275. :m DRAG:    \ Handles a drag region click
  276.     setLimits: self                    \ Omit in subclasses which need
  277.                                     \  custom drag limits
  278.     get: dragFlg  0exit
  279.     ^base  whrFEv  addr: dragRect
  280.     call DragWindow  ;m
  281.  
  282. private
  283.  
  284. \ Some housekeeping routines for Size: and Zoom:
  285.  
  286. :m ClrOldBars:
  287.     getVSrect: self 16 +  put: tempRect
  288.     clear: tempRect  update: tempRect    \ Including the grow box
  289.     getHSrect: self  put: tempRect
  290.     clear: tempRect  update: temprect  ;m
  291.  
  292. :m FixNewBars:
  293.     ClrOldBars: self                    \ Yes, the code's the same so far!!
  294.     addr: portRect  call ClipRect
  295.     setContRect: [self]
  296.     penIntoWind: self  ;m
  297.  
  298. public
  299.  
  300. :m SIZE:    \ ( w h -- )  Resizes window and accumulates update regions.
  301.     pack  ^base  swap  true makeint
  302.     ClrOldBars: self
  303.     call SizeWindow
  304.     FixNewBars: self  ;m
  305.  
  306. :m SETSIZE:    size: self  ;m    \ For naming consistency with Rects and 
  307.                             \  Views.
  308.  
  309.  
  310. :m MOVE:    \ ( x y -- )  Moves the window.
  311.     pack  ^base  swap  w 0
  312.     call MoveWindow  ;m
  313.  
  314.  
  315. :m CENTER:  { \ sw sh pw ph -- }
  316.         \ Centers the window on the screen.
  317.         \ Yeah, I know, here in Oz we spell this "centre", but we Ozzies
  318.         \ are more flexible than the Yanks, so we'll magnanimously do it
  319.         \ their way, not ours.
  320.         
  321.     screenbits  -> sh  -> sw  2drop
  322.     size: portRect  -> ph  -> pw
  323.     sw pw - 2/  sh ph - 2/  move: self  ;m
  324.  
  325.  
  326. :m ZOOM:  { part -- }
  327.     word0  ^base  whrFEv
  328.     part makeint  call TrackBox  i->l
  329.     IF    getRect: self  put: tempRect  tempRect  call EraseRect
  330.         ^base  part makeint  word0  call ZoomWindow
  331.         FixNewBars: self
  332.     THEN  ;m
  333.  
  334.  
  335. :m GROW:        \ Handles a mouse-down in the grow box.
  336.     get: growFlg
  337.     IF    setLimits: self                    \ Omit in subclasses which need
  338.                                         \  custom grow limits
  339.         0 ^base  whrFEv  addr: growrect
  340.         call GrowWindow  ?dup
  341.         IF    unpack  size: self  ( draw: self )
  342.             penIntoWind: self
  343.         THEN
  344.     ELSE
  345.         ^base  call SelectWindow
  346.     THEN
  347.     update: self  ;m
  348.  
  349.  
  350. :m CONTENT:        \ Handles a content click.
  351.     active: self
  352.     IF        exec: content
  353.     ELSE    select: self
  354.     THEN  ;m
  355.  
  356.  
  357. :m TITLE:    \ ( addr len -- )  Sets the title of the window.
  358.     str255  ^base  swap  call SetWTitle  ;m
  359.  
  360. :m NAME:  ( addr len -- )    title: self  ;m        \ An alias for TITLE:.
  361.  
  362.  
  363. :m GETNAME:    \ ( -- addr len )  Returns name of window.
  364.     ^base  buf255  call GetWTitle
  365.     buf255 count  ;m
  366.  
  367.  
  368. :m MAXX:    \ ( -- x )  Returns the x coordinate value corresponding to
  369.             \  the window being moved to the right of the screen.
  370.     screenbits drop nip nip
  371.     size: portRect  drop  -  ;m
  372.  
  373.  
  374. :m MAXY:    \ ( -- y )
  375.     screenbits nip nip nip
  376.     size: portRect  nip  -  ;m
  377.  
  378. \            =================
  379.  
  380. :m KEY:        \ ( c -- )  May be used in subclasses to do something with
  381.             \  typed keys.  Here, we just drop it.
  382.     drop  ;m
  383.  
  384.  
  385. :m SHOW:    ^base  call ShowWindow  ;m
  386.  
  387. :m HIDE:    ^base  call HideWindow  ;m
  388.  
  389.  
  390. :m SETGROW:    \ ( l t r b  T  |  F -- )  Sets grow limits, if boolean is true.
  391.  
  392.     \ Note: in class Window itself, we IGNORE these grow limits and
  393.     \  use a default value based on the size of the screen at the time
  394.     \  the grow is actually done.
  395.  
  396.     dup  put: growFlg
  397.     if  put: growrect  then  ;m
  398.  
  399. :m SETDRAG:    \ ( l t r b  T  |  F -- )  Sets drag limits.
  400.  
  401.     \ Note: in class Window itself, we IGNORE these drag limits and
  402.     \  use a default value based on the size of the screen at the time
  403.     \  the drag is actually done.
  404.  
  405.     dup  put: dragFlg
  406.     if  put: dragRect  then  ;m
  407.  
  408. :m SETSCROLL:    \ ( b -- )
  409.     put: scrollFlg  ;m
  410.  
  411.  
  412. :m CLASSINIT:
  413.     xts{ null null null null }  actions: self
  414.     ['] null  dup  put: idle  put: deact
  415.     true  put: scrollFlg  true  put: dragFlg  ;m
  416.  
  417.  
  418. :m MARKALIVE:    \ A special method really intended just to allow us to
  419.                 \ mark fWind alive on startup.
  420.     true  put: alive   ;m
  421.  
  422.  
  423. :m TEST:        \ Fires up a test window.
  424.     100 100 300 200 put: tempRect
  425.     screenbits true setGrow: self
  426.     tempRect  " Test"  docWind  true true  new: self  ;m
  427.  
  428. ;class
  429.