progress with uik internals, layouting

225 views
Skip to first unread message

John Asmuth

unread,
Apr 21, 2012, 1:39:02 PM4/21/12
to go-...@googlegroups.com
Hi all,

As the topic suggests, I've been busy.

I've revamped a lot of the stuff inside block and foundation to make it easier for specialization blocks and foundations (that is, type MyBlock struct { Block; ... } and type MyFoundation struct { Foundation; ... }) to reuse code. Now Block and Foundation have a .HandleEvent(interface{}) method that specializations can call to deal with a default case when switching on event types.

Specializations are allowed to call methods on their embedded pieces - but different components are not allowed to call methods on each other.

Having all inter-component communication be done via non-blocking channel operations is important to the goal of not letting components get in each others' ways.

I've also created a "flow" layout, in the layouts package. It's not something that will remain, probably, but it places its children according to the size hints it receives from them, and shows how a more interesting layouter can be built.

My current intention is to create one basic layouter similar to java's GridBagLayout. Once such a thing exists, the equivalent of gtk's hbox() and vbox() can be built easily.

Any of the design wizards out there have more thoughts on this aspect?

Anthony Starks

unread,
Apr 23, 2012, 5:52:49 AM4/23/12
to go-...@googlegroups.com
I've been experimenting with something I call the percent box (pbox), where a pbox is made up of sections with a specified location (x,y), and dimension (w,h).  Both locations and dimensions are expressed as percentages of the surrounding box.  

For example, this description:

<pbox width="1024" height="768" inset="4" bgcolor="black">
        <section x="0"  y="0"  w="60" h="100" bgcolor="red"/>
        <section x="60" y="0"  w="40" h="50"  bgcolor="green"/>
        <section x="60" y="50" w="40" h="50"  bgcolor="blue"/>
</pbox>


Continuing, this description emulates the colors and layout of the website "The Verge"

<pbox width="1024" height="768" inset="1">
    <section x="0"      y="0"       w="33.3"    h="66.7"    bgcolor="purple"    tcolor="white"/>
    <section x="33.3"   y="0"       w="33.3"    h="33.3"    bgcolor="green"     tcolor="white"/>
    <section x="33.3"   y="33.3"    w="33.3"    h="33.3"    bgcolor="orange"    tcolor="white"/>
    <section x="33.3"   y="66.7"    w="33.3"    h="33.3"    bgcolor="green"     tcolor="white"/>
    <section x="0"      y="66.7"    w="33.3"    h="33.3"    bgcolor="orange"    tcolor="white"/>
    <section x="66.7"   y="0"       w="33.3"    h="33.3"    bgcolor="green"     tcolor="white"/>
    <section x="66.7"   y="33.3"    w="33.3"    h="66.7"    bgcolor="red"       tcolor="white"/>
</pbox>


Finally, adding content and style:

<pbox width="1024" height="768" bgcolor="white" inset="1" font="Calibri" tsize="64" tunit="pt" tcolor="white">
<section x="0"    y="0"  w="100"  h="20" bgcolor="rgb(127,0,0)">CICERO, ILL.</section>
<section x="0"    y="25" w="33.3" h="10" bgcolor="rgb(150,150,150)" tsize="25">POPULATION</section>
<section x="33.3" y="25" w="33.3" h="10" bgcolor="rgb(150,150,150)" tsize="25">FORECLOSURE RATE</section>
<section x="66.7" y="25" w="33.3" h="10" bgcolor="rgb(150,150,150)" tsize="25">SINGLE-FAMILY DETACHED HOMES</section>
<section x="0"    y="35" w="33.3" h="20" bgcolor="rgb(150,150,150)">80,550</section>
<section x="33.3" y="35" w="33.3" h="20" bgcolor="rgb(150,150,150)">8.6%</section>
<section x="66.7" y="35" w="33.3" h="20" bgcolor="rgb(150,150,150)">36%</section>
<section x="0"    y="55" w="50"   h="15" bgcolor="rgb(150,150,150)" tsize="25">HOMEOWNERS PAYING MORE THAN 30% OF INCOME ON HOUSING</section>
<section x="50"   y="55" w="50"   h="15" bgcolor="rgb(150,150,150)" tsize="25">% OF OCCUPIED UNITS THAT ARE OVERCROWDED</section>
<section x="0"    y="70" w="50"   h="30" bgcolor="rgb(150,150,150)">56%</section>
<section x="50"   y="70" w="50"   h="30" bgcolor="rgb(150,150,150)">5%</section>
</pbox>


