From 0fe5765c452f370886cd5f9103565ae92eaf82ce Mon Sep 17 00:00:00 2001 From: Quinn Dunki Date: Sat, 24 Jan 2015 17:17:38 -0800 Subject: [PATCH] Support for removing views - Added WGDeleteView and &KILL - Added WGEraseView and &WIPE - Fixed focus iteration code to handle unallocated views in the middle of the list --- Documentation.md | 54 +++++++++++++++++++++++-- ReadMe.md | 1 + WeeGUI_MLI.s | 4 +- applesoft.s | 26 ++++++++++++ views.s | 103 +++++++++++++++++++++++++++++++++++++++-------- weegui.dsk | Bin 143360 -> 143360 bytes weegui.s | 3 ++ 7 files changed, 171 insertions(+), 20 deletions(-) diff --git a/Documentation.md b/Documentation.md index eb07475..75f2e9d 100644 --- a/Documentation.md +++ b/Documentation.md @@ -272,11 +272,23 @@ A View is a rectangle inside which content is displayed. Content exists in a spe Many API calls rely on the concept of a "selected" view. One view at a time can be "selected", and subsequent view-related operations will apply to that view. There is no visual effect to "selecting" a view. It's simply a way to tell WeeGUI which view you are currently interested in. -**IMPORTANT:** The visual border around a view (a one-character-thick outline) is drawn *outside* the bounds of the view. This means *you need to allow room around your views*. Don't attempt to place a view in columns 0 or 79, or in rows 0 or 23. *In order to maximize rendering speed, WeeGUI takes only minimal precautions to prevent rendering outside the visible screen area.*
- + +View Styles +----------- + +Views in WeeGUI can be drawn with two different types of frame: Plain and Fancy. Examples of each are shown below. + + +**IMPORTANT:** The visual border around a view (a one-character-thick outline) is drawn *outside* the bounds of the view. This means *you need to allow room around your views*. Don't attempt to place a view in columns 0 or 79, or in rows 0 or 23. *In order to maximize rendering speed, WeeGUI takes only minimal precautions to prevent rendering outside the visible screen area.* Rendering outside the screen area will almost certainly cause crashes and other Very Bad Thingsā„¢ on your Apple II. + +Because view frames are rendered with Mousetext characters, views have limits on how close they can be placed together, and overlapping views may not always look perfect. WeeGUI views are drawn with a modern display-list rendering strategy, which means it combines information about all views to make the result look as good as possible within the constraints of the Apple II character set. For example, you *can* have Plain views that are separated by only one row, because there is a "double-horizontal-line" character in Mousetext that WeeGUI can use to render horizontal borders close together. However, no such character exists for verticals, thus adjacent views must be separated by at least two columns. You'll need to experiment a bit to get a sense of what will render well and what won't. + +
+ + Cursors ------- @@ -314,7 +326,7 @@ These routines are used for creating, modifying, and working with views. ####WGCreateView -Creates a new WeeGUI view. Up to 16 are allowed in one program. If a view is created with the same ID as a previous view, the previous view is destroyed. Views are not shown when created. Call *WGPaintView* to display it. +Creates a new WeeGUI view. Up to 16 are allowed in one program. If a view is created with the same ID as a previous view, the previous view is destroyed and replaced with the new one. Views are not shown when created. Call *WGPaintView* to display it. @@ -399,6 +411,18 @@ Configuration block consists of eight bytes:
+####WGDeleteView +Deletes the selected view. The view is erased from the screen, and the ID is now available for use by a new view. + + + +
AssemblyApplesoft
+X:		WGDeleteView
+
+&KILL
+
+ + ####WGSelectView Selects a view. Subsequent view-related operations will apply to this view. Does not affect visual appearance of view. @@ -522,6 +546,30 @@ X: WGViewPaintAll +####WGEraseViewContents +Erases the content area of the selected view. The frame is not touched. + + + +
AssemblyApplesoft
+X:		WGEraseViewContents
+
+&ERASE
+
+ + +####WGEraseView +Erases the content area and frame of the selected view. + + + +
AssemblyApplesoft
+X:		WGEraseView
+
+&WIPE
+
+ + ####WGViewSetTitle Changes the title of the selected view. Titles are only visible in the "fancy" style of view border. In Applesoft, the view is automatically redrawn to reflect the change. In assembly, you must call WGPaintView manually to see the change. diff --git a/ReadMe.md b/ReadMe.md index 838390a..136b2c9 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -3,6 +3,7 @@ Known issues ------------ - Hitting Reset during a WeeGUI application will leave your Apple II in an unsafe state +- Calling WGEraseView on a view that shares border rendering with other views will require manually redrawing those views. To Do: diff --git a/WeeGUI_MLI.s b/WeeGUI_MLI.s index 5e30a1c..7d15a6e 100644 --- a/WeeGUI_MLI.s +++ b/WeeGUI_MLI.s @@ -63,5 +63,7 @@ WGScrollY = 58 WGScrollYBy = 60 WGEnableMouse = 62 WGDisableMouse = 64 -WGExit = 66 +WGDeleteView = 66 +WGEraseView = 68 +WGExit = 70 diff --git a/applesoft.s b/applesoft.s index 7936750..d2cdb9f 100644 --- a/applesoft.s +++ b/applesoft.s @@ -901,6 +901,26 @@ WGAmpersand_GETstore: rts +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; WGAmpersand_KILL +; Deletes the selected view +; &KILL +WGAmpersand_KILL: + jsr WGDeleteView + jsr WGBottomCursor + rts + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; WGAmpersand_WIPE +; Erases all of the selected view +; &WIPE +WGAmpersand_WIPE: + jsr WGEraseView + jsr WGBottomCursor + rts + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGAmpersand_EXIT ; Shuts down WeeGUI @@ -1088,6 +1108,12 @@ WGAmpersandCommandTable: .byte TOKEN_GET,0,0,0,0,0 .addr WGAmpersand_GET +.byte "KILL",0,0 +.addr WGAmpersand_KILL + +.byte "WIPE",0,0 +.addr WGAmpersand_WIPE + .byte "EXIT",0,0 .addr WGAmpersand_EXIT diff --git a/views.s b/views.s index 92b9ad2..7ea425c 100644 --- a/views.s +++ b/views.s @@ -232,6 +232,26 @@ WGCreateButton_done: +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; WGDeleteView +; Deletes the current view and removes it from the screen +; +WGDeleteView: + SAVE_AY + + jsr WGEraseView + + LDY_ACTIVEVIEW + + lda #0 + sta WG_VIEWRECORDS+2,y ; 0 width indicates unused view + jsr WGViewPaintAll + + RESTORE_AY + rts + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGPaintView ; Paints the current view @@ -464,6 +484,43 @@ paintWindowTitle_done: rts +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; WGEraseView +; Erases the current view (including decoration) +; +WGEraseView: + SAVE_AXY + SAVE_ZPP + + LDY_ACTIVEVIEW + + lda WG_VIEWRECORDS+0,y + dec + sta PARAM0 + + lda WG_VIEWRECORDS+1,y + dec + sta PARAM1 + + lda WG_VIEWRECORDS+2,y + inc + inc + sta PARAM2 + + lda WG_VIEWRECORDS+3,y + inc + inc + sta PARAM3 + + ldy #' '+$80 + jsr WGFillRect + +WGEraseView_done: + RESTORE_ZPP + RESTORE_AXY + rts + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGEraseViewContents ; Erases the contents of the current view (interior contents only) @@ -564,12 +621,15 @@ WGViewFocusNext: jsr unfocusCurrent WGViewFocusNext_loop: - inc WG_FOCUSVIEW ; Increment and wrap + lda WG_FOCUSVIEW ; Increment and wrap + inc + cmp #16 + beq WGViewFocusNext_wrap + sta WG_FOCUSVIEW + LDY_FOCUSVIEW lda WG_VIEWRECORDS+2,y - bne WGViewFocusNext_wantFocus - lda #0 - sta WG_FOCUSVIEW + beq WGViewFocusNext_loop WGViewFocusNext_wantFocus: ; Does this view accept focus? LDY_FOCUSVIEW @@ -584,6 +644,10 @@ WGViewFocusNext_focus: RESTORE_AY rts +WGViewFocusNext_wrap: + stz WG_FOCUSVIEW + bra WGViewFocusNext_loop + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGViewFocusPrev @@ -596,18 +660,15 @@ WGViewFocusPrev: jsr unfocusCurrent WGViewFocusPrev_loop: - dec WG_FOCUSVIEW ; Decrement and wrap - bpl WGViewFocusPrev_wantFocus + ldx WG_FOCUSVIEW ; Decrement and wrap + dex + bmi WGViewFocusPrev_wrap -WGViewFocusPrev_hadNone: - ldx #$f -WGViewFocusPrev_findEndLoop: +WGViewFocusPrev_findLoop: stx WG_FOCUSVIEW LDY_FOCUSVIEW lda WG_VIEWRECORDS+2,y - bne WGViewFocusPrev_wantFocus - dex - bra WGViewFocusPrev_findEndLoop + beq WGViewFocusPrev_loop WGViewFocusPrev_wantFocus: ; Does this view accept focus? LDY_FOCUSVIEW @@ -622,6 +683,10 @@ WGViewFocusPrev_focus: RESTORE_AXY rts +WGViewFocusPrev_wrap: + ldx #$f + bra WGViewFocusPrev_findLoop + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; unfocusCurrent @@ -1124,18 +1189,24 @@ WGViewPaintAll: WGViewPaintAll_loop: txa - jsr WGSelectView + sta WG_ACTIVEVIEW LDY_ACTIVEVIEW - lda WG_VIEWRECORDS+2,y ; Last view? - beq WGViewPaintAll_done + lda WG_VIEWRECORDS+2,y ; Valid view? + beq WGViewPaintAll_next jsr WGEraseViewContents jsr WGPaintView + +WGViewPaintAll_next: inx - bra WGViewPaintAll_loop + cpx #16 + bne WGViewPaintAll_loop WGViewPaintAll_done: + lda #-1 + jsr WGSelectView + RESTORE_AXY rts diff --git a/weegui.dsk b/weegui.dsk index 4298bb938eae51b88ed634c589b90abf7c00e131..242ff43dccb645b82a9e75c36694b94e8763fa34 100644 GIT binary patch delta 4741 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 De}f!g delta 4518 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 diff --git a/weegui.s b/weegui.s index 7a03553..52761a9 100644 --- a/weegui.s +++ b/weegui.s @@ -71,8 +71,11 @@ WGEntryPointTable: .addr WGScrollYBy .addr WGEnableMouse .addr WGDisableMouse +.addr WGDeleteView +.addr WGEraseView .addr WGExit + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGInit ; Initialization. Should be called once at app startup