-
-
Notifications
You must be signed in to change notification settings - Fork 77
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
Layout combinators to simplify GUI layout #24
Comments
Grid, row, and column make sense to me. In fact, the GUI I am working on (see below) uses a CSS grid with sizing and positioning tweaked using the CSS. It was indeed a pain but the CSS approach thankfully has tons of resources available online and is pretty complete, if messy. I am concerned that using these combinators will clash with the CSS itself, and the "philosophy" of HTML pages in that style/layout is defined in the CSS and content in the HTML. Adding the combinators as a quick-and-dirty alternative (but not replacement) to CSS sounds good to me. I do prefer the Ji style to the wxhaskell you provided. I don't have a problem with the I have posted a short blog entry on the current status of my GUI here. This program is a game utility for the game Torchlight 2, which is a hack-n-slash action game. The game has a limited inventory space, and my goal with this program is to enable users to extract item data from the game's save files, store it separately, search it, and when desired import it back in. The Haskell source for the GUI is here. On the root level of the project is a GUI directory that has the starting HTML file as well as the CSS file. Almost all the elements are created dynamically with What I want to do next GUI wise is add a search box and a list of database results in the bottom half that is currently empty. I want users to be able to select and drag one of these search results into the grid at the top, which would have the effect of injecting the item into the game's save file. I need to learn and implement some database Haskell stuff before then as well as implement/test writing to the game's save files. |
Wow, thanks a lot Daniel, this is exactly the kind of "beyond my imagination" GUI example that I was looking for. 😃 I would like to study it further. Since I don't have Torchlight2 installed, could you post a transcript of the final HTML rendering somewhere, for instance as a gist? The background and icons obviously don't match the traditional system UI styles, but I definitely want to treat the "non-traditional" style on an equal footing. In wxHaskell, they would have required drawing primitives (hence issue #22), but it appears that regular HTML elements -- or maybe SVG elements -- can substitute for these nicely. I will need some time to mull about a good design for combinators that offer quick-and-dirty layout but can also accommodate custom CSS styling with minimal code changes. The philosophy that HTML is completely free of style specifications is a bit of a lie (elements in sequence are laid out in sequentially, nested elements inherit styles), but hopefully I will come up with something satisfying. In any case, I would like to replace the tedious incantations of |
Here it is. I added a small clickable div to enable saving, which I'm working on now. Also I had to manually fix some tags (mostly all img tags) to get the formatter to work. |
Thanks, will take a look! |
…ayout combinators. This way, it is possible to style the layout differently after the fact. #24
Ok, so I implemented the combinators Essentially, these combinators just wrap everything in a couple of I also started to overhaul the mechanism for setting properties and the I would like to synchronize
Also, I would like to borrow an idea from wxHaskell where properties like
(The What do you think? |
I am liking the way this is going. What I'd like to do this weekend is pull in the latest updates and try to migrate my current GUI layout as a test case. Actually, I might wait until these set/get updates are made as that seems like a larger departure from the old framework, and thus more worthy of investigation. These ideas look good to me on paper so I'd like my opinion to be informed by some experience. |
Ok! I would also like to combine the My motivation for a module reorganization is twofold:
|
@HeinrichApfelmus , is the big update you want to do complete? Let me know when you think it's ready for me to try out, please. Thanks. |
@daniel-r-austin Oops, sorry, yes. The gist of it is ready by now. There are probably still a few combinators to be added as I convert the other examples, but it's ready to be tried out. |
Ok, I have now converted all the examples and as of commit 5c9b6b0, the introduction of get/set combinators and the module reorganization are "officially" done and ready to be tried out. Converting the examples was very instructive for me. Here my experience with the "new" style. Like:
Neutral:
Dislike:
I will now try to rethink the design and fix the dislikes. Since the browser does DOM manipulation with destructive updates, the distinction between It's probably a good idea if I make a new branch for that and don't push everything onto master. |
I started to do my transition yesterday (very casually though). It's good to see that we have similar impressions. Here are mine so far:
This was a big redesign, and I really like the consistency improvements that were made. The nits I have are mostly related to convenience of style. |
Nice!
|
Ok, I made a new branch html-combinators where we can experiment with creating The Chat.hs example contains a very first attempt, I'm actually quite pleased. Apparently, the |
I'll try to test this guy out this weekend. I'm trying to track down a nasty bug that has otherwise eluded me. |
…askell. Clean up read-only and write-only attributes to be more type safe. #24 http://hackage.haskell.org/packages/archive/glib/0.12.4/doc/html/System-Glib-Attributes.html
…tributes to be used with (#). Return to (#.) for setting classes. Change (#+) to accept a list of children instead. #24 Clean up some leftovers from the 'Property' -> 'Attr' rename.
I tried to copy existing HTML combinator library designs, but that didn't work too well because it would have mean to duplicate the attribute/property system to get a nice syntax for setting element attributes on creation. In the end, I reverted the whole thing to the "chained applications of I renamed the |
I'm just getting around to looking at the last two updates. I haven't tried them out on my own yet, but looking over the Chat.hs, I do like keeping the Doing appending with a list of children elements looks great. At first I was skeptical because I didn't like the idea of needing to wrap single children in As for the |
Great! I have now converted the Buttons example and I'm pleased with the results. The only two things that I still find ugly are
Hopefully I'll figure something out there as well. |
Nice!
It is actually possible to get rid of the |
OK, well that's what I get for pulling an example out of my ass. I guess it's just better to illustrate with code. Forgive the indentation errors due to copy/paste.
This was the result of my "naive" translation of the If you want to see more of the code, you can check out my FNIStash repo in the TPG-update branch. My GUI stuff is in src/FNIStash/UI (just pushed). |
Here's how I would write your example. Since the code is mainly concerned with building elements, I would put it in the Note that in general, it is a good idea to populate children at the time when the element is defined/created. This mirrors the functional style where you, say, define a list by declaring the elements it contains, rather than creating an empty list and updating it to add elements imperatively. This is the essential stylistic change made possible with the new
I'm inconclusive about what this code tells us about the distinction between It is clearly less noisy to remove |
Thanks for taking me to school. That code is much improved. I only had to put an additional
As for the interleaving of element creation and interaction, I'm not sure how to do it otherwise but am open to suggestions. The way it is set up now is to process messages from the backend . When the frontend gets a new message, the GUI is updated. Definitely imperative-ish. In So let's say I make the processing of |
Ah, concerning the element creation, I think that some imperative style cannot be avoided. In particular, the But now I understand how your function works in the first place: apparently, you are reading the channel into a lazy list and the
and use
whereas a "more pure" implementation would be
Concerning the However, I think that there is a cheap and mostly working implementation that can eliminate the |
Thanks for the tips! I'll try them out when I get a chance. The |
Concerning the weird bug you're encountering, I just noticed that my implementation of the Namely, I had assumed that each DOM element in the client window is referenced by a unique element ID In particular, if you create an I will try to fix this as soon as possible. |
Ok, I think I have the fixed the issue, so that |
…wser window in advance. Implementation of 'getValue' still missing. #24
Alright! I have implemented and pushed a cheap and mostly working solution to remove the Internally, an One consequence of this approach is that some operations like |
Unfortunately, the bijection fix does not seem to fix my issue. I can work around it for now (ie settle for some acceptable but not ideal behavior). Going into it with more specificity might be worth a new issue as it seems a bit beyond the scope of the architecture redesigns here. I must have cloned the repo just before you submitted the new |
Hope you had relaxing holidays, or are still having them, as the case may be. ⛺ 😄 I'm eager to make a first release, so if you have time to check out the |
Thanks for the reminder. I'll start the effort ASAP. |
I haven't made a lot of progress yet, but working on it so far has been pretty smooth. I have run into an issue though, which I hope is easy to resolve. With this candidate release, how does one get an instance to Specifically, I have an element (call it "icon") that, when moused over, appends a new element to its window's body. Essentially it works like an info popup (there is a picture on my blog). The event handler is defined deep down with the icon definition itself, which is pretty far removed from the "top level" where the |
Indeed, you would have to pass a However, I could change the
Sometimes, this function will return a window corresponding to limbo. Trying to do anything interesting like Actually, I think this is probably a good idea, even if some functions will throw exceptions. After all, the API makes it look as if |
So Unrelated, but there are old |
Ok, I took the easy way out and implemented the type signature The trick with building instructions works for things that do not return results, but functions like
Oh, which ones? It seemed to me that they are all used by the |
Ah, duplicate names, but both used. Never mind about that then. I did a transition to this release (twice, actually, due to a git snafu). I can compile but am experience some weird behavior I have not yet been able to explain. Most of it is related to events - either callbacks not being fired or elements not being found. Still trying to diagnose these problems but they are taking a while. |
Ok, that doesn't sound too good. Chances are that I have introduced bugs in the code, and I suspect they have to do with the assignment of unique IDs to elements. Is it possible to boil it down to a minimal example? Alternatively, could you make a mockup variant of FNIStash that runs on OS X and does not require an existing installation of Torchlight 2? That way, I could try to take a look as well! Maybe a couple of dummy icons and dummy item descriptions will do. |
I haven't tested whether the events work on the examples. That would be my first step toward a minimal example. Making a OS X mockup would be a lot harder. |
Unfortunately, I have not been able to reproduce the issue so far. Here are some other, unrelated comments in the mean time.
I'll give a good effort to resolve the still lingering event issues, but at some point I'll need to concede defeat. |
Thanks! Don't worry if you can't track down the remaining issue. Right now, I think it's more important to release whatever we have in order to let a larger audience play with it. The version numbering starts at Concering the other points:
|
Ok, sounds good! Onward we go. On Thu, Jul 18, 2013 at 12:45 PM, Heinrich Apfelmus <
|
Any luck with the event issue? If not, then let's release what we have! |
No such luck. I went back to focusing on FNIStash dev instead of testing TPG. Let's do the release and get it into new hands to see what holds up. |
Awesome, and thanks again for your help! It is alive, err, I mean, uploaded to hackage. |
I would like to simplify the API for GUI layout.
Since our focus is on GUIs, I wonder if we should downplay the full HTML capability and instead provide a few combinators for aligning GUI elements. WxHaskell has a layout combinators like
grid
,row
andcolumn
that make it very easy to align elements. For instance, the following screen layoutwas created by the following code
Even though the layout is fairly complex, it can be specified in just 18 lines of Haskell code, half of which are essentially just a list of widgets.
The thing is that HTML allows very rich and aesthetically appealing user interfaces, but the design tends to take a lot of time (also because HTML+CSS has an impoverished box model compared to, say, TeX). When writing a GUI application, I wager that programmers probably to prototype the functionality first and upgrade the design later. Hence, a couple combinators for quickly creating layouts might come in very handy.
What is your opinion of the combinators
grid
,row
,column
?Concerning style, WxHaskell specifies attributes as
but I don't think that this is worth copying. I prefer the elegant Ji style that uses chains of
#
in a clever way.However, I would like to reduce the number of variants of
#
,#+
,#=
and so on, and streamline this part of the API as well. Unfortunately, there are many possibilities for doing so, and I have a hard time making decisions without guidance from example GUI code.@daniel-r-austin, I would would be very interested in a screenshot of the GUI program you mentioned. Also, did you create elements mostly with the Haskell code (
new
and so on), or did you specify the layout by writing a HTML page first? What about GUI elements that are created dynamically, like elements of, say, a shopping cart?The text was updated successfully, but these errors were encountered: