WIMP Programming - Window Furniture
Mike Howard (479) 216 posts |
Just for the halibut (but also as a learning experience) I’m going to recreate a Scrabble like game I did in BASIC back in the day on my A300. It was a single tasking effort. I’m going to use C and the WIMP this time around and as opposed to my original crude dictionary routine I’m implementing a DAWG. WIMP programming is not something I’m experienced in and done in C, it will be 100% new to me. My first thoughts are to use multiple windows for the basic structure, one for the board, upto another four for the required tile racks. Obviously other windows as required but my query is mainly about title bars on the windows for the racks. So, before I play around too much, can I have windows without any furniture at all and still move them around the screen? I assume I could move them programatically in response to mouse events? Alternatively, could I completely replace the title bar with my own sprite which was NOT the full width of the window? The intended result being that it might look like a tab on the top of the rack icon sprite that could be clicked upon to drag. Or, it might appear as though it was part of the sprite that is the rack? I can’t see in WinEd a way to make the title bar transparent which I think would help. I am thinking the rack would be an icon containing my sprite. The rack sprite would have a 3D like appearance and so the top might/would not appear to extend across the whole of it’s window at the top. The window holding the rack icon would have it’s work background set to be transparent giving more to the 3D shape of a rack. Clearly not Style Guide compatible, just my first thoughts but I want the rack to appear as a floating entity. I’ve seen ‘Wimp Programming In C’ online by Steve Fryatt which is great and will be really helpful. Any pointers (no pun intended) appreciated. |
Rick Murray (539) 13840 posts |
Yes. Off the top of my head, get WindowState, fudge the positions, call OpenWindow to make it happen. There isn’t a way to make title bars transparent. And don’t make a mistake here – there is no such thing as transparent. What it actually means is “don’t draw the background”. Best if your rack sprite fits the window. ;) If you want a custom mini title bar, the way to do this might be to disable the regular one, then have a small icon (either as an icon or with a sprite in it) at the top, with which you fake the usual title bar behaviour. But do note that this won’t follow the system theming. |
Rick Murray (539) 13840 posts |
The Wimp is a big pile of system calls taking data arranged in memory blocks. It was originally aimed at assembler programming, which can lead to some rather obscure code in BASIC, and an unholy abuse if structs and unions in C. My advice – use a library. I’d point you towards DeskLib (but then I’m biased). What you are looking for might be capable with the Pane2 part of the library. The benefit of this is that a good library provides a lot of ready built routines. By way of example, the code at the bottom of https://www.stevefryatt.org.uk/risc-os/wimp-prog/mouse-clicks-in-windows is a tad more complex than calling Icon_printf(). ;) That’s not to say it’s wrong. It’s just that the more a library can do for you, the less you have to do for yourself. |
Mike Howard (479) 216 posts |
Hopefully I can master this ‘Textile’ without making a fool of myself….. Er, got there in the end.
Ok.
Thanks for the clarification. I was seeing said oddness whilst tinkering in WinEd.
I’ll look at this. Sytem theming wouldn’t matter in this scenario.
Had thought of this and it might be a nice simple option. Uhm, would ToolTips be easy to implement I wonder? Thank you for taking the time to comment. |
Steve Fryatt (216) 2105 posts |
If Mike’s following my OSLib-based tutorial, that might not be the easiest option…
Er, yes… yes, it is. That’s the whole point. Because your average RISC OS user seems to like to re-invent every wheel going, the aim of the whole tutorial was to explain how things worked at the Wimp level, before building up.
1 See the “Writing to icons” section that the linked code is towards the end of. |
Mike Howard (479) 216 posts |
Yes, a library seems the way to go. I have the ROOL dev environment, can I easily use Desklib with that or would I need to use GCC? Does Desklib have documentation? A pane sounds reasonable. Back in the day I implemented one from BASIC which worked well for what I needed. Maybe it would work now. I’ll look further into Desklib. |
Rick Murray (539) 13840 posts |
The official DeskLib is at https://www.riscos.info/index.php/DeskLib I also have a fork that I’ve been on and off maintaining, but it is based upon an older (v2.30) version, so it has features, just different ones. ;) Mine is at http://heyrick.ddns.net/desklib/ and the proper version is at the above link. Both are 32 bit safe, and I’d recommend you use the proper version. Just mentioning mine as an option and also to show why I’m a little biased here… There are also tutorials at the riscos.info link. |
Rick Murray (539) 13840 posts |
If you would like to look at some real life code that uses DeskLib, the source of my simple ebook viewer is available – https://heyrick.eu/blog/index.php?diary=20200601 It “should” (hopefully!) work with either version of DeskLib. I use my own…obviously. Here is how to embed a pane into a window (down as part of the scroll bar area) as Manga does it, along with browsers, etc etc. https://heyrick.eu/blog/index.php?diary=20171217 |
Rick Murray (539) 13840 posts |
Ah, I see. That, not only makes sense but is also pretty truthful. Only joking, but yeah, that’s how it often is. ;) Wasn’t there a plan to make some sort of IDE and library that would improve things for those sane people that want to code without understanding every bit of under the hood activity? Writing code on RISC OS involves a hell of a lot more work. Libraries such as the aforementioned do good things to automate common things (like call this function if this window is clicked) but there’s still a need to do a lot to get a task going. Many many decades ago I wrote a horrible hack (that I never finished) that reads a Template file and makes a bare skeleton app from it, which helps with the boring grunt work, but still… |
Steve Drain (222) 1620 posts |
Rather like the Toolbox, then. ;-)
I have lost count of the number of those I have started. I have yet to find the ideal one. |
Mike Howard (479) 216 posts |
Yes, I have been following your tutorial and it is extremely good. I tend to gloss over stuff I think I know only to realise a little later that I actually dont’ know, so I’ve reread a couple of areas a more than once. I’m looking at everything I can find at the moment, trying to get back into things. Rick’s point about VB is so true. I created many an app using .Net without the underlying knowledge. I prefer this way though. |
David J. Ruck (33) 1635 posts |
Yes, everything is possible with the standard Wimp calls.
You would have to implement the titlebar as a small pane window, as transparency isn’t possible. In my !Mirror application I implemented an entirely fake title bar on the bottom of the window, so when reflecting above the normal titlebar doesn’t get in the way. I’d be happy to explain how I did it, if I can still understand the code! |
Mike Howard (479) 216 posts |
Ok, understood.
Link is broken.
Now that would be really good of you. Thanks. |
Rick Murray (539) 13840 posts |
The voice of experience right there. 😂
|
Clive Semmens (2335) 3276 posts |
as a small pain window In my experience most windows are more like a great pain. |
David J. Ruck (33) 1635 posts |
Sorry about the broken link, this should work !Mirror |
Steve Fryatt (216) 2105 posts |
I’ve just rebuilt the AOF version of SFLib, which can be found on my website, to contain all of the latest fixes that are on GitHub. It was built with the DDE, and should be fine to use with it. There’s no support for panes in SFLib, as I tend to use the Nested Wimp’s support in projects, but it’s got a lot of standard Wimp functionality in there. What it lacks compared to DeskLib is the additional stuff – things like linked lists spring to mind. As with DeskLib, documentation usually falls into the “you have the source code” category… :-) Compared to DeskLib, the main advantage of SFLib is that it plays nicely with OSLib – which is what gives you all of the SWI veneers. With DeskLib, unless there’s veneers in DeskLib then you’re either writing your own or falling back to It’s worth mentioning again that OSLib isn’t really a library as such: it is just a collection of clean veneers around SWIs, plus collections of structs, enums and #defines for parameters and memory blocks, but adds no functionality on to those. There is OSLibSupport, which does add things like event handling, and probably has a similar relationship to OSLib that SFLib does (ie. it’s a library that uses, and works with, OSLib). As far as pane handling goes, it’s worth noting that this stuff is wrong. Whilst writing it over Christmas, the approach used was optimised into a form that works well with the Nested Wimp but has significant performance issues on older Wimp versions. Since then I’ve not had the time to go back and correct the text and example code, so it remains a bad thing to follow (fixing it is on the to-do list, but then so is a lot of other stuff). |
Mike Howard (479) 216 posts |
No problem, I got the application and I’ve had a look at it. It looks really good, that is, it fakes the title bar seamlessly. Was it written in C? |
Mike Howard (479) 216 posts |
Thanks for the info, I’ve downloaded it. I think, rather than mark time waiting to figure out how best to use panes and such to fake the title bar, I’ll procede using the simpler option of the standard approach in the short term. At least I’ll be getting something done. Hopefully I can get more idea on faking the title bar as I go along. David’s implementation looks brilliant. |
Steve Fryatt (216) 2105 posts |
I’m not sure how Mirror does it, but that looks like something that could be done using the Nested Wimp: nest a window with a title bar and no work area into the main window that has no title bar. Alternatively, if you don’t care about keeping a standard Wimp title bar, use a window with no furniture at all. Add an icon at the side of the window (any side, so this has the advantage that you could have vertical bars on the left or right), make it draggable, and use a Drag Type of 1 (“Drag Window Position”). This works with no panes at all, but won’t let you escape the rectangular window shape. |
David J. Ruck (33) 1635 posts |
!Mirror actually draws a fake titlebar all the time, not just when it is at the bottom of the window, this is because it has a resize button on the right instead of a toggle size one, which isn’t something the WIMP supports. It’s written in C and uses RISC_OSLib (because it was written in 1991). It dynamically creates 4 icons at the top (or bottom of the window), the send to back and close icons on the left and the resize on the right, with the titlebar sized to take up the space between. The size of the titlebar and position of the resize icon being altered any time the window is resized. The redraw handler takes care of plotting the different tool sprites which make up the title bar. It uses its own copy of the tool sprites which match the ones from the default theme on my machine, but may not look the same as if you are using a different theme. I suspect I didn’t change it to use the tool sprites that the Wimp is using, as it was maintaining compatibility with RISC OS 2. I think I can drop that now, so should change it! |
Mike Howard (479) 216 posts |
So, I’ve been plodding along. Sorry if this rambles on. The programming documentation is not very intuitive, almost designed to stop people learning how to do it :) I think I’m struggling to perceive the polling process, a bit like when I first programmed on android! Anyway, SFLib and OSLib have been a great help. I am though banging my head figuring out how to insert a delay loop. At the start of the game, just like the real thing, players draw a tile for the order of play. If there are less than 4 humans, I want a slight delay between the last player drawing/displaying his tile and the computer drawing/displaying it’s tile. The window I’m using for this has, amongst others, four sprite icons for displaying the tiles and four writable text icons for the players’ names. Initially, only the first player’s icons are active, the other six are shaded. I have a Window based ‘mouse click’ event on the window and when the sprite icon is clicked, the event handler is called and a random tile is displayed and the player’s name read in. These two icons are then shaded and the next sprite and text icons are ‘unshaded’ and the handler exits and we await the next player’s click. All works as I expected until I want to insert the delay just before displaying the computer’s tile. I have tried recursing into the function that does the ‘shading/tile getting’ work, immediately after the last human, with a flag set to use a one second delay but what happens is the last players tile does not get displayed until the delay ends and the computers tile displays instantly thereafter. I assume because I’m still in the original mouse click event handler in reality? I’ve tried a wimp user message with a message handler. The result was the same, No display of the players tile until the delay is over and then both tiles at once. The closest I got was NOT using wimp_MASK_NULL in the main wimp_poll loop and using my flag to determine if the work function should be called to get the computer’s tile. This worked except that the delay was arbitary and too long. Not very subtle either. Clearly this is all due to my ignorance but I’m struggling to find any concrete examples of how things like wimp messages and polling actually work and thus why, when I shade the icons and set their state, this is not acted upon before the delay loop. |
Dave Higton (1515) 3526 posts |
You’ve discovered that you need a state machine. It might be quite simple, let’s see… You can set a state “delaying” to be TRUE or FALSE. Normally it would be FALSE, but you read the monotonic timer and add 100 centiseconds to it to give you the end time. Now you can Wimp_Poll with null events returned, and, in each one, check the monotonic timer and see if the end time has been reached or exceeded. Then do what you have to do in terms of redrawing, set the delaying state FALSE, and continue wiith null events not returned. It’s equally valid to have a main state that can take on various values, and act on each value, perhaps with a CASE statement. |
Stuart Painting (5389) 714 posts |
Wimp_PollIdle is your friend. It’s much easier to have the Wimp introduce the delay than having your own application eating up null polls to check whether the desired delay time has expired. So you would change your poll mask to allow null polls, call OS_ReadMonotonicTime and increment with the desired delay, then call Wimp_PollIdle instead of Wimp_Poll. The next null poll you get indicates that the delay has happened. Of course you may get other poll reasons in the interim (e.g. if the user clicks a mouse button) so you may need to call Wimp_PollIdle again. |
Mike Howard (479) 216 posts |
I’ve tried a number of things and those things a number of ways so my rambling above may not be 100% accurate. So, with null events returned and using a flag in the CASE statement of the wimp_poll loop I can get it to work ok. I just didn’t want to return null events for the lifetime of the game.
I’m not sure exactly what you mean here. Are you suggesting multiple wimp_poll loops? |