Get OpenWindow events with AutoOpen flag in toolbox (RISCOS Cloverleaf)
Sergey Lentsov (8268) 63 posts |
Hello, Me need to get OpenWindow events to adjust controls position and size when window resized by user. Is there is normal way to get OpenWindow events and make toolbars working as expected (moving/resizing together with main window)? Right now i try to control toolbar subwindow myself but it required additional code. |
Alan Robertson (52) 420 posts |
As I’ve never programmed using Toolbox windows yet, I have not tried to replicate your issue, but I just thought I’d share what I know from non-toolbox development. It is only the window that is being moved, or resized that produces the ‘Open_Window_Request’ event code. The app should: The Toolbox event logic may be different, but I doubt it. I assume you would need to do the same, so if you are doing it yourself, you are probably doing it the right way. |
Steve Drain (222) 1620 posts |
Could you be a little more specific? Is it the scrollbars? I have found working with the Toolbox can make many things much easier, but it does throw up barriers to detailed Wimp stuff and sometimes a little lateral thinking helps. |
Paolo Fabio Zaino (28) 1882 posts |
Not sure I fully understand this, are you sure you are using the ToolBox? Because, when you set the auto-open flag, you’re using the ToolBox and an Open Window Request event happens then the method called should be Toolbox_ShowObject for that specific window. Anyway, if an object is set to auto-open and auto-close, then it makes sense it doesn’t see the Open Window event, that is handled by the ToolBox for the object. BTW, this is clearly stated in the ToolBox Guide. If you are using “Toolbars”, how did you create them? Did you associated them using ResEd on the main/parent window selecting → Toolbars → Bottom Left “ToolbarName” etc? And then creating a toolbar with that exact name? Basically what the actions I mentioned should do is simply set the toolbars as “Attached Objects”, so Toolbox_ShowObject and Toolbox_ObjectDelete should handle them all at once. They should also move with your main window when you move it IIRC. Also look for: window_set_tool_bars( MyFlags, WindowObjectId, InternalBottomToolBarId, InternalTopToolbarId, ExternalBottomToolbarId, ExternalTopToolBarId) If you need some template and code examples to look at, the original Acorn !Hyper application has a toolbar or two, so you can look at that code. If it doesn’t compile, there is a piece of code in the file c.button that it trying to pass a pointer with the & which is clearly a typo, just remove the & and compile (also to have it working create the following in AcornC/C++: Install.!Hyper) Now, to the specifics of the event propagation if you chose a manual path as you seems you have done: AFAIR, to receive an event you need to (well) ensure you have control, if you decide to have control then you need to ensure you move and resize all connected objects. The ToolBox events are just an abstraction over the WIMP events, so you always get the event on the object that is being used to generate the event. In your case, if you are moving a block of “composed windows”, most likely the window that displays the title bar (which is used to move it) will receive the event and only that window.
Not sure what you mean by normal, you seems to imply “automatic” with normal? If automatic then ensure you have created your window-conglomerate correctly as specified above. If you use the ToolBox you definitely write much less code, because for example, you can “register” a client handle that is a pointer to a data structure that represent the “client-side” state of a ToolBox object (for example the actual Draw file that is being displayed in a window object or the text for a text-editor etc… so if you have shared objects, your client code doesn’t have to do a lot of things to determine which object state is associated with the object and event). One way to “propagate” a received event to parent objects could be: toolbox_raise_event( myflags, ObjectId, ComponentId, EventReceived ) Where the event you transmit is the event received by the window where the event has been triggered, object id is the window you want to send the event to and component id is the id of the parent. But if you need to re-size all connected objects manually, but in a sort of semi-automated way, you can probably use one of the methods I suggest below.
Yup, this is what I do (and what I call “manual path”), maybe there is a way with less coding, but I suspect if there is then there would be also limitations. So, I have never tried to explore such a way. What you would do “normally” is just create some libraries of reusable code for your own applications, so you code less and you still maintain full control. I do not know much about what you are doing, so apologies if below I mention things you have already done/tried, anyway here are few ideas for creating re-usable code on multiple toolbox applications: If you are coding in C++, I would use a Singleton Class to represent the entire structure and ensure that the method .move (for example) reorganise all the “connected” windows (I call them connected, because they are not necessarily a child of the window with the titlebar). Given that it’s a singleton, all events handlers in your main code will access the same instance of the class and can control the exact same windows-conglomerate using a single method call. You can also decide if it’s the case to do a force_redraw or whatever either in your calling code or within the window class implementation. If, instead, your application may have multiple instances of the same multi-windows structure (for example a graphic program that allows editing multiple pictures at the same time or a text editor that can have multiple documents opened at the same time), then I would avoid the singleton pattern and use a Class that works more like a Command Pattern where you determine which window-conglomerate to address on a per event base, using the Window Handler to identify the correct window object in your code through the command pattern (given that a conglomerate of windows may come with different window handlers to your event handler code, but they would refer all to the same structure, which is what you seem to be wanting to achieve). In that case you can propagate the event to the rest of your structure as it’s required by your specific app and window-conglomerate. If you are using C instead, things can get a bit more messy, but you still could use a struct to represent your windows-conglomerate and determine which struct in a “command pattern-like” function where you pass the Window Handler you have received and the function works out which struct it needs to use to update. Hope this helps! :) |
Sergey Lentsov (8268) 63 posts |
Thanks to all for the answers. I want to make Filer-like application with Toolbar at the top and TreeView control at the left. I’m using C++ and TBX library. To set the Toolbar I’m use this code:
The itl_toolbar function code from TBX:
It works and toolbar initially displayed at correct place but with “auto-open” flag I don’t get OpenWindow events and without “auto-open” the toolbar stay at initial place and not moved when main window moved. Seems Toolbox needs OpenWindow event to keep the Toolbar at place but why it eat the event and not forward to the app? Now I make a workaround and placed Toolbar controls and TreeView in the separate subwindows, turned off the “auto-open” flag and do reposition of subwindows manually when size of main window changed. Problem mainly solved. I just wondered why Toolbox so stupid and eat the OpenWindow event.. |
Steve Drain (222) 1620 posts |
There must be a good reason for it, because it is documented on page 5 of the Toolbox manual. ;-) My lateral thinking on this would be to check the Window object Extent every 10cs or so, using PollIdle say, to see if the user has changed it, and rearrange the filer icons if they no longer fit. |