The Go structs:

type Pbox struct {
Width    int     `xml:"width,attr"`
Height   int     `xml:"height,attr"`
Inset    int     `xml:"inset,attr"`
Tsize    int     `xml:"tsize,attr"`
Tunit    string  `xml:"tunit,attr"`
Tcolor   string  `xml:"tcolor,attr"`
Font     string  `xml:"font,attr"`
Bgcolor  string  `xml:"bgcolor,attr"`
Sections []slist `xml:"section"`
}

type section struct {
dx, dy, dw, dh int
X              float64 `xml:"x,attr"`
Y              float64 `xml:"y,attr"`
W              float64 `xml:"w,attr"`
H              float64 `xml:"h,attr"`
Tsize          float64 `xml:"tsize,attr"`
Id             string  `xml:"id,attr"`
Label          string  `xml:"label,attr"`
Bgcolor        string  `xml:"bgcolor,attr"`
Tcolor         string  `xml:"tcolor,attr"`
Tstyle         string  `xml:"tstyle,attr"`
Align          string  `xml:"align,attr"`
Href           string  `xml:"href,attr"`
Content        string  `xml:",chardata"`
}

John Asmuth

unread,
Apr 23, 2012, 1:58:40 PM4/23/12
to go-...@googlegroups.com
I like this - I don't immediately see how to do a pbox with a gridbag, or vice versa (a gridbag would auto-resize itself when its components resize themselves), so it seems like a good idea to provide that as well.

I've got a rudimentary gridbag working - what are the odds that you take a look at that and use its example to make the pbox? I don't do this just to dump work on you. I really just want someone who isn't me to point out the irritating bits of the current interface :)

- John

John Asmuth

unread,
Apr 23, 2012, 1:58:55 PM4/23/12
to go-...@googlegroups.com
I like this - I don't immediately see how to do a pbox with a gridbag, or vice versa (a gridbag would auto-resize itself when its components resize themselves), so it seems like a good idea to provide that as well.

I've got a rudimentary gridbag working - what are the odds that you take a look at that and use its example to make the pbox? I don't do this just to dump work on you. I really just want someone who isn't me to point out the irritating bits of the current interface :)

- John

On Monday, April 23, 2012 5:52:49 AM UTC-4, Anthony Starks wrote:

John Asmuth

unread,
Apr 23, 2012, 1:59:05 PM4/23/12
to go-...@googlegroups.com
I like this - I don't immediately see how to do a pbox with a gridbag, or vice versa (a gridbag would auto-resize itself when its components resize themselves), so it seems like a good idea to provide that as well.

I've got a rudimentary gridbag working - what are the odds that you take a look at that and use its example to make the pbox? I don't do this just to dump work on you. I really just want someone who isn't me to point out the irritating bits of the current interface :)

- John

On Monday, April 23, 2012 5:52:49 AM UTC-4, Anthony Starks wrote:

John Asmuth

unread,
Apr 25, 2012, 11:22:30 AM4/25/12
to go-...@googlegroups.com
I've changed the drawing method to synchronous, since the concurrent compositing method was far too slow and it didn't seem like there was a good way to collect groups of updates.

The bright side is that it still stays out of the way of the event handling, and I think that is where most delays happen anyway: people (understandably) like to write linear code in their event handlers. With go.uik you can do that without performance issues (except that this one component won't respond to more events until you're done). You still have to draw quickly, though.

