Bound Together Forever
BlitzMax Forums/MaxGUI Module/Bound Together Forever
| ||
Now that I am starting to work on my Carryall 750k interface, I am noticing apparently you cannot bind either global or local variables to any of the gadgets, I.E.:g_slide=CreateSlider(h,v,x,y,zvideo,SLIDER_HORIZONTAL|SLIDER_TRACKBAR)While I can modify this control, I must use this to read its value: slidepos=slidervalue(g_slide)Isn't there a way of building a Gadget and hardwiring a variable to it so I don't have to manually read the value of every gadget I need for later ? I.E.: g_slide=CreateSlider(link(slidepos),h,v,x,y,zvideo,SLIDER_HORIZONTAL_SLIDER_TRACKBAR)What would be a good example in coding this ? |
| ||
Why would you need to? Its like this because the value is kept not by MaxGUI but by the system itself. Windows GUI stuff is a kernel thing, so all state a window can have is kept internally. Meaning you have to call an API function to get any value from it. If its speed related it would actually be slower, since that "link" would have to call the relevant API in addition to the abstraction cost itself. You could build something like that link yourself though, by using function pointers. But i see no value in doing that. It would just be an abstraction on top of another abstraction ;) EDIT: And even then it would still be a function call. Its impossible to make it look like a variable, since that would require language level support for it. EDIT2: And if that link was to be totally generic, it would need some way of figuring out which gadget it was operating on. Leading to the very same "API" as the original. Unless of course you created functions at runtime, JIT style... |
| ||
That's quite a brainweaver there, Grable. Just saying it should be an available option - and was hoping it could be done. :) Actually, it can be done w virtual variables. I didn't see that until you you mentioned, "Its impossible to make it look like a variable." You do remember my function ? addmenu "file,n@new state,o@open state,z@close state,-,s@save as ...,q@exit" addmenu "help,instructions,-,about,author,credits,-,website"Certainly a lot faster than manually typing out for each of them: CreateMenu "New State",menuid+n,gadget[menuid],"N",modifier_command |
| ||
That is still a function call. What you want is to type "something" and have that something not only act like a function but also return a value. Which is something you can only do IF the language supports it. The furthest you could reduce it down to would be something()But that would require you to hardcode each and every function to directly call the API on a global. IE not very generic ;) And for just saving you some typing, i really see no value in doing it in the language proper. I would instead build a parser/compiler and interpreter/virtual machine, then i could decide the rules of how everything works myself. IE what you seem to want is a scripting language. |
| ||
Writing a Game Making programming language is in my list. But I have many other projects to finish first. (1) Carryall 750k Method (this is the one using MaxGUI) (2) Vector Editor & Builder (make your own vector images with arc ability) (3) sample game based on Bill Budge's Bomber game (to demonstrate vectors) (4) Tilemaster 2016 (comprehensive at-the-pixel level editor) (5) Back on course, S3 or - a game programming language. Perhaps both. |
| ||
Not sure if I correctly understood what you wanted to do, but couldn't you just set your variable when the event from the slider occured? Every time the event pops up the variable is set. You can use even a hook instead of the Wait-Event-Queue. SuperStrict Import MaxGui.Drivers Global SliderPos:Int Local Window1:TGadget = CreateWindow("Window1",404,205,335,211,Null,WINDOW_TITLEBAR|WINDOW_RESIZABLE |WINDOW_STATUS |WINDOW_CLIENTCOORDS ) Local SL2:TGadget = CreateSlider(38,28,247,40,Window1,SLIDER_HORIZONTAL | SLIDER_TRACKBAR ) SetSliderRange( SL2,1 ,10 ) SetSliderValue( SL2,1 ) Repeat WaitEvent() Select EventID() Case EVENT_WINDOWCLOSE Select EventSource() Case Window1 Window1_WC( Window1 ) End Select Case EVENT_GADGETACTION Select EventSource() Case SL2 SL2_GA( SL2 , EventData() ) End Select End Select Forever Function Window1_WC( Window:TGadget ) DebugLog "Window Window1 wants to be closed" End End Function Function SL2_GA( Slider:TGadget , Number:Int ) 'Slider Range was initially set to: 1 as Start and: 10 as End Value DebugLog "Slider SL2 changed to " + Number SliderPos=SliderValue( Slider ) End Function |
| ||
I think dw817 would like to 'transmit' the value to other gadgets, automatically (sort of). Imagine to have a slider: when you move the knob, a label_text is changed accordingly AND a (for example) a ListBox() is moving its content to show a specific 'range' of value (don't know if this is possible!). It's sure you can do this like in the example posted by jsp (just put a SetGadgetText(label,SliderPos) and other in the SL2_GA() function. An 'automatic' solution - like SetGadgetLink(my_slider,this_label) (and you can add more item to the 'queue' to receivers) is 'good to see' I've done something similar for one of my GUI (just graphics, in game). I've tried to do something in the past, the idea was to implement in MaxGUI, but then I gave up (no time!), mainly because many gadgets have not 'exposed' their inner value (ie: progressBar position, you need to find where is stored the current value, same for ListBox() etc) This was my experiment |
| ||
Hi Degac. I tried your program. I'm not really understanding the source-code, but you are correct, I want to have a value I can read or set. Just by changing a variable it immediately appears as an effect in the gadgets - or I can read the variable solely to retrieve the status and position of the gadget. I have also already written code to this effect and am continuing on. Thanks for your submit. |
| ||
It looks to be an Event Multiplexer of sorts. Getting a single event from a Source gadget and "sending" it to other gadgets by updating them with the state from the event. Not exactly what your looking for if my understanding of your post is correct, but interesting nonetheless. |
| ||
Building on the concepts of degacs post, heres something using variables as intermediaries. Its not automatic though. One has to register and link gadgets with variables explicitly, and periodically call a Sync() method to update gadgets->variables or variables->gadgets depending on the current event. But i think its pretty close to your original requirement ;) EDIT: Fixed some bugs and added some more abstractions. |
| ||
@Grable Wow... just read your code... vodoo magic in some places :D (pointer & co) Finding the progressbar value seems so easy now! :) Thanks a lot, something interesting to explore! |
| ||
An abstraction that helped me a lot when working on a personal software was "properties", which would be something like a "smart variable" or a class that wraps a variable. You can have Bool properties, Int properties, String properties etc. These properties belong to the document that the user is editing, like a "scene" for example. The GUI of your application serves two purposes: to represent the state of properties visually to the user and to allow the user to manipulate these properties. In the case of an integer value, a slider type of gadget can be used for that. In the case of a boolean value, a check box is used for that. When the user toggles the check box, internally that boolean property is being modified. When a property changes, you may want to run some specific code to do something. You subscribe an object and a function from that object to the property. If I'm not mistaken this association takes the form of a "delegate", an object that can invoke that function. When the property changes, it invokes each delegate that was assigned to it (with each delegate representing functions that want to be run when the property changes), so the functions 'run' and do what they're meant to. EDIT: Added a 'BaseProperty' type with essential functionality that all properties should have (the subscriber list and notification), and all properties 'extend' this base property type. There's plenty that can be improved in that code since it's just an example, it's not a final product. The benefit of this abstraction is that it's got your back when your program becomes complex. You can assign the same property to several gadgets, like for example, having different colour pickers that all change the same R, G and B byte-value properties. BlitzMax doesn't have many language features to help with this, we need to use static functions. You can do more elegant (and efficient) solutions with C++ by using templates (i.e like this). Further reading: - https://en.wikipedia.org/wiki/Model–view–controller (and its variations) - https://en.wikipedia.org/wiki/Delegate_(CLI) |