diff --git a/Makefile b/Makefile index c8e0d49..102bea6 100644 --- a/Makefile +++ b/Makefile @@ -8,8 +8,8 @@ all: redomod: rm -f go.* - go mod init - go mod tidy + GO111MODULE= go mod init + GO111MODULE= go mod tidy # sync repo to the github backup # git remote add github git@github.com:wit-go/widget.git diff --git a/action.go b/action.go new file mode 100644 index 0000000..b42e8ab --- /dev/null +++ b/action.go @@ -0,0 +1,104 @@ +package widget + +type Action struct { + ActionType ActionType + WidgetType WidgetType + + WidgetId int + ParentId int + + // Text string // what is visable to the user + ProgName string // a name useful for programming + + // most primitive widgets just store a single thing + Value any + + // how to arrange widgets + Direction Orientation + + // This is used for things like a slider(0,100) + X int + Y int + + // This is for the grid size & widget position + W int + H int + AtW int + AtH int + + // Put space around elements to improve look & feel + Margin bool + + // Make widgets fill up the space available + Expand bool +} + +type ActionType int // Add, SetText, Click, Hide, Append, Delete, etc + +const ( + Add ActionType = iota + Delete + Get + Set + GetText + SetText + AddText + Show + Hide + Enable + Disable + Margin + Unmargin + Pad + Unpad + Append + Move + Dump + User // the user did something (mouse, keyboard, etc) + InitToolkit // initializes the toolkit + CloseToolkit // closes the toolkit + UserQuit // the user closed the GUI + EnableDebug // open the debugging window +) + +func (s ActionType) String() string { + switch s { + case Add: + return "Add" + case Delete: + return "Delete" + case Get: + return "Get" + case Set: + return "Set" + case GetText: + return "GetText" + case SetText: + return "SetText" + case AddText: + return "AddText" + case Show: + return "Show" + case Hide: + return "Hide" + case Enable: + return "Enable" + case Disable: + return "Disable" + case Margin: + return "Margin" + case Unmargin: + return "Unmargin" + case Pad: + return "Pad" + case Unpad: + return "Unpad" + case Append: + return "Append" + case Move: + return "Move" + case Dump: + return "Dump" + } + return "ActionType.String() Error" +} diff --git a/doc.go b/doc.go new file mode 100644 index 0000000..7719a9d --- /dev/null +++ b/doc.go @@ -0,0 +1,14 @@ +package widget + +// passes information between the gui package and the toolkit plugins +// +// This is the only thing that is passed between the toolkit plugin +// +// what names should be used? This is not part of [[Graphical Widget]] +// Event() seems like a good name. +// Event is used too much: web dev, cloud, etc +// I'm using "Action". Maybe it should really be +// "Interaction" as per wikipedia [[User interface]] +// +// TODO: convert this to a protobuf (?) +// diff --git a/geom.go b/geom.go new file mode 100644 index 0000000..2232807 --- /dev/null +++ b/geom.go @@ -0,0 +1,64 @@ +package widget + +/* + 2D geometry values + + There are lots of issues when supporting multiple toolkit plugin + geometries. The geometries vary widely especially between the + graphical displays and the serial console ones. + + To simplyfy this, we stick to using the concepts: + + ------------------------------ ^ + | top | | + | | | + | left right | height + | | | + | bottom | | + ------------------------------ v + + <----------- width ----------> + + This way, width & height are always positive numbers. + + The qustion of (top,bottom) & (left,right) becomes problematic. + + In almost every toolkit, right > left. However, top & bottom + vary and a choice can not be made easily. Luckily, we maybe do + not have to make that decision here and can pass that determination + to the toolkits. So, we use excusively: + + geom(left, right, top, bottom) + size(width, height) +*/ + +type Geom struct { + Left any + Right any + Top any + Bottom any +} + +type Size struct { + Width any + Height any +} + +type Orientation int // Add, SetText, Click, Hide, Append, Delete, etc + +const ( + Horizontal Orientation = iota + Vertical +) + +func (s Orientation) String() string { + switch s { + case Horizontal: + return "Horizontal" + case Vertical: + return "Vertical" + default: + return "Horizontal" + } + return "Horizontal" +} diff --git a/grid.go b/grid.go new file mode 100644 index 0000000..0adedff --- /dev/null +++ b/grid.go @@ -0,0 +1,41 @@ +package widget + +// This is how grids are handled. On the application side, +// things are mostly handled this way. Web browsers, etc +// +// On the toolkit side, this must be translated into the display +// code. This is particularly complicated with ncurses but once +// done in the toolkits, bears fruit in the application code simplicity + +// NOTE: X numbers horizontally, Y is numbered down. Like in mathematics, EXCEPT Y IS DOWN +// this is the only sensible way. It's way too confusing to use negative numbers for Y. +// This is an attempt to make it simple for people to program against this code, +// then we hide these implementation details in the toolkit plugins + +// Grid numbering examples (H) or (W,H) +// ----------------------- +// -- (1) -- (2) -- (3) -- (X) +// ----------------------- +// +// (Y) +// --------- +// -- (1) -- +// -- (2) -- +// --------- +// +// (X,Y) +// -------------------------------------- +// -- (1,1) -- (2,1) -- (3,1) -- (4,1) -- +// -- (1,2) -- (2,2) -- (3,2) -- -- +// -- (1,3) -- -- (3,3) -- (4,3) -- +// -------------------------------------- + +type GridSize struct { + Width int + Height int +} + +type GridOffset struct { + X int + Y int +} diff --git a/reflect.go b/reflect.go new file mode 100644 index 0000000..783ecd0 --- /dev/null +++ b/reflect.go @@ -0,0 +1,96 @@ +package widget + +import ( + "reflect" + "strconv" +) + +func GetString(A any) string { + if A == nil { + // log.Warn("getString() got nil") + return "" + } + var k reflect.Kind + k = reflect.TypeOf(A).Kind() + + switch k { + case reflect.Int: + var i int + i = A.(int) + return strconv.Itoa(i) + case reflect.String: + return A.(string) + case reflect.Bool: + if A.(bool) == true { + return "true" + } else { + return "false" + } + default: + // log.Warn("getString uknown kind", k, "value =", A) + return "" + } + return "" +} + +// work like unix os.Exec() ? everything other than 0 is false +func GetBool(A any) bool { + if A == nil { + // log.Warn("getBool() got nil") + return false + } + var k reflect.Kind + k = reflect.TypeOf(A).Kind() + + switch k { + case reflect.Int: + var i int + i = A.(int) + if i == 0 { + return true + } else { + return false + } + case reflect.String: + if A.(string) == "true" { + return true + } else { + return false + } + case reflect.Bool: + return A.(bool) + default: + // log.Warn("getString uknown kind", k, "value =", A) + return false + } + return false +} + +// work like unix? everything other than 0 is false +func GetInt(A any) int { + if A == nil { + // log.Warn("getBool() got nil") + return -1 + } + var k reflect.Kind + k = reflect.TypeOf(A).Kind() + + switch k { + case reflect.Int: + return A.(int) + case reflect.String: + tmp := A.(string) + i, _ := strconv.Atoi(tmp) + return i + case reflect.Bool: + if A.(bool) { + return 0 + } else { + return -1 + } + default: + // log.Warn("getString uknown kind", k, "value =", A) + return -1 + } + return -1 +} diff --git a/widget.go b/widget.go index 0a0e5de..2ff7773 100644 --- a/widget.go +++ b/widget.go @@ -5,7 +5,7 @@ package widget // This is the only thing that is passed between the toolkit plugin // // what names should be used? This is not part of [[Graphical Widget]] -// Event() seems like a good name. +// Event() seems like a good name. // Event is used too much: web dev, cloud, etc // I'm using "Action". Maybe it should really be // "Interaction" as per wikipedia [[User interface]] @@ -14,42 +14,6 @@ package widget // type WidgetType int // Button, Menu, Checkbox, etc. -type ActionType int // Add, SetText, Click, Hide, Append, Delete, etc - -type Action struct { - ActionType ActionType - WidgetType WidgetType - - WidgetId int - ParentId int - - Text string // what is visable to the user - Name string // a name useful for programming - - // This is how the values are passed back and forth - // values from things like checkboxes & dropdown's - B bool - I int - S string - A any // switch to this or deprecate this? pros/cons? - - // This is used for things like a slider(0,100) - X int - Y int - - // This is for the grid size & widget position - W int - H int - AtW int - AtH int - - // Put space around elements to improve look & feel - Margin bool - - // Make widgets fill up the space available - Expand bool - -} const ( Unknown WidgetType = iota @@ -79,32 +43,6 @@ const ( Stdout // can be used to capture and display log output ) -const ( - Add ActionType = iota - Delete - Get - Set - GetText - SetText - AddText - Show - Hide - Enable - Disable - Margin - Unmargin - Pad - Unpad - Append - Move - Dump - User // the user did something (mouse, keyboard, etc) - InitToolkit // initializes the toolkit - CloseToolkit // closes the toolkit - UserQuit // the user closed the GUI - EnableDebug // open the debugging window -) - func (s WidgetType) String() string { switch s { case Root: @@ -160,45 +98,3 @@ func (s WidgetType) String() string { } return "WidgetType.String() Error" } - -func (s ActionType) String() string { - switch s { - case Add: - return "Add" - case Delete: - return "Delete" - case Get: - return "Get" - case Set: - return "Set" - case GetText: - return "GetText" - case SetText: - return "SetText" - case AddText: - return "AddText" - case Show: - return "Show" - case Hide: - return "Hide" - case Enable: - return "Enable" - case Disable: - return "Disable" - case Margin: - return "Margin" - case Unmargin: - return "Unmargin" - case Pad: - return "Pad" - case Unpad: - return "Unpad" - case Append: - return "Append" - case Move: - return "Move" - case Dump: - return "Dump" - } - return "ActionType.String() Error" -}