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.
+
+
+Assembly | Applesoft |
---|
+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
Assembly | Applesoft |
---|
X: WGClearScreen
|
-&HOME
+&HOME(0)
|
@@ -911,7 +937,7 @@ Paints a desktop background on the screen.
Assembly | Applesoft |
---|
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.
+
+
+Assembly | Applesoft |
---|
+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