-
Notifications
You must be signed in to change notification settings - Fork 32
Builder#648 support Widget Monitor #306
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
monitor.go
Outdated
// stageMonitor class. | ||
type stageMonitor struct { | ||
// MonitorWidget class. | ||
type MonitorWidget struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- stageMonitor 这个名字是 scratch 这边来的,是否保留兼容比较好?
- 另外不见得所有 widget 的名字都要带上 widget 吧?我个人其实喜欢不带 widget 字样的,比如 timer,不一定非要叫 timerWidget。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The name MonitorWidget comes from the requirements document: spx: support Widget Monitor builder#648.
- I prefer to use a single module for all Widget types, named something like widget.Monitor. However, the implementation of Monitor depends on data structures such as drawContext. These data structures are placed in the top-level namespace. Extracting these structures into a separate general module to handle dependencies would require significant changes, so I kept the original design and placed MonitorWidget in the top-level namespace as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- stageMonitor 这个名字是 scratch 这边来的,是否保留兼容比较好?
As far as I know, stageMonitor
is a internal concept of Scratch. Scratch users do not need to know that name. While in Go+ builder, we expose the concept "Monitor" as a widget type (by two ways: 1. text "Monitor" in the Builder UI 2. MonitorWidget
in code to do type-assertion). So the simplicity & intelligibility matters for its name here, and I don't think "stageMonitor" is a good name for this Go+ Builder widget type.
If we need to keep compatibility, I'll prefer to support both "stageMonitor" & "monitor", the first for compatibility & the second for Go+ Builder.
- 另外不见得所有 widget 的名字都要带上 widget 吧?我个人其实喜欢不带 widget 字样的,比如 timer,不一定非要叫 timerWidget。
Monitor
& MonitorWidget
are both fine for me. @xushiwei If you prefer Monitor
here, we can name it Monitor
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned in https://github.com/goplus/spx/pull/306/files#r1703607442
Let's rename MonitorWidget
to Monitor
. I'll update the product doc as well.
return widget | ||
} | ||
} | ||
return nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It panics if not found.
We expect it to panic here, to keep consistent with other similar operations, e.g. turnTo("not_exist")
monitor.go
Outdated
@@ -59,9 +61,14 @@ type stageMonitor struct { | |||
"isDiscrete": true, | |||
"visible": true | |||
*/ | |||
func newStageMonitor(g reflect.Value, v specsp) (*stageMonitor, error) { | |||
func newMonitorWidget(g reflect.Value, v specsp) (*MonitorWidget, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be ok to omit color
in config (v
here), as it makes no sense for current monitor style. While it panics if I do so
panic: color is nil
} | ||
w := labelW + textRectW + (stmHoriGapSm * 3) | ||
h += (stmVertGapSm * 2) | ||
hGap := stmHoriGapSm * p.size |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's issue with style details here. For example:
- The gap size and rect height is incorrect
- The label color is not correct
- There should be no out border for the round-rect
- There should be background of
#fff
- The background of value-part is translucent, which is not expected
- There should be no border of round-rect of value-part
- The width of value-part is not right

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issues related to font size, font changing, and layout adaptation will be resolved after the font library implementation is upgraded.
@@ -163,24 +171,30 @@ func (p *stageMonitor) draw(dc drawContext) { | |||
default: | |||
x, y := int(p.x), int(p.y) | |||
labelRender := gdi.NewTextRender(defaultFont2, 0x80000, 0) | |||
labelRender.Scale = p.size | |||
labelRender.AddText(p.label) | |||
labelW, h := labelRender.Size() | |||
|
|||
textRender := gdi.NewTextRender(defaultFontSm, 0x80000, 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The font size for value-part is not correct, 12px
(maybe defaultFont2
?) expected, while got 11px
(defaultFontSm
)
@@ -163,24 +171,30 @@ func (p *stageMonitor) draw(dc drawContext) { | |||
default: | |||
x, y := int(p.x), int(p.y) | |||
labelRender := gdi.NewTextRender(defaultFont2, 0x80000, 0) | |||
labelRender.Scale = p.size | |||
labelRender.AddText(p.label) | |||
labelW, h := labelRender.Size() | |||
|
|||
textRender := gdi.NewTextRender(defaultFontSm, 0x80000, 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And is it possible to specify font file? Or should we wait for
the upgrade of the font library to EbitenEngine or Godot.
and then support it?
[Git-flow] Hi @JiepengTan, There are some suggestions for your information: Rebase suggestions
Which seems insignificant, recommend to use For other If you have any questions about this comment, feel free to raise an issue here: |
@@ -75,8 +81,8 @@ func newStageMonitor(g reflect.Value, v specsp) (*stageMonitor, error) { | |||
x := v["x"].(float64) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the current implementation, for widgets' position, x: 0, y: 0
means the left-top corner (of viewport); while for sprites' position, x: 0, y: 0
means the center point (of map).
Though the positioning behavior of widgets and sprites is different: widgets are positioned relative to the viewport, and sprites are positioned relative to the map. I believe it'll be better to keep the convention that x: 0, y: 0
means the center point for both.
@JiepengTan @xushiwei What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And the direction of the coordinate system. Currently, for widgets, the Y-axis points down, while for sprites, the Y-axis points up; I suggest we unify this as well.
@@ -163,24 +170,30 @@ func (p *stageMonitor) draw(dc drawContext) { | |||
default: | |||
x, y := int(p.x), int(p.y) | |||
labelRender := gdi.NewTextRender(defaultFont2, 0x80000, 0) | |||
labelRender.Scale = p.size |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are two different implementations for TextRender
here:
internal/gdi/gdi.go
, which will be used for build without-tags canvas
internal/gdi/gdi_canvas.go
, which will be used for build with-tags canvas
In this PR the field Scale
is added in the first implementation only.
So if we run
GOOS=js GOARCH=wasm go build -tags canvas
to build spx, it throws error:
# github.com/goplus/spx
./monitor.go:173:15: labelRender.Scale undefined (type gdi.TextRender has no field or method Scale)
./monitor.go:178:14: textRender.Scale undefined (type gdi.TextRender has no field or method Scale)
In web page of Builder, we use spx version which is built with -tags canvas
to render within HTML Canvas.
To fix that, I think we should add field Scale
in the implementation for TextRender
in internal/gdi/gdi_canvas.go
as well.
return | ||
} | ||
|
||
// ------------------------------------------------------------------------------------- | ||
// IWidget | ||
func (pself *Monitor) GetName() string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here it is *Monitor
instead of Monitor
who implemented interface Widget
. Hence the user will have to do type assertion like this:
scoreMonitor := getWidget("life").(*Monitor)
To understand the code, the user will have to know the concept "pointer", which I think is not expected. To avoid the user noticing concept "pointer", I'll suggest to rename type Monitor struct
to something like MonitorImpl
and make a type alias for *MonitorImpl
:
type MonitorImpl struct {}
func (pself *MonitorImpl) Visible() bool {}
func (pself *MonitorImpl) Show() {}
func (pself *MonitorImpl) Hide() {}
type Monitor = *MonitorImpl
Then the user can do type assertion with Monitor
without noticing pointer:
scoreMonitor := getWidget("life").(Monitor)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, we will support
// generics is utilized under the hood
scoreMonitor := getWidget(Monitor, "life")
rather than
scoreMonitor := getWidget("life").(Monitor)
goplus/builder#648
Project file 648.zip
Monitor.mp4
PS: The issues with font scaling and position adaptation will be resolved after the upgrade of the font library to EbitenEngine or Godot. Currently, go+builder can disable the Monitor's scaling feature to circumvent this bug.