At some point I might put in a mechanism to time-out draws that take too long, and still display everything else. I know how I'd do it, but it's a bit of mechanics and I'll just keep it in mind if the issue ever becomes interesting.

- John

John Asmuth

unread,
May 19, 2012, 9:40:54 PM5/19/12
to go-...@googlegroups.com
Been thinking a bit more, and I think that some kind of configuration file, like the XML you provide (though json might be nicer), could be the way to go.

A suggestion - instead of "67", maybe "2/3"?

I'm creating (in my head, so far) a way to make layouts pluggable. That is, a Foundation type that takes a new "Layout" type, which is something that, given a configuration, a set of widgets to stick into that configuration, and their min/max/preferred sizes, assign bounding boxes to each of those widgets. This would at least make it so no one has to grok the Foundation boilerplate - you could just instantiate a Foundation and give it the Layout (and give the Layout the widgets). I'll turn the grid into the first example.

Maybe then you could turn pbox into the second? :)

- John

On Monday, April 23, 2012 5:52:49 AM UTC-4, Anthony Starks wrote:

Daniel Skinner

unread,
May 19, 2012, 10:16:34 PM5/19/12
to go-...@googlegroups.com

Regarding pbox, this reminds me of weights in android layouts, except instead of defining the explicit percentage, its derived from the value divided by the sum of the parents children. So 3 children with a weight of 1 gives a total weight of 3, and thus ~= 33.3%

Change one of the children's weight to 2 and now total weight is 4 and that child takes up 50% with the other two taking up 25% each.

You can also explicitly state what the sum should be on the parent.

Overall, I find this approach works well as it provides a bit of flexibility but its function is not immediately obvious to newcomers I find.

--
You received this message because you are subscribed to the Google Groups "go-uik" group.
To view this discussion on the web visit https://groups.google.com/d/msg/go-uik/-/PlAguVRNduYJ.
To post to this group, send email to go-...@googlegroups.com.
To unsubscribe from this group, send email to go-uik+un...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/go-uik?hl=en.

Daniel Skinner

unread,
May 19, 2012, 10:22:21 PM5/19/12
to go-...@googlegroups.com

And also, even though I didn't state it, this approach would inheritantly work with input like 67 or 2/3, just depends on implementation details and constraints that might seem fitting for keeping ppl from writing whacky layouts for the sanity of all

chance mcdonald

unread,
May 23, 2012, 11:49:44 AM5/23/12
to go-...@googlegroups.com
Just wanted to say thanks for developing this gui for golang.
To unsubscribe from this group, send email to go-uik+unsubscribe@googlegroups.com.

John Asmuth

unread,
May 23, 2012, 3:48:40 PM5/23/12
to go-...@googlegroups.com
layouts.Grid and layouts.PadBox now use a new foundation type, layouts.Layouter. The Grid and PadBox need to implement the LayoutEngine interface, and if pbox does too then it should make it much easier to make a working layout.

Take a look and let me know what you think?

There is only one semi-subtle part, I think, having to do with thread-safety. All of the methods defined in the LayoutEngine interface will be called from the Layouter's goroutine. Extra methods (like those used to add blocks or set configurations on the Grid, Padbox or Pbox) will be called from different goroutines, so it's important to keep that in mind when dealing with the shared data in your type.

The way I am solving that issue is a method Layouter.Config(x), which can be called from any goroutine, and will then call LayoutEngine.ConfigUnsafe(x), with the same x, moving the data safely into the right goroutine. The thing to do at that point is to do a type switch to see what the message actually is.

- John

John Asmuth

unread,
May 23, 2012, 3:48:56 PM5/23/12
to go-...@googlegroups.com
Thanks :)

John Asmuth

unread,
May 23, 2012, 3:53:06 PM5/23/12
to go-...@googlegroups.com
I think this suggestion is pretty reasonable (especially better than erroring out when weights to sum correctly), but I'm not going to make any executive decisions here. It's Anthony's project :)
To unsubscribe from this group, send email to go-uik+unsubscribe@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages