Apologies in advance if I am just repeating anyone else's idea, as I have skimmed, I think that the defer op idea is a good one, and it can solve more problems than zindex for overlays.
The defer op would function as a 'last op only' each new push to the list would become the one that functions, as in the drawing order, the one at the top is rendered last, and thus its' defers are the ones that should be processed, and the others discarded. This would be done by using a loop to drain the channel into a predeclared variable and then processing it at the end of the render queue.
This is something that could do more than just determining the topmost, active layer, it can also deal with any other type of concurrent requests that should only operate the last one and discard the rest. Such as identifying which tab of a stack selector is active, since its operations also have the same property as the zindex problem - its ops are the ones that get to the GPU, and thus its deferred operations end up at the end of the queue.
The atomic FIFO design of CSP channels enables this kind of programming, which stays more within the idiom of Gio itself, as well as exploiting the language's native use of it.
Oh. yes, of course, this isn't a pure channel based design problem, the queue is, however FIFO and the same principles apply.
I of course prefer to move this into the run loop, as it enables the direct use of channel syntax. That's probably not relevant as you can wrap channel sends with functions anyway.
I thought further about what I wrote in this post previously and decided that it was horribly cumbersome. This is yet another example where the fluent programming 'Domain Specific Language' has massive advantages. By wrapping all of the creation of objects in function calls you gain the ability to generate secondary data structures that automate this process of generating the tree structures.
Simply embedding your tab movement type into all 'tabbable' widgets, and have these widgets embed to a central variable storing the tab movement type's state, you can have all of the necessary data implemented without having to specify a thing, except to disrupt the intrinsic tree structure (and thus grouping).
You can then make short and simple flag-functions that flip values to do such things as specifying groups, and their starting points, observe their visibility properties, and all sorts of other things that I probably haven't thought of.
It's for this reason I have tenaciously adhered to this grammar, and why I have been slowly developing the architecture for an entire development environment that builds upon this capability.
The thing that was most frustrating for me in the beginning with Gio was the opacity of widgets. DSL solved the problem by allowing a state variable to cut across arbitrary branches of trees.
Thanks for pointing me in the right direction, I have been thinking how to implement a lot recently. I will move to there and mark this resolved.
So, in other words, I need to write functions that mimic the behaviour under the 'gain focus' condition in editor.go, right? Adding those events to the gtx.ops queue?
Then it looks like those booleans and the functions are all outdated, and indeed nobody else was using them. I see the sense of it though it's very minimalistic implementation, there really should be an entire keyboard focus set which would by default follow the tree of widgets as its path.
I thought I had better dig around a bit and see if I just have missed something with an example of code somewhere that calls the focus method. It used to work, and even, when an editor was focused on an old configuration widget, when it was scrolled, the focus jumped to the first next editor to be rendered.
But I haven't seen this function work at all since at least october last year in any of my code. I figured I could defer dealing with the problem until later.
I'm mainly posting this issue in order to canvas the devs watching this issue tracker whether they can confirm they have observed the same issue, or, more happily, that they can point me at a repository that has this function in use and it is working.
I just realised that I could probably roll the whole flexed/rigid chained parameters on Flex so you can just straight say 'Rigid(' and voila a flex is created in the function if it hasn't already been. I mean, it's just two versions that start from either package root or another type (I embed several things, theme, window, other state structure relevant to the interface)
By the way, there is no reason I can see why dynamically generated flexes would create garbage, since they are not reconfigured. Go just mostly doesn't let you tinker with mutability, but if a slice is never deallocated or resliced it's not going to generate garbage and even then the garbage is only the metadata.
Like, the scroller, it can be out of view and not painting but won't be deallocated and instantly comes up with its last state when the switcher brings it into the view. Think of how many options that is when you combine two words in it, RigidEnd(...layout.Widget).RigidStart(...layout.Widget).RigidW(...layout.Widget).RigidSE(...layout.Widget)... Put the options into a couple of slices and all of those variants can be generated automatically with iteration, I think you could at least collapse Flex and Direction into one unified scheme this way.
This is why I wrapped all of the widgets in chained methods. It's just
For the case of Flex it's: Flex().Rigid().Flexed(0.5,).Fn(gtx)
Then when you are embedding them into each other, you want to break the line after each dot operator if there is more than two (or even sometimes for two).Flex(). Rigid( <widget> ). Flexed(0.5, <--- <widget> ). <--- Fn(gtx)
As you can see, if you click and drag along the gutter of most editors, covering the area of those two arrows, you can easily switch it. Goland has a nice 'flip' function that works with
,and most math operators, but unfortunately not the dot operator. But you can see how easily that could be done and how pleasant it would make rearranging the structure of a complex layout.
About the only downside is that practically doubles the indentation, two for each level of depth, which then forces me to cut the inner parts out into logical groups in functions, but you can go pretty deep if you aren't dividing the screen a lot horizontally, before having a mess.
I find in some, maybe a lot of cases, that I am using Flexed.Rigid blocks to counteract the widget's inbuilt expanding tendency, and one of the widgets that does this is the Label. As such, I removed that feature and use Flex or Direction to implement center/left/right (or all 8 directions and centre).
My overall feeling is that there is a lot of overlap between the several different layout widgets, that there probably is a way to collapse and simplify them. One, that reading this issue brought up was to change my methods to variadic, and then within the structure outlined above, instead of only one widget, you can put one, or many, and best of all, without me breaking all of my old work before I revise it to take advantage of this.
You could probably make a widget-and-parameter struct, and by using struct member labels, omit parameters when not needed, but also have the option of then having a list of 'cells' that you can specify things, like a weight value (1=equal) and a stretch-or-truncate option to define when a widget should either change to a smaller form (ellipsise, fade off) or disappear if it has insufficient space and isn't salient. I suppose that this one would suit especially a table layout notion, as one of the parameters could be row/colspan. On one hand you have implicit typed parentheses blocks, with the requirement of a label to omit fields, on the other, you have the option of the (final) parameter of a function being variadic.
I just wanted to let you guys know I have made a bunch of changes/fixes that you might want to move upstream, I will list them in the order I made them:
https://github.com/p9c/gio now contains a fork of gio current up to yesterday, with two main changes:
gogio now has a 'nostrip' option which disables the
-w -sldflags, which might make debugging possible in the apk. I'm not sure if this is useful?
I discovered to my chagrin that my plans of implementing standard X11 select/middle click paste, known as the 'primary' buffer, required me to poke also at the
app/internal/wmdirectory. I am not sure yet if the fix I made should be applied to the other platform button handling, as the X11 handling was definitely wrongly implemented.
When I say wrongly implemented, I found by logging the mouse events that presses get a 'button' value but there is zero in the release. The upshot of this is that the whole pointer click handling cannot be used in its current state to work with anything more than that primary mouse button, you know, that one that some computers only have 'one' of. Where it previously ORs the button code and then NOT-ANDs it, resulting in press with button and unpress with no button, it now ORs both press and release and then resets the value to zero after dispatching the event.
As I am trying desperately hard to avoid doing too much on upstream stuff and work around it, an extended version of the layout/widget/material library can be found at https://github.com/p9c/gel - in there are pretty much all the things, but crammed into one package and using chained methods.
But changes of substance are also in there:
the editor has been updated to include several new features:
triple click selects the entire text (might be better to make that the line but I am not using multilines anytime soon). To do this I had to change the gesture package to properly handle the extra time for 3 clicks with the double click interval limit.
Using the xgb interface from burntsushi the editor when the editor selection changes the selection is copied to the primary buffer, if on X11, and when the middle button is clicked, the content of the primary buffer is pasted and left selected to make it visible if it was misplaced (later I guess to add drag-and-drop, which should move the whole selection around, on desktop, this is incorrect behavior on touch interfaces however.
So there may be some kinks in mobile interfaces and with other platforms - I have just implemented it for X11 and since the dummy getprimary function returns an empty string, and the paste will then be ignored, though it will change the cursor, and perhaps. Ok, so it doesn't cancel if you drag, which probably should be added, or, perhaps instead the caret could appear where it will insert, as the wobbly accidental scroll thing tends to do (which could be at least partially alleviated by disabling scroll while hover and button down). And a big grabber for mobile from long touch, and canceled by typing (deleting selection of course).
There's a few more things to round it out but we were going to run with just giving nice big friendly copy paste clear buttons, the new selection thing is wonderful, and why I have put the energy into this, but for copying and pasting crypto keys and short notes the prior setup was acceptable.
I promise not to mention it again but there is also a set of tools for working with offscreen dimensions calculations by using macro recording then discarding after the dimensions are returned, that I have used to implement a scrollbar that at least when used with relatively short axis-height segments in the
Listis smooth and fast, though initial display does stall the paint for some tens of frames. I can't justify doing it now but I want to generalise the segment iterator to allow any widget to be in a cell aligned baseline, bottom or top, and of course to be able to reverse the order of both axes. I don't know if the cost of either interfaces or functions to enable this efficiently is there, my guess would be interfaces will be faster for the glyphs than making the glyphs into widgets.
I hope this is of some use as I am otherwise doing it for the parallelcoin wallet's GUI anyhow.