Comments (11)
This is a limitation of dyn-view
, and one of the reasons it's not documented yet/why I'm not sure it's a good idea. The problem is that while it can discover what dependencies the generated views have, it has no way to register those deps with the renderer. Probably the easiest fix would be to make dyn-view
add its own observers to dependencies reported by its children, but I'll have to sit down and think that through in case it would cause other problems. In the mean time, using obs-combine
is the right approach here, though you also have to make sure your monster group view uses the ability decks value from the combined observable and not the main one (if you don't, things might work out most of the time, but you're going to be depending on a race between the observables).
from racket-gui-easy.
I just pushed a set of changes to track hidden deps in dyn-view
s and to make it so that if-view
(and derivatives like cond-view
and case-view
) short circuit. This should make it easier to create disjoint views like you're trying to do, though there are some caveats still:
racket-gui-easy/examples/issue-23-short-circuiting.rkt
Lines 70 to 84 in 424ad3b
from racket-gui-easy.
Yes, I think they should generally be avoided. Ultimately, views are objects with internal mutable state so re-using the same view can be problematic.
In that case specifically, if-view
calls destroy
on its children when they get replaced, so the static view would get torn down after its first use and on subsequent uses it would appear empty. This would've been a problem before this set of commits too, but commit bebc226 makes it more apparent since it removes children from containers to avoid retaining them unnecessarily.
from racket-gui-easy.
Thank you for this; unless you feel strongly otherwise, I'm going to close this issue because I was successfully able to update to 0.5 and use a cond-view where I had this dyn-view before. 🎉 ❤️
from racket-gui-easy.
This is a limitation of
dyn-view
, and one of the reasons it's not documented yet/why I'm not sure it's a good idea. The problem is that while it can discover what dependencies the generated views have, it has no way to register those deps with the renderer. Probably the easiest fix would be to makedyn-view
add its own observers to dependencies reported by its children, but I'll have to sit down and think that through in case it would cause other problems.
That makes sense, and is kind of what I figured. It's unfortunate that cond-view
really won't work here without producing errors (though IIRC they don't prevent the application from running).
In the mean time, using
obs-combine
is the right approach here, though you also have to make sure your monster group view uses the ability decks value from the combined observable and not the main one (if you don't, things might work out most of the time, but you're going to be depending on a race between the observables).
That is unexpected, in some way, but also makes sense. Unfortunately the use of the @ability-decks
in make-monster-group-view
needs to be an observable—is your suggestion just to @
-wrap the correct value, then?
At any rate, this might give me the motivation I need to drop some of the cons
objects and put more things in struct
s (there's already a large number floating around, but no harm in adding more).
from racket-gui-easy.
This is wonderful! I haven't updated to try this out yet, but I plan to soon.
I completely follow the coerce
problem in your link, but I'm still trying to digest what's happening in 87580f8 where you say that referring to a static view is a problem: does this mean that static views should be considered something of an anti-pattern (i.e., all views should be returned by functions)?
from racket-gui-easy.
I want to expand on this some more, in case I forget some of these details by the next time I get to work on this stuff.
Initially, when I came up with view<%>
, I imagined view implementations would end up being stateless. That's why create
returns a native widget instance and why update
and destroy
get passed those instances. In those cases, you can pass the same instance of a view<%>
around multiple times and it won't cause any issues because the instances don't have any internal state. By the time I started implementing container views, I stopped worrying about retaining that property, because it made the implementation of those views much simpler. However, that breaks the promise that view<%>
s are purely representations of GUIs, which I'm not too happy about, but, in practice, it doesn't seem to cause many issues (of all the GUIs I've written with gui-easy so far, that example was the only one where I had reused a view like that).
I think for now I'm going to leave things as they are so we can see how much this trips people up. If it turns out to cause a lot of pain and confusion, what we can do is change those views that are stateful to parameterize their state per native widget instance. To give a concrete example, if-view
's then-view
and else-view
would change from being (or/c #f (is-a/c view<%>))
to (weak-hasheq/c any/c (or/c #f view<%>))
. Alternatively, we could wrap native widgets in a mixin that lets us store contextual data directly on those instances, simplifying some of the state & memory management.
from racket-gui-easy.
Ok, that seems to make sense to me at the moment.
One last question: I saw a current-renderer
parameter at a glance; is that considered public/stable? I don't recall seeing an update to the docs mentioning it, but it is certainly something I'm interested in. Though, using (render (dialog …))
without a parent
argument hasn't caused any trouble for me so far…
from racket-gui-easy.
No, it won't be public. I added it for internal use only and mostly as a way of getting around changing the view<%>
interface s.t. create
, update
and destroy
take an additional renderer param. I probably will eventually change the interface and get rid of it.
You can bind the top level window's renderer (or store it in your own param) and use it to make modal dialogs already (see "examples/modal.rkt"). What you can't currently do is bind the renderer for a dialog because rendering a dialog blocks until the dialog is closed. I haven't yet thought of a nice way to get around that.
from racket-gui-easy.
Got it, thanks!
from racket-gui-easy.
Here's an example of making your own parameter, for the record. I couldn't think of a thread-safe/re-entrant way to do it without a parameter containing a thunk:
#lang racket
(require racket/gui/easy)
(define cr (make-parameter (thunk #f)))
(define root
(parameterize ([cr (thunk root)])
(render
(window
(button
"Click me"
(lambda ()
(render
(dialog
(text "hello"))
((cr)))))))))
The view construction could then be placed in its own function(s) as long as it had access to the parameter. Thunk-ing is necessary because without it the value root
is evaluated in the first form of parameterize
before root
is bound to the value that parameterize
would return (i.e., it is undefined)!
from racket-gui-easy.
Related Issues (20)
- How does one program GUIs to handle heterogeneous data, especially with sub-views that contain internal state? HOT 1
- Containers which create internal panels are always stretchable HOT 2
- is there a way to close a dialog programmatically? HOT 5
- Is it possible to detect when the main window closes? HOT 2
- Render popup-menus relative to a child widget? HOT 1
- Documentation for case-view condition doesn't match implementation HOT 1
- Default keymap for (input) should be (keymap:get-editor) HOT 6
- `group` does not accept styles shown in docs HOT 1
- button contract should allow bitmap%, not just label-text% HOT 1
- Error in remove-dependencies while updating conditional view within a list-view HOT 3
- Feature-request: Slightly fancier menus HOT 1
- observable-view: change-children: cannot delete non-window area HOT 2
- Canvas: `ctx: undefined; cannot use field before initialization` HOT 9
- Docs say default hpanel alignment is `'(center top)`, but it isn't
- Clean way to implement a list of checkboxes? HOT 2
- dialog with `close-button` style has no close button HOT 1
- `obs-set!` function
- Duplicate `gui-easy-lib` dependency HOT 4
- Feature request: Checkboxes in menu items HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from racket-gui-easy.