diff --git a/Documentation.md b/Documentation.md index 496b46c..99d6af5 100644 --- a/Documentation.md +++ b/Documentation.md @@ -97,9 +97,9 @@ Calling WeeGUI ###Applesoft -WeeGUI is accessed from Applesoft through ampersand extensions. For example, the DESK command clears the screen and draws a desktop background: +WeeGUI is accessed from Applesoft through ampersand extensions. For example, the HOME command clears the screen and can optionally draw a desktop background: - 10 &DESK + 10 &HOME(1) If the call requires parameters, you can make a C-style function call. For example, to select view #6, you would call: @@ -425,6 +425,32 @@ Configuration block consists of five bytes: +####WGCreateRadio +Creates a new WeeGUI radio button view. This is a specialized version of WGCreateView, and its parameters are similar. + +Radio buttons act as a group; selecting one radio button deselects all other radio buttons. In WeeGUI, all radio buttons function as a single group. If you need multiple radio groups, rethink your design until you realize you don't need that. + + + +
AssemblyApplesoft
+X:        WGCreateRadio
+PARAM0: Pointer to configuration block (LSB)
+PARAM1:    Pointer to configuration block (MSB)
+
+Configuration block consists of five bytes:
+0:    View ID (0-15)
+1:    X position of checkbox
+2:    Y position of checkbox
+3:     Pointer to null-terminated string label (LSB)
+4:    Pointer to null-terminated string label (MSB)
+
+&RADIO(    View ID,
+        X position,
+        Y position,
+"Label")
+
+ + ####WGCreateProgress Creates a new WeeGUI progress bar view. This is a specialized version of WGCreateView, and its parameters are similar. @@ -899,7 +925,7 @@ Clears the screen to black. Unlike Applesoft HOME, this version always clears to AssemblyApplesoft
 X:		WGClearScreen
 
-&HOME
+&HOME(0)
 
@@ -911,7 +937,7 @@ Paints a desktop background on the screen. AssemblyApplesoft
 X:		WGDesktop
 
-&DESK
+&HOME(1)
 
