Computer Science Canada Custom Buttons |
Author: | Clayton [ Sat Dec 09, 2006 10:40 am ] | ||
Post subject: | Custom Buttons | ||
I was asked by a friend the other day why he couldn't pass procedures with parameters when he created a button in Turing. I told him quite plainly that Turing's built in GUI sucked. So he asked me how to get around it. I told him to make one himself, he claimed he didn't know how, so I did. Heres the source with an example program:
a couple of procedures you should know about when using this: Create (x, y : int, text : string) Creates a button at (x,y) with text inside of it. The button will automatically become the width and height required for the text. CreateFull (x, y, width, height : int, text : string) Like Create, except you specify its width and height. Pressed : boolean Pressed simply returns true if the button has been pressed (ie the mouse button was released over it) Refresh Simply redraws the button on the screen again EnableRollover (choice : boolean, Color : int) Enables a rollover effect on the button (true for it to happen, false for it not to). With rollover enabled, the button will change color to Color when the mouse is over the button Have fun with it, just remember to give credit to me if you use it. NOTE: I will be making this a module later on so that more people will be able to use it. EDIT: Any additions you would like to see are welcome! I'm always open to suggestions |
Author: | Cervantes [ Sat Dec 09, 2006 11:02 am ] |
Post subject: | Re: Custom Buttons |
Freakman wrote: I was asked by a friend the other day why he couldn't pass procedures with parameters when he created a button in Turing. I told him quite plainly that Turing's built in GUI sucked.
I'd just like to point out that there is a reason this can't be done. It's because each button is an object, and one of it's instance variables is an action procedure. That is, a procedure with no parameters. Turing is a typed language, and a procedure with one parameter has a different type than a procedure with no parameters. In the class for the button, the instance variable must be given a type. It's got to be either a procedure with no parameters, or a procedure with one parameter, or.... Thus, all buttons have to be consistant with each other. The best way to do this is to make all buttons use action procedures. This wouldn't be much of a problem if Turing had support for anonymous functions. |
Author: | Clayton [ Sat Dec 09, 2006 11:04 am ] |
Post subject: | |
Aye, I know that. I was just explaining that too him (also didn't want to drone on with my post [Which I think I did anyway]). Any other suggestions though Cervantes? |
Author: | Cervantes [ Sat Dec 09, 2006 11:14 am ] |
Post subject: | |
You've handled the buttons' actions the same way I did. I'm actually not so sure that's the best way to do it, anymore. It means having a really big main loop, because you've got to do all those if statements yourself. Can you find a way to make both approaches possible? I'd also suggest giving the buttons some visual charactersitc that shows when they are pressed down. The button should look different when the mouse is pressing it than when the mouse is merely hovering over it. In your Create procedure, you assigned a value to `height'. Why not assign that variable outside that procedure, right when you declare the variable? The code inside a class is run each time an object is created, and `self' is that object, so doing it this way would give you the same effect. It's not necessarily better, though. Just something to consider. Here's something else to consider. Your code checks the state of the mouse each time the Pressed function is called. You'll be checking the state of the mouse once for each button you've got. That's not really necessary. We should only have to check the state of the mouse at most once each time through the loop. So, one possibility is to use a global variable for the state of the mouse, but we all hate global variables. Another possibility is to pass the state of the mouse into the Pressed function as a parameter. This could also give you the power to sort of fudge the position of the mouse if you wanted to, by passing in bogus values. To show off the fact that your buttons don't act like the action-procedure slaves that Turing's GUI's buttons are, why don't you make a procedure that takes in a colour as a parameter and does your little "draw the screen that colour, View.Update, then delay(1000)"? |
Author: | Clayton [ Sat Dec 09, 2006 11:28 am ] | ||
Post subject: | |||
Thanks for the suggestions Cervantes, I'll be sure to try and get those points worked into there somehow. For now though, I have decided to get everything moved into a module (the class still exists, but the programmer doesn't deal directly with it). The modules' name has become Buttons for simplicity. the class name is now buttons instead. The code: (with the procedure Cervantes mentioned above)
Because the class is now being handled through a module, I had to find a way to get my procedures and functions to act upon seperate buttons (as opposed to all of them). So now Create and CreateFull are functions returning ints. This is your button id. The procedures breakdown like this: Create (x, y : int, text : string) : int Same as before, it just returns the buttons new id. CreateFull (x, y, width, height : int, text : string) : int Again, only thing that is different is that it returns a button id. Refresh (button_id : int) You now have to pass it the button id that you want it to refresh. EnableRollover (button_id : int, choice : boolean, clr : int) Just like the above, except you have to pass it the button id that you want to have the rollover. Pressed (button_id : int) : boolean Just pass it the button id now. Any other suggestions, just say them. |
Author: | Hackmaster [ Sat Dec 09, 2006 3:56 pm ] |
Post subject: | |
I would just like to point out that there is another way around the first stated problem, altough it's ugly, and quite frankly, your way is much better. but, for people who are new, and don't know about objects, a very, very verboten way to do this is simply to use global variables in your procedure. (shudder) it counts as an action proc now, because it dosen't take parameters... but all other coders will hate you. just putting that out there. |
Author: | joedirt [ Sun Dec 17, 2006 7:19 pm ] |
Post subject: | |
hey freakman, I'm a fairly new to turing a i was woundering if you could explain or make a code for a simple custon button. One where all you do is click and there is no rollover of whatever, just as simple as you can. -thanks |
Author: | Clayton [ Sun Dec 17, 2006 7:30 pm ] | ||
Post subject: | |||
Read my above posts and it well tell you all you need to know to understand. |
Author: | joedirt [ Sun Dec 17, 2006 8:03 pm ] |
Post subject: | |
i got this far but i still can't figure out how to make a if statment which only works when the mouse is over a button and the mouse is clicked at the same time. in this code i'll click away from the button then move my mouse over it and it still works. Please help. var x, y, button : int procedure redbox Draw.FillBox (10, 10, 50, 50, red) end redbox procedure box Draw.FillBox (10, 10, 50, 50, black) end box loop Mouse.Where (x, y, button) box var x1, y1 : int if x < 50 and y < 50 and Mouse.ButtonMoved ("down") then redbox delay (1000) end if end loop |
Author: | ericfourfour [ Sun Dec 17, 2006 11:28 pm ] |
Post subject: | |
I have two ideas to handle the actions. The first one is to use an action class. The second is to inherit the button object and use it. |