Skip to content

Commit

Permalink
gfx: fix PR #8 inconsistencies
Browse files Browse the repository at this point in the history
  • Loading branch information
larpon committed Dec 22, 2023
1 parent ed88769 commit c0db5b1
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 107 deletions.
6 changes: 3 additions & 3 deletions examples/ui/ui.v
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ pub fn (mut a App) init() ! {
a.window.mode = .ui

root := &ui.Rectangle{
width: a.canvas().width
height: a.canvas().height
width: a.window.width
height: a.window.height
fills: .body
body: [
&ui.Button{
x: 50
y: 50
width: 50
height: 50
radius: 3
label: 'Hello World'
},
]
}
Expand Down
4 changes: 2 additions & 2 deletions lib/gfx.b.v
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub enum EndEnum {
passthru
}

[params]
@[params]
pub struct EndOptions {
how EndEnum
}
Expand Down Expand Up @@ -521,7 +521,7 @@ const dontcare_pass = gfx.PassAction{
pub fn make_clear_pass(r f32, g f32, b f32, a f32) gfx.PassAction {
mut color_action := gfx.ColorAttachmentAction{
load_action: .clear
clear_value: Color{
clear_value: gfx.Color{
r: r
g: g
b: b
Expand Down
76 changes: 66 additions & 10 deletions ui/button.v
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// that can be found in the LICENSE file.
module ui

// import shy.lib as shy
import shy.lib as shy

// Item is the base type for all UI elements.
// By embedding `Item` in a struct - the struct fulfills
Expand All @@ -14,17 +14,73 @@ module ui
// creation of new UI nodes that can be reused across code-bases.
@[heap]
pub struct Button {
Rectangle // pub mut:
// text Text
Rectangle
pub mut:
label string
}

// init initialize this `Button` and it's children.
pub fn (mut b Button) init(ui &UI) ! {
// assert i != unsafe { nil }
b.radius = 3
b.color = ui.theme.colors.button_background

b.Rectangle.init(ui)!
}

// update is called when the `Button` needs to e.g. update it's layout or position.
pub fn (mut b Button) update() {
// assert i != unsafe { nil }
//
b.Rectangle.update()
}

// draw draws the `Button` and/or any child nodes.
pub fn (b &Button) draw(ui &UI) {
assert b != unsafe { nil }
mut mb := unsafe { b }
mb.Rectangle.color = ui.theme.colors.button_background
b.Rectangle.draw(ui)
for child in b.body {
child.draw(ui)
pub fn (mut b Button) draw() {
// assert b != unsafe { nil }
// mut mb := unsafe { b }
b.Rectangle.draw()

// Draw text
vs := b.visual_state()

et := b.ui.easy.text(
x: vs.x
y: vs.y
// width: vs.width
// height: vs.height
origin: shy.Anchor.center
text: b.label
)
et.draw()

for mut child in b.body {
child.draw()
}
}

// event delegates `e` `Event` to any child nodes and/or it's own listeners.
pub fn (mut b Button) event(e Event) ?&Node {
if node := b.Rectangle.event(e) {
return node
}
hit := b.Rectangle.contains_pointer_device()
b.color = b.ui.theme.colors.button_background
if hit {
// vs := b.visual_state()
b.color = b.ui.theme.colors.button_background.lighter()
}

if hit {
for on_event in b.on_event {
assert !isnil(on_event)

if on_event(b, e) {
// If `on_event` returns true, it means
// a listener on *this* item has accepted the event
return b
}
}
}
return none
}
119 changes: 45 additions & 74 deletions ui/item.v
Original file line number Diff line number Diff line change
Expand Up @@ -19,56 +19,75 @@ pub struct Item {
pub:
id u64 = 1
mut:
ui &UI = unsafe { nil }
// NOTE The `unsafe { nil }` assignment once resulted in several V bugs: https://github.com/vlang/v/issues/16882
// ... which was quickly fixed but one of them couldn't be made as an MRE (minimal reproducible example) - so it's
// a target of regression: https://github.com/vlang/v/commit/2119a24 <- this commit has the fix.
parent &Node = unsafe { nil }
body []&Node
on_event []OnEventFn
// nice to have state
hovered_by_pointer_device bool
pub mut:
// Transformations
rotation f32
scale f32 = 1.0
offset vec.Vec2[f32]
origin shy.Anchor
origin shy.Origin
}

// init initialize this `Item` and it's children.
pub fn (i &Item) init() ! {
assert i != unsafe { nil }
for child in i.body {
child.init()!
pub fn (mut i Item) init(ui &UI) ! {
// TODO V BUG #20220 (https://github.com/vlang/v/issues/20220)
// TODO V BUG #20229 (https://github.com/vlang/v/issues/20229)
// assert i != unsafe { nil }
i.ui = ui
for mut child in i.body {
child.init(ui)!
}
i.update()
}

// update is called when the `Item` needs to e.g. update it's layout.
pub fn (mut i Item) update() {
// assert i != unsafe { nil }
for mut child in i.body {
child.update()
}
}

/*
// parent returns this `Item`'s parent.
pub fn (i &Item) parent() &Node {
assert i != unsafe { nil }
//assert i != unsafe { nil }
// TODO BUG returning ?&Node is not possible currently: if isnil(i.parent) { return none }
return i.parent
}
*/

// reparent sets this `Item`'s `parent` to `new_parent`.
pub fn (i &Item) reparent(new_parent &Node) {
assert i != unsafe { nil }
assert new_parent != unsafe { nil }
pub fn (mut i Item) reparent(new_parent &Node) {
// assert i != unsafe { nil }
// assert new_parent != unsafe { nil }
unsafe {
i.parent = new_parent
}
}

// draw draws the `Item` and/or any child nodes.
pub fn (i &Item) draw(ui &UI) {
pub fn (mut i Item) draw() {
// println(ptr_str(i.ui))
// Items are invisible, they have a size only
for child in i.body {
child.draw(ui)
for mut child in i.body {
child.draw()
}
}

// visual_state returns this `Item`'s `VisualState`.
@[inline]
pub fn (i &Item) visual_state() VisualState {
assert i != unsafe { nil }
p := i.parent()
// assert i != unsafe { nil }
p := i.parent //()
if !isnil(p) && p.id != 0 {
// TODO switch to matricies and actually do the needed transformation math here
p_vs := p.visual_state()
Expand Down Expand Up @@ -96,11 +115,11 @@ pub fn (i &Item) visual_state() VisualState {
}

// event delegates `e` `Event` to any child nodes and/or it's own listeners.
pub fn (i &Item) event(e Event) ?&Node {
pub fn (mut i Item) event(e Event) ?&Node {
// By sending the event on to the children nodes
// it's effectively *bubbling* the event upwards in the
// tree / scene graph
for child in i.body {
for mut child in i.body {
if node := child.event(e) {
return node
}
Expand All @@ -112,11 +131,13 @@ pub fn (i &Item) event(e Event) ?&Node {
vs.Rect.contains(e.x, e.y)
}
else {
true
false
}
}

i.hovered_by_pointer_device = false
if hit {
i.hovered_by_pointer_device = true
for on_event in i.on_event {
assert !isnil(on_event)

Expand All @@ -130,6 +151,12 @@ pub fn (i &Item) event(e Event) ?&Node {
return none
}

// contains_pointer_device returns `true` if this item contains the coordinates for
// a pointer device, such as a computer mouse.
pub fn (i &Item) contains_pointer_device() bool {
return i.hovered_by_pointer_device
}

/*
fn (mut i Item) shutdown() {
for child in i.body {
Expand All @@ -141,62 +168,6 @@ fn (mut i Item) shutdown() {
//i.body.free()
}*/

@[heap]
pub struct Rectangle {
Item
pub mut:
// extra parts
stroke shy.Stroke
radius f32 // rounded corner radius. 0 = none
color shy.Color = shy.colors.shy.red
fills shy.Fill = .body | .stroke
}

/*
// parent returns the parent Node.
pub fn (r &Rectangle) parent() &Node {
return r.Item.parent()
}
*/

// draw draws the `Rectangle` and/or any child nodes.
pub fn (r &Rectangle) draw(ui &UI) {
p_vs := r.visual_state()
er := ui.easy.rect(
x: p_vs.x
y: p_vs.y
width: p_vs.width
height: p_vs.height
rotation: p_vs.rotation
scale: p_vs.scale
offset: p_vs.offset
origin: p_vs.origin
// easy rect config
stroke: r.stroke
radius: r.radius
color: r.color
fills: r.fills
)
er.draw()
// Draw rest of tree (children) on top
r.Item.draw(ui)
}

/*
// visual_state returns this `Rectangle`'s `VisualState`.
@[inline]
pub fn (r &Rectangle) visual_state() VisualState {
return r.Item.visual_state()
}
*/

/*
// event sends an `Event` any child nodes and/or it's own listeners.
pub fn (r &Rectangle) event(e Event) ?&Node {
return r.Item.event(e)
}
*/

@[heap]
pub struct EventArea {
Item
Expand Down Expand Up @@ -253,7 +224,7 @@ pub fn (pea &PointerEventArea) visual_state() VisualState {
}*/

// event sends an `Event` any child nodes and/or it's own listeners.
pub fn (pea &PointerEventArea) event(e Event) ?&Node {
pub fn (mut pea PointerEventArea) event(e Event) ?&Node {
if e is MouseButtonEvent || e is MouseMotionEvent || e is MouseWheelEvent {
ex := match e {
MouseButtonEvent, MouseMotionEvent, MouseWheelEvent {
Expand Down
Loading

0 comments on commit c0db5b1

Please sign in to comment.