@@ -972,6 +998,22 @@ PARAM3: Height +####WGStrokeRoundRect +Draws the outline of a "round" rectangle, with left and right edges curved instead of straight. The rectangle is drawn one pixel outside the region you specify. So, *do not* attempt to stroke a rectangle in row 0, row 23, column 0, or column 79. You may overwrite screen holes and cause system malfunctions. + + + +
AssemblyApplesoft
+X:		WGStrokeRoundRect
+PARAM0: Left edge
+PARAM1:	Top edge
+PARAM2: Width
+PARAM3: Height
+
+&DRAW(left,top,width,height)
+
+ + ####WGFillRect Fills a rectangle with a given character diff --git a/WeeGUI_MLI.s b/WeeGUI_MLI.s index e9ece09..1d3bac3 100644 --- a/WeeGUI_MLI.s +++ b/WeeGUI_MLI.s @@ -71,4 +71,6 @@ WGSetState = 74 WGViewSetRawTitle = 76 WGSetContentWidth = 78 WGSetContentHeight = 80 +WGStrokeRoundRect = 82 +WGCreateRadio = 84 diff --git a/applesoft.s b/applesoft.s index 11423a0..acb9bd1 100644 --- a/applesoft.s +++ b/applesoft.s @@ -386,21 +386,25 @@ WGAmpersandTempStrArgument_error: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGAmpersand_HOME -; Clears the screen -; &HOME +; Clears the screen to black (if 0) or "desktop" fill (if 1) +; &HOME(0 or 1) WGAmpersand_HOME: - jsr WGClearScreen - jsr WGBottomCursor + jsr WGAmpersandBeginArguments + jsr WGAmpersandIntArgument + pha + jsr WGAmpersandEndArguments + pla - rts + beq WGAmpersand_HOMEClearScreen - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; WGAmpersand_DESK -; Render the desktop -; &DESK -WGAmpersand_DESK: jsr WGDesktop + bra WGAmpersand_HOMEBottomCursor + +WGAmpersand_HOMEClearScreen: + jsr WGClearScreen + ; execution falls through here + +WGAmpersand_HOMEBottomCursor: jsr WGBottomCursor rts @@ -492,6 +496,45 @@ WGAmpersand_CHKBX: rts +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; WGAmpersand_RADIO +; Create a radio button +; &RADIO(id,x,y,"title") +WGAmpersand_RADIO: + jsr WGAmpersandBeginArguments + + jsr WGAmpersandIntArgument + sta WGAmpersandCommandBuffer+0 + jsr WGAmpersandNextArgument + + jsr WGAmpersandIntArgument + sta WGAmpersandCommandBuffer+1 + jsr WGAmpersandNextArgument + + jsr WGAmpersandIntArgument + sta WGAmpersandCommandBuffer+2 + jsr WGAmpersandNextArgument + + jsr WGAmpersandStrArgument + stx WGAmpersandCommandBuffer+3 + sty WGAmpersandCommandBuffer+4 + + jsr WGAmpersandEndArguments + + CALL16 WGCreateRadio,WGAmpersandCommandBuffer + + LDY_ACTIVEVIEW ; Flag this as an Applesoft-created view + lda #VIEW_STYLE_APPLESOFT + ora WG_VIEWRECORDS+4,y + sta WG_VIEWRECORDS+4,y + + jsr WGPaintView + jsr WGBottomCursor + + rts + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGAmpersand_PROG ; Create a progress bar @@ -1249,8 +1292,8 @@ WGAmpersandCommandTable: .byte TOKEN_HOME,0,0,0,0,0 .addr WGAmpersand_HOME -.byte "DESK",0,0 -.addr WGAmpersand_DESK +.byte "RADIO",0 +.addr WGAmpersand_RADIO .byte "WINDW",0 .addr WGAmpersand_WINDW diff --git a/macros.s b/macros.s index a3f5d3f..aafd3bd 100644 --- a/macros.s +++ b/macros.s @@ -93,10 +93,14 @@ pha lda SCRATCH1 pha + lda SCRATCH2 + pha .endmacro .macro RESTORE_ZPS ; Restores Zero Page locations we use for scratch + pla + sta SCRATCH2 pla sta SCRATCH1 pla diff --git a/memory.s b/memory.s index 6a03eb8..0a6e2a8 100644 --- a/memory.s +++ b/memory.s @@ -19,6 +19,7 @@ VIEW_STYLE_FANCY = $02 VIEW_STYLE_PROGRESS = $03 VIEW_STYLE_CHECK = $04 VIEW_STYLE_BUTTON = $05 +VIEW_STYLE_RADIO = $06 VIEW_STYLE_TAKESFOCUS = $04 ; Styles >= this one are selectable diff --git a/rects.s b/rects.s index 97d3708..a1dee4d 100644 --- a/rects.s +++ b/rects.s @@ -159,7 +159,7 @@ WGFillRect_horzLoopOddAlignedOneWidth: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -; WGStrokeRect +; WGStrokeRect / WGStrokeRoundRect ; Strokes a rectangle (assumes 80 cols) ; PARAM0: Left edge ; PARAM1: Top edge @@ -171,6 +171,8 @@ CH_TOP = '_'+$80 CH_BOTTOM = 'L' CH_LEFT = 'Z' CH_RIGHT = '_' +CH_ROUND_LEFT = '('+$80 +CH_ROUND_RIGHT = ')'+$80 CH_DOUBLE = '\' .macro PLOTHLINE @@ -194,8 +196,21 @@ CH_DOUBLE = '\' WGStrokeRect: - SAVE_AXY - SAVE_ZPS + pha + lda #CH_LEFT + sta SCRATCH1 + lda #CH_RIGHT + bra WGStrokeRect_common +WGStrokeRoundRect: + pha + lda #CH_ROUND_LEFT + sta SCRATCH1 + lda #CH_ROUND_RIGHT +WGStrokeRect_common: + sta SCRATCH2 + pla + SAVE_AXY + SAVE_ZPS ; Top and bottom edges ; @@ -374,7 +389,7 @@ WGStrokeRect_vertLoop: ; CASE 1: Left edge even-aligned, even width SETSWITCH PAGE2ON ldy #$0 - lda #CH_LEFT ; Plot the left edge + lda SCRATCH1 ; Plot the left edge sta (BASL),y lda PARAM2 ; Is width even? @@ -390,7 +405,7 @@ WGStrokeRect_vertLoop: dec tay SETSWITCH PAGE2OFF - lda #CH_RIGHT ; Plot the right edge + lda SCRATCH2 ; Plot the right edge sta (BASL),y jmp WGStrokeRect_vertLoopEvenAlignedNextRow @@ -402,7 +417,7 @@ WGStrokeRect_vertLoopEvenAlignedOddWidth: inc lsr tay - lda #CH_RIGHT ; Plot the right edge + lda SCRATCH2 ; Plot the right edge sta (BASL),y WGStrokeRect_vertLoopEvenAlignedNextRow: @@ -417,7 +432,7 @@ WGStrokeRect_vertLoopOdd: ; CASE 2: Left edge odd-aligned, even width SETSWITCH PAGE2OFF ldy #$0 - lda #CH_LEFT ; Plot the left edge + lda SCRATCH1 ; Plot the left edge sta (BASL),y lda PARAM2 ; Is width even? @@ -432,7 +447,7 @@ WGStrokeRect_vertLoopOdd: lsr tay SETSWITCH PAGE2ON - lda #CH_RIGHT ; Plot the right edge + lda SCRATCH2 ; Plot the right edge sta (BASL),y jmp WGStrokeRect_vertLoopOddAlignedNextRow @@ -444,7 +459,7 @@ WGStrokeRect_vertLoopOddAlignedOddWidth: inc lsr tay - lda #CH_RIGHT ; Plot the right edge + lda SCRATCH2 ; Plot the right edge sta (BASL),y WGStrokeRect_vertLoopOddAlignedNextRow: diff --git a/views.s b/views.s index b91375a..2b8dda1 100644 --- a/views.s +++ b/views.s @@ -156,6 +156,72 @@ WGCreateCheckbox_done: rts +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; WGCreateRadio +; Creates a new radio button +; PARAM0: Pointer to configuration struct (LSB) +; PARAM1: Pointer to configuration struct (MSB) +; +; Configuration struct: +; ID: View ID (0-f) +; XX: Screen X origin +; YY: Screen Y origin +; SL: String pointer (LSB) +; SH: String pointer (MSB) +; +WGCreateRadio: + SAVE_AXY + + ldy #0 + lda (PARAM0),y ; Find our new view record + pha ; Cache view ID so we can select when we're done + + asl + asl + asl + asl ; Records are 16 bytes wide + tax + + iny + lda (PARAM0),y + sta WG_VIEWRECORDS+0,x ; Screen X + + iny + lda (PARAM0),y + sta WG_VIEWRECORDS+1,x ; Screen Y + + lda #1 + sta WG_VIEWRECORDS+2,x ; Initialize screen width + sta WG_VIEWRECORDS+3,x ; Initialize screen height + sta WG_VIEWRECORDS+7,x ; Initialize view width + sta WG_VIEWRECORDS+8,x ; Initialize view height + + lda #VIEW_STYLE_RADIO + sta WG_VIEWRECORDS+4,x ; Style + + stz WG_VIEWRECORDS+5,x ; Initialize scrolling + stz WG_VIEWRECORDS+6,x + + stz WG_VIEWRECORDS+9,x ; Initialize state + stz WG_VIEWRECORDS+10,x ; Initialize callback + stz WG_VIEWRECORDS+11,x + + iny + lda (PARAM0),y + sta WG_VIEWRECORDS+12,x ; Title + iny + lda (PARAM0),y + sta WG_VIEWRECORDS+13,x + + pla + jsr WGSelectView ; Leave this as the active view + +WGCreateRadio_done: + RESTORE_AXY + rts + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; WGCreateProgress @@ -374,6 +440,8 @@ WGPaintView: pla ; Draw outline cmp #VIEW_STYLE_FANCY beq WGPaintView_decorated + cmp #VIEW_STYLE_RADIO + beq WGPaintView_radio jsr WGStrokeRect @@ -389,7 +457,10 @@ WGPaintView_decorated: jsr WGFancyRect jsr paintWindowTitle bra WGPaintView_done - + +WGPaintView_radio: + jsr WGStrokeRoundRect + ; execution falls through here WGPaintView_check: jsr paintCheck bra WGPaintView_done @@ -947,16 +1018,46 @@ WGViewFocusAction: SAVE_AXY lda WG_FOCUSVIEW - bmi WGViewFocusAction_done + bpl WGViewFocusAction_do + jmp WGViewFocusAction_done +WGViewFocusAction_do: LDY_FOCUSVIEW lda WG_VIEWRECORDS+4,y ; What kind of view is it? and #$f ; Mask off flag bits cmp #VIEW_STYLE_CHECK beq WGViewFocusAction_toggleCheckbox + cmp #VIEW_STYLE_RADIO + beq WGViewFocusAction_toggleRadio bra WGViewFocusAction_buttonClick ; Everything else treated like a button +WGViewFocusAction_toggleRadio: + lda #15 +WGViewFocusAction_toggleRadioLoop: + pha + cmp WG_FOCUSVIEW + beq WGViewFocusAction_toggleRadioLoopNext + LDY_AVIEW + lda WG_VIEWRECORDS+4,y + and #$f + cmp #VIEW_STYLE_RADIO + bne WGViewFocusAction_toggleRadioLoopNext + lda WG_VIEWRECORDS+9,y ; check if this radio button is selected + beq WGViewFocusAction_toggleRadioLoopNext + lda #0 + sta WG_VIEWRECORDS+9,y ; if so, deselect it and repaint + pla + pha + jsr WGSelectView + jsr WGPaintView +WGViewFocusAction_toggleRadioLoopNext: + pla + dec + bpl WGViewFocusAction_toggleRadioLoop + LDY_FOCUSVIEW + ; execution falls through here + WGViewFocusAction_toggleCheckbox: lda WG_VIEWRECORDS+9,y ; Change the checkbox's state and redraw eor #%00000001 diff --git a/weegui.dsk b/weegui.dsk index 9f47c4d..3efa95c 100644 Binary files a/weegui.dsk and b/weegui.dsk differ diff --git a/weegui.s b/weegui.s index c8266fc..64133d1 100644 --- a/weegui.s +++ b/weegui.s @@ -74,6 +74,8 @@ WGEntryPointTable: .addr WGViewSetRawTitle .addr WGSetContentWidth .addr WGSetContentHeight +.addr WGStrokeRoundRect +.addr WGCreateRadio ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/zeropage.s b/zeropage.s index 34e352b..ec5fa11 100644 --- a/zeropage.s +++ b/zeropage.s @@ -22,3 +22,4 @@ PARAM2 = $08 PARAM3 = $09 SCRATCH0 = $19 SCRATCH1 = $1a +SCRATCH2 = $1b