Is this a bug?
BlitzPlus Forums/BlitzPlus Beginners Area/Is this a bug?
| ||
I created a G.U.I test to see how buttons and such could assist me in a program, and when I used my code based on Mak's simple_button program I was surprised to find that my code that was nearly identical to Maks' despite some lack of white space, did not work. Here's Mak's code and my code. Maks: ;create main window window=CreateWindow( "Main window",0,0,400,300 ) ;create a centred button button=CreateButton( "Click Me",ClientWidth(window)/2-32,ClientHeight(window)/2-12,64,24,window ) ;wait for an event... While WaitEvent()<>$803 ;was it a gadget action event? If EventID()=$401 ;yes! was it from the button? If EventSource()=button ;Yep! Notify "Right on!" EndIf EndIf Wend End My code: Function Start() While Not Apocalypse() If WaitEvent()=$401 If EventSource()=button Then Notify("Hope it worked!") Else If SelectedGadgetItem("TIME") Notify("TIME") EndIf EndIf EndIf Wend End End Function This is just a test. I'm clueless, I've seriously tried just about anything a begginer could think of-Global, different loops etc. |
| ||
Um, well, for starters, it doesn't look like you've got your whole code in there. The function Apocalypse() isn't shown anywhere. Also, you don't seem to have created a window OR a button, and it's no good checking for events from gadgets that don't exist. If there's any more to your code, post it. If not, then the nonexistent gadgets and function are DEFINITELY going to be at least part of the problem. |
| ||
..and use TAB to indent.. [TAB], not a random amount of [spaces], TAB TAB TAB TAB TAB. And do indent the correct way, indent the scope of a command, not the command or close-command itself. You might want to set the TAB amount to 4 characters btw.. |
| ||
I know it's not nice when people seem to be being pedantic, but I really have to agree with CS_TBL. It makes it so hard for me to understand what you're doing when you indent randomly both in terms of the size and where you indent. There is a ton of code around so if you're not sure of the generally accepted "rules" of indentation, it shouldn't be hard to find them and pick them up, and it really will make times like this when you need help, that much easier. |
| ||
Alright, when you've both finished, may I remind you that in the forums, the TAB key won't make an indent; if you are typing in your response, pressing TAB will simply highlight the "Create Topic" button below the text area. The code would have to be indented ahead of time, and I believe that Siopses' code was typed directly into the forum. It is also possible that there was a formatting error on his computer; strangely enough, computers do still make mistakes. Also, if there was a large quantity of code to be viewed, I would agree that proper indentation makes a world of difference, but in this case, it's easy enough to read even without tabs indents. |
| ||
Duh, don't write code on the forum then.. :P And even when I do code on the forum sometimes I make sure to manually indent it correctly with spaces then, it's just a matter of code-netiquette towards others, I think. |
| ||
Also, if there was a large quantity of code to be viewed, I would agree that proper indentation makes a world of difference, but in this case, it's easy enough to read even without tabs indents. Well I hope your answer was the one he needed then, because I really can't follow it. Granted, I'm not the best reader of other people's code, but there you are. |
| ||
First of all, I copied the code off of Blitz Plus and posted it on the forum, if you want it all here it is; also ADAM my computer may be a Compaq but its relativly new so I don't know about any formatting conflicts... Anyway heres ALL my code. Main=CreateWindow("MAIN",300,200,400,500,main,15) button=CreateButton("Enter",200,100,100,100,main,1) list=CreateListBox(100,200,200,50,main) texto=CreateTextArea(50,90,100,20,main) CreateLabel("Hello"+TextAreaText(texto)+", great day aye?",200,20,100,20,main) hi=CreateLabel("Whats your name?",50,50,100,20,main) AddGadgetItem List,"TIME" AddGadgetItem List,"PLACE" SeedRnd Milliseconds ;Functions Function Apocalypse() Repeat Until WaitEvent()=$803 Notify("Its the Apocalypse!") Delay 500 End End Function Function Start() While Not Apocalypse() If WaitEvent()=$401 If EventSource()=button Then Notify("Hope it worked!") Else If SelectedGadgetItem("TIME") Notify("TIME") EndIf EndIf EndIf Wend End End Function Function ReturnName(Name) While Not Apocalypse() If EventID()=$401 If EventSource()=button TextAreaText(texto) EndIf EndIf Wend End Function Apocalypse() Start() ReturnName(Name) End |
| ||
So, if this comes straight from your Blitz IDE, then your indenting is all wrong. You really need to work on that, prior to further code. It's like studying piano, first learn to sit up straight and keep your arms/wrist straight, after that: go on with the rest. Sound boring, but this indenting prevents tons o' bugs later, when your sources get bigger. (and that's something for YOUR convenience also, naturally we (ppl who intend to help you) also want to read it in a nicely formatted way) |
| ||
Well here's one problem for starters, Siopses: because of the way you coded Apocalypse(), your program will never actually reach Start(). The first thing in Apocalypse() is an empty Repeat...Until loop, that runs until an $803 event (that's the window being closed, right?) So basically, your program can't do anything until the window is closed. Then, when it does get closed, it displays the message, waits for half a second, and ends the program. See what I mean? Your program will never get out of Apocalypse(). Try replacing your Apocalyptic code with this: Function Apocalypse() If WaitEvent() = $803 Notify "It's REALLY the apocalypse!" Delay 500 End EndIf End FunctionThis code ends your program only IF the window is closed. Okay, that's one thing. Now, your other problem is in ReturnName(name). Small, but an error nevertheless. After checking to see if your button was pushed, you have the command TextAreaText(texto), but you don't use it. I think you probably intended to type: Notify(TextAreaText(texto))That's about all I can figure out, and no, lack of indenting did NOT make it more difficult for me; your code is easy enough to understand. In the future though, "proper" indenting can make your code easier for YOU to review, especially as your programs become larger. So, hope that helps, and best of luck to you, Siopses. Happy coding! |
| ||
What do you guys mean when you say 'proper indenting'?, and also this still won't explain the button problem. ADAM: So if I make a loop for a function to end the program like Apocalypse() then it will be stuck in the loop untill the program ends, therfore putting all other functions to a halt? ;Event List KEY_DOWN=$101 ;A key was pressed down-needs the keys scancode for EventData(). KEY_UP=$102 ;A key has been released on the keyboard-needs the keys scancode for EventData(). KEY_USED=$103 ;A key has been typed-needs keys ascii value. MOUSE_BUTTON_DOWN=$201 ;self explanatory, needs one of the following values(1=left,2=middle,3=right). MOUSE_OVER_CANVAS=$203 ;self explanatory, you need to use EventX() and EventY() along with the canvas handle. GADGET_USED=$401 ;self explanatory, you need to be specific to what kind of gadget it is, and what the gadgets handle is as well. MENU_SELECTED=$1001 ;something has been selected from a menu, needs the menu identifier X_HIT=$803 ;The X was hit APPLICATION_HALTED=$2001 ;Self explanatory, means that the program was suspended APPLICATION_RESUMED=$2002 ;Self explanatory, means that the program was resumed Main=CreateWindow("MAIN",300,200,400,500,main,15) button=CreateButton("Enter",200,100,100,100,main,1) texto=CreateTextArea(50,90,100,20,main) CreateLabel("Hello"+TextAreaText(texto)+", great day aye?",200,20,100,20,main) hi=CreateLabel("Whats your name?",50,50,100,20,main) SeedRnd Milliseconds ;Functions Function GuiJuggler(CURRENT_EVENT) CURRENT_EVENT=WaitEvent() If CURRENT_EVENT=$803 Then Notify("Bye bye, until next time") Delay 1000 End Else If CURRENT_EVENT=$2001 Then Notify("If your tired of this program just hit X") Else If CURRENT_EVENT=$2002 Then Notify("Oh good your back!") EndIf EndIf EndIf End Function Function ReturnName(Name) While Not GuiJuggler($803) If EventID()=$401 If EventSource()=button TextAreaText(texto) EndIf EndIf Wend End Function GuiJuggler(CURRENT_EVENT) ReturnName(Name) End I created the function GuiJuggler() instead of Apocalypse; works great, is much more useful then Apocalypse. |
| ||
do you know what a scope is? |
| ||
Yes I do, actually I think I understand scopes pretty well- for a begginer. So when you indent you make sure the scope's connect, in a matter of speaking? Like this? Function GuiJuggler(CURRENT_EVENT) CURRENT_EVENT=WaitEvent() If CURRENT_EVENT=$803 Then Notify("Bye bye, until next time") Delay 1000 End Else If CURRENT_EVENT=$2001 Then Notify("If your tired of this program just hit X") Else If CURRENT_EVENT=$2002 Then Notify("Oh good your back!") Else If CURRENT_EVENT=$401 If EventSource()=button Then Notify("It worked!") EndIf EndIf EndIf EndIf EndIf End Function |
| ||
but then the other way around.Function f00() While 1 If a Select b Case 0 For x=0 to 9 For y=0 to 9 If z=0 Notify "0" If k=0 If l=4 If m$="?" Debuglog "w00!" Endif Endif EndIf Else Notify "not 0" Endif Next Next Case 1 Notify "mmm.." Case 2 Notify "crickey!" EndSelect Endif Wend End Function Each time you start a scope-creating command, like For, If, Function, While, Select, etc. you indent its scope by exactly one [TAB] (I suggest 4 chars for a Tab). No matter whether they are the same commands on a row, so if you have 4 If's after each other, then you indent each If individually. |
| ||
Thank you for the help, but do you know why CreateButton() is'nt working on my Blitz Plus application? |
| ||
Tip for the future, Siopses: when looking for help in the forums, always give some details along with a problem instead of just saying it isn't working. Does the program run, or do you get a runtime error message (REM)? If you get a REM, what does it say? In your GUI_Juggler(CURRENT_EVENT) function, the (CURRENT_EVENT) variable isn't necessary in your function declaration. In other words, you don't need GUI_Juggler(CURRENT_EVENT), just GUI_Juggler(). Then in your ReturnName(Name) function, you have the code: While Not GUI_Juggler($803)The $803 in the parentheses is needless. See, when you call GUI_Juggler(CURRENT_EVENT) like that, you pass the event $803 to the CURRENT_EVENT variable, but then, in the first line of code in GUI_Juggler(), you have the code: CURRENT_EVENT = WaitEvent()which renders the $803 obsolete. All you need is to have the function GUI_Juggler() with nothing in the parentheses, and the same thing in yuor ReturnName(Name) loop. Does that make any sense? BTW, glad I could help on your code problem. |
| ||
No not really, because my GuiJuggler() function needs the CURRENT_EVENT because If I took it out then whenever GuiJuggler() had to do something then the loop would break. The CURRENT_EVENT=WaitEvent() so basically put, when I say While Not GuiJuggler($803) it says that while CURRENT_ EVENT is not equal to $803 then continue. See what I mean? |
| ||
What can I do with a bugged version of Blitz Plus? How can I not use buttons for GUI? I know I can't, you don't get a warranty or anything. |
| ||
Blitzplus is perfectly capable of creating buttons, you just need to learn how to use it. It will take some time to get used to programming if you have little experience with it. Have a look at the samples and play around with modifying little components - plenty of them use buttons. |
| ||
That's what I've been doing for the last few weeks, and when I make a button and attempt to use it nothing happens. Please do keep in mind that this is based on Maks' simple_button example. |
| ||
rule: a function only knows: - its own variables (declared in the function) - given function-arguements .. Function(likethis, andthis, andthistoo) - globals Your button is not global, nor was it a function arguement, nor did you declare it inside the function. Didn't test, but it's something I noticed.. but in all cases: do indent your code the proper way! Otherwise I can't be bothered to read+help. And remember: indented sourcecode has > style scopes. (the deeper a scope, the more tabs you give) |
| ||
Thank you, I tested it and you were right. I'm going to write those rules down. Thanks, Siopses |
| ||
;----------------------------------------------------------- ;Event List ;----------------------------------------------------------- KEY_DOWN=$101 ;A key was pressed down-needs the keys scancode for EventData(). KEY_UP=$102 ;A key has been released on the keyboard-needs the keys scancode for EventData(). KEY_USED=$103 ;A key has been typed-needs keys ascii value. ; -------- MOUSE_BUTTON_DOWN=$201 ;self explanatory, needs one of the following values(1=left,2=middle,3=right). MOUSE_OVER_CANVAS=$203 ;self explanatory, you need to use EventX() and EventY() along with the canvas handle. ; -------- GADGET_USED=$401 ;self explanatory, you need to be specific to what kind of gadget it is, and what the gadgets handle is as well. ; -------- MENU_SELECTED=$1001 ;something has been selected from a menu, needs the menu identifier ; -------- X_HIT=$803 ;The X was hit ; -------- APPLICATION_HALTED=$2001 ;Self explanatory, means that the program was suspended APPLICATION_RESUMED=$2002 ;Self explanatory, means that the program was resumed ;----------------------------------------------------------- Main = CreateWindow("MAIN",300,200,400,500,main,15) button = CreateButton("Enter",200,100,100,100,main,1) texto = CreateTextArea(50,90,100,20,main) CreateLabel("Hello"+TextAreaText(texto)+", great day aye?",200,20,100,20,main) hi=CreateLabel("Whats your name?",50,50,100,20,main) SeedRnd Milliseconds ;----------------------------------------------------------- ;Functions ;----------------------------------------------------------- Function GuiJuggler(CURRENT_EVENT) CURRENT_EVENT=WaitEvent() If CURRENT_EVENT=$803 Then Notify("Bye bye, until next time") Delay 1000 End Else If CURRENT_EVENT=$2001 Then Notify("If your tired of this program just hit X") Else If CURRENT_EVENT=$2002 Then Notify("Oh good your back!") EndIf EndIf EndIf End Function ; -------- Function ReturnName(Name) While Not GuiJuggler($803) If EventID()=$401 If EventSource()=button TextAreaText(texto) EndIf EndIf Wend End Function ;----------------------------------------------------------- GuiJuggler(CURRENT_EVENT) ReturnName(Name) EndThis is uncorrected, just an example of what ppl mean. Question: 1 Do functions in BPlus have to appear in the code before you use them (Either way it might be better to not stick them in the middle) 2 Does BPlus have an ElseIf command? |
| ||
Hi H&K - Q1 - functions can be anywhere although they must be after any arrays are declared which are used within a function Q2 - Yes. It does have an ElseIf command. |
| ||
Generally one wants functions in another file, to include into your main code, so in the end this function location is irrelevant anyway. |
| ||
Thanks Matty. @Siopses This is ment hopfully as some helpful advice. As you can see from my post above I have split your code into 3 parts 1) Event List, 2) Main Code, 3) Functions 2b)More code. As Matty has just confirmed then functions dont have to be written out before you call them, so move GuiJuggler(CURRENT_EVENT) ReturnName(Name) Endto before the Function part, then put a few blank lines then the functions. (This is only prefference) Or put them in another file and include them. Do not stick them in the middle of code with "Global Scope" Second, using if; when you are comparing things one after the other to see if they are true, then you dont need two if If EventID()=$401 If EventSource()=button TextAreaText(texto) EndIf EndIf If EventID()=$401 AND EventSource()=button TextAreaText(texto) EndIf There is also a command ElseIF (or Else If) which you could use as so If CURRENT_EVENT=$803 Then Notify("Bye bye, until next time") Delay 1000 End Else If CURRENT_EVENT=$2001 Then Notify("If your tired of this program just hit X") Else If CURRENT_EVENT=$2002 Then Notify("Oh good your back!") EndIf EndIf EndIf If CURRENT_EVENT=$803 Then Notify("Bye bye, until next time") Delay 1000 End Else If CURRENT_EVENT=$2001 Then Notify("If your tired of this program just hit X") Else If CURRENT_EVENT=$2002 Then Notify("Oh good your back!") EndIf |
| ||
Multiple checks could as well be done using Select-case-EndSelect. Also, I prefer to have a mainloop which waits for the events, and have functional parts checking for specific events. This is quite a standard mold you could use: Repeat WaitEvent() If EventId=$803 quit=1 SomeFunction ' function call to another function Until quit ' optionally some clean-up here.. End Function SomeFunction() If EventID()=... If EventSource()=... .. EndIf EndIf End Function No need to send events around using function arguements. The events are global. Ofcourse, what you really want is that everything is local, no globals whatsoever, as they truly limit your code -and motivation- when the source gets big. As a result of this localness you want your variables hidden, e.g. "datahiding", as much as you can. It's a bit crappy to explain this to a beginner btw, because I just *know* you'll fail to see the point of this. :P There's a tutorial in the B+ tutorial sections, made by me, which explains how to work with banks in combination with own gadgets.. apart from these own gadgets, the principle could be used for anything else. I could say 'skip it in the first years and just toy around a bit'. The problem however is that you have Blitzplus! Would you be a B3d user then it was easy: you'd probably be doing more gamestuff and less interface stuff. But since you're messing around with B+'s gadgets you're obviously interested in GUI/applications. At a certain point it's even right, games need editors, editors are best done with a GUI system. So, if you want to focus on GUI, prepare for patience and tidyness. Things to keep in mind about GUI: - an interface is usually most of the work for any tool - an interface can grow as functionality grows, it can actually grow even larger than the functionality grows An example: your functionality is: "draw an oval of any given color, size and location" A GUI? For a possible solution you'll need: - a canvas to see your result - since the user can create an oval off-screen, one must be able to scroll through the canvas - using scrollbars - using mousewheels - using keyboard shortcuts (e.g. cursors, page up/dn, home/end) - since the user can create small very ovals, one must be able to zoom in/out - using a scrollbar - using mousewheels - using keyboard shortcuts - the user might want to alter the size of the canvas, e.g. when the hostwindow gets resized or something - the user might want to click/drag the oval and have pickup squares (like in photoshop) to resize/relocate the oval. Some users would prefer this over textfields. - as the user can create black ovals, the user might want to be able to change the background color of the canvas - using 3 textfields for r,g,b - using 1 textfield for rgb (like $ffff00 for yellow) - using a button raising a colorrequester (some standard B+ object) - five textfields for x,y,width,height,color - when processing the color textfield there might be incorrect values (e.g. rgb values too high or negative) - prompt the user about it, or: - auto-clip them yourself - update that textfield again so that they contain the clipped values That's all quite a lot, just to have the ideal oval tool. But it's actually this nitpicking of details that consumes most of your time when doing a proper interface. But ok, let's assume you're up to this: you've seen that I used mousewheel/keyboard at two locations, if you want to support them at both points, you'll need to make sure they don't get mixed up. Next problem, you or someone else makes an additional request for your oval designer: now it should also draw rects and lines. Ouch, you just hardwired all the stuff to the DrawOval function, but well, the rect won't require more arguements and the line can steal away the w and h textfields for x2 and y2. So, sofar it's all doable. But now! You get a request for bezier-splines. DAMN, that'll require 8 parameters and perhaps another one to define the amount of line segments. Now you've not enough textfields, and your cornerpickup system in the canvas is worthless all of a sudden. You could add more textfields, but because you keep adding things, slowly but surely your source becomes a nightmare. Actually, I don't think I'm exaggerating this story, just look at 3dsmax or so, just observe what functionality it has in those canvases. Of course, who needs a tool to draw ovals, and who needs a tool with so many details? Even a map-editor has quite a lot of details tho, any GUI has details, more than you think! This fact of GUI-bloat means that you'll need to make sure that you START right with your GUI, that you start in a way which is future-proof. This is actually quite hard, even for me in Blitzmax with all its language extras compared to Blitzplus. It requires extra thinking on what might be required in the future. That's why it is SO EXTREMELY important to make tidy indented code, with enough white lines to keep things readable, and enough comments to make your code readable after 8 months of not touching it. (Even a week can be enough to obscure your memory regarding your own code!) Ok.. </lecture> :P |
| ||
G.U.I is extremely confusing, I have three questions How do you make usable buttons? How do you make usable window menus? I am so bad at this. I cannot make buttons, canvases or menu's that work. I tried to make a menu that requests an image to load and instead of it being a clean little "File" or "Help" menu it turned out to not even appear like that and be everything below a certain point. I'd give you the code but its not properly indented. Also, know any good Blitz tutorials, this website is lacking. |
| ||
I'd give you the code but its not properly indented. There you go again, you shouldn't just indent for this website, but also for yourself. Your code should've been indented as standard. And seriously, I find the manual extremely readable and educative. I learnt the GUI in only a week orso, without forum, without assistance, just by using the manual. |
| ||
; button howto window=CreateWindow("w00t!",0,0,640,480) MyButton=CreateButton("click here!",8,8,80,24,window) MyOtherButton=CreateButton("click here too!",8,32,80,24,window) Repeat WaitEvent() If EventID()=$803 quit=1 If EventID()=$401 If EventSource()=MyButton Notify "w00! button 1" If EventSource()=MyOtherButton Notify "w00! button 2" EndIf Until quit End Nnotice how the indenting at the creation of the menu items also makes things clear. ; windowmenus howto window=CreateWindow("w00t!",0,0,640,480) Menu_file=CreateMenu("&File",0,WindowMenu(window)) Menu_Open=CreateMenu("&Open",1,Menu_file) CreateMenu "",99999,Menu_file Menu_Save=CreateMenu("&Save",2,Menu_file) Menu_SaveAs=CreateMenu("Save &As",3,Menu_file) CreateMenu "",99999,Menu_file Menu_Quit=CreateMenu("&Quit",4,Menu_file) Menu_edit=CreateMenu("&Edit",100,WindowMenu(window)) Menu_Cut=CreateMenu("C&ut",101,Menu_edit) Menu_Copy=CreateMenu("&Copy",102,Menu_edit) Menu_Paste=CreateMenu("&Paste",103,Menu_edit) Menu_Tools=CreateMenu("&Tools",200,WindowMenu(window)) Menu_Showmoney=CreateMenu("&Showmoney",201,Menu_tools) Menu_help=CreateMenu("&Help",300,WindowMenu(window)) Menu_About=CreateMenu("&About",301,Menu_help) UpdateWindowMenu window ; otherwise you won't see changes MyButton=CreateButton("click here!",8,8,80,24,window) MyOtherButton=CreateButton("click here too!",8,32,80,24,window) Repeat WaitEvent() If EventID()=$803 quit=1 If EventID()=$401 If EventSource()=MyButton Notify "w00! button 1" If EventSource()=MyOtherButton Notify "w00! GANGBANG!" EndIf If EventID()=$1001 Select EventData() Case 1 a$=RequestFile("anything..") Case 2 a$=RequestFile("anything..",True) Case 3 a$=RequestFile("anything..",True) Case 101 Notify "cut" Case 102 Notify "copy" Case 103 Notify "paste" Case 201 If MenuChecked(Menu_Showmoney) UncheckMenu Menu_Showmoney Else CheckMenu Menu_Showmoney UpdateWindowMenu window Case 301 Notify "Random stuph"+Chr(13)+"All rights reserved" End Select EndIf Until quit End |
| ||
same shit, now with canvas.. |
| ||
If you create a button in a function will it work in that function? I've tried it out and it doesn't work. About my unindented code, that was a test before I started to indent. |
| ||
I'm trying to finish an app this weekend, just a paint or cal- culator thing. I'll work out the buggs myself. I'm using this forum way too much. Thanks for helping a stupid yank, Siopses |
| ||
A button, as well as a window, a canvas, image, timer etc. etc. is just a (int) variable. They can be declared locally in a function, but if you want it to work, then it must be within a loop where there's a WaitEvent() command. In this case the main repeat-until loop is the mainloop containing the WaitEvent, the function call gives the button as argument so that the function knows what it's supposed to be window=CreateWindow("oO",0,0,640,480) button=CreateButton("x",0,0,32,32,window) Repeat WaitEvent() If EventID()=$803 quit=1 dostuff button Until quit End Function dostuff(b) If EventID()=$401 If EventSource()=b Notify "yay!" EndIf EndIf End Function another option: the whole creation + mainloop in a function dostuff End Function dostuff() window=CreateWindow("oO",0,0,640,480) button=CreateButton("x",0,0,32,32,window) Repeat WaitEvent() If EventID()=$803 quit=1 If EventID()=$401 If EventSource()=button Notify "yay!" EndIf EndIf Until quit FreeGadget button FreeGadget window End Function here's how I've done these things for years: window=CreateWindow("bank demo",0,0,640,480) bank=createstuff(window) Repeat WaitEvent() If EventID()=$803 quit=1 dostuff bank Until quit End Function createstuff(window) bank=CreateBank(16) PokeInt bank,0 ,CreateButton("1",0,0,32,32,window) PokeInt bank,4 ,CreateButton("2",32,0,32,32,window) PokeInt bank,8, CreateButton("3",0,32,32,32,window) PokeInt bank,12,CreateButton("4",32,32,32,32,window) Return bank End Function Function dostuff(b) button1=PeekInt(b,0) button2=PeekInt(b,4) button3=PeekInt(b,8) button4=PeekInt(b,12) If EventID()=$401 Select EventSource() Case button1 Notify "1 monkey" Case button2 Notify "2 giraffe" Case button3 Notify "3 lions" Case button4 Notify "4 dogs" End Select EndIf End Function This bank stuff might appear tricky, but it's just memory you can fill with whatever. And since a gadget is just an int, and since you can store ints in banks, you can store gadgets in banks. This is quite a good method for datahiding. As you see there are no globals, and yet the functions do all the work. |
| ||
Ok thanks, I'll look into that CreateBank function. |
| ||
I have one question though, using banks how come you cannot use banks for text areas? My code is belowwindow=CreateWindow("ABACUS",200,200,500,400,window,15) menu=WindowMenu(window) help=CreateMenu("Help",0,menu) CreateMenu("About",1,help) ;Functions ;This function has a window parameter because of the bank Function SetUp(window) bank=CreateBank(35) PokeInt bank,5,CreateButton("+",100,300,75,75,window) PokeInt bank,10,CreateButton("-",200,300,75,75,window) PokeInt bank,15,CreateButton("*",300,300,75,75,window) PokeInt bank,20,CreateButton("/",400,300,75,75,window) PokeInt bank,25,CreateTextArea(100,100,50,50,window) PokeInt bank,30,CreateTextArea(400,100,50.50,window) ;So we can use this bank everywhere else Return bank End Function ;This function will allow us to add,subtract,multiply and divide. Function Math() plus=PeekInt(bank,5) subtract=PeekInt(bank,10) multiply=PeekInt(bank,15) divide=PeekInt(bank,20) value1=PeekInt(bank,25) value2=PeekInt(bank,30) Repeat If EventID()=$401 Select EventSource() Case plus Notify("Answer:"+TextAreaText(value1)+TextAreaText(value2)+"") Case subtract Notify("Answer:"+TextAreaText(value1)-TextAreaText(value2)+"") Case multiply Notify("Answer:"+TextAreaText(value1)*TextAreaText(value2)+"") Case divide Notify("Answer:"+TextAreaText(value1)/TextAreaText(value2)+"") Select WaitEvent() Case $803 Notify("Bye bye, 'till next time") Delay 500 End End Select End Select EndIf Forever End Function |
| ||
An int is 4 bytes. Use steps of 4 in your banks, currently you're wasting some bytes here and there by using steps of 5. Generally speaking, your code always looks weird to me, such unusual places to do the things you do. It's like you insist on drawing humans with two heads while everyone tells you a human has only one head.. :P * Indenting is not ideal yet, tabs of 8 are extremely uncomfortable. You might have this file: C:\Program Files\BlitzPlus\cfg\blitzide.prefs Open it, change the value after edit_tabs to 4. Maybe you even want to change colors and font? * Use plenty of whitelines, currently you have none. Whitelines are equally comfortable for a source as indenting. (a whiteline is just pressing [enter] 1x or 2x on a line without code) PokeInt bank,30,CreateTextArea(400,100,50.50,window) If you had read the error the IDE gave you, you would've noticed that the amount of parameters is incorrect. In total, you need 5 parameters, I count only 4. Look sharply. Once this works you'll notice it starts bugging you with "Operator cannot be applied to strings". TextAreaText is a string, you are doing math stuff to it. The only "math" you can do to strings is '+', but that's actually string-combining, so "23" + "23" becomes "2323", not "46". |
| ||
Actually there are countless o' bugs.. |
| ||
Fixed/souped-up the whole shebang: A few notes: - note how I added whitelines, stick to that habit! - get rid of the idea that you must put your waitevent into some function this is only relevant when doing popup-things that create, function and clear themself on their own. For instance, a popup bankmonitor, a popup color-selector, etc. you're still far from there, so don't bother yet. I strongly advice you to keep my standard mainloop model! Which means you'll have a small mainloop with the Waitevent() (you don't need any bla=WaitEvent()), a simple check on window-close, and then only function calls to the actual functionality. - You can debuglog a gadget, it'll show some very huge number, a sign it's created correctly. If you debuglog a gadget, and there's not any big number showing up then this gadget is not created correctly. Since this large number is equal to 'true' (which is any number except 0) you can check on the gadget's precent using If MyGadget ; do your stuff here Endif - Make DAMN well sure that you *never* divide by zero. I dunno what OS you're running, but doing a /0 using B+ in 98se means that you may reboot. Not because your system freezes, but because nothing ever compiled with Blitz will run nor compile. This check is quite simple: If Value Debuglog 1/Value EndIf This code is always correct as the IF checks whether it's 0 or not 0. When the condition is true it means that Value is not 0 and you can use it as divider. |
| ||
Oh never mind the tab 4 thing, it's this lousy codebox that's doing tab 8.. |
| ||
So basically I make TextAreaText(texto) into a Float and all then process it through the adding and such? |
| ||
Of course, even when the textareafields are only to be integer, even then 3/2 would result in 1.5 (which is a float), wouldn't it? |
| ||
Why does it have to be a float? |
| ||
If you divide 3/2 the int way, then you get 1 as result, not 1.5, because 1.5 is a float value. |
| ||
Is this a good set-up for a program?;G.U.I stuff bank=CreateBank(24) PokeInt bank,0,window=CreateWindow("PINTO",300,300,500,500,main,15) PokeInt bank,4,canvas=CreateCanvas(0,0,400,400,main) PokeInt bank,8,changecolor=CreateButton("Color",100,400,75,75,main,1) PokeInt bank,12,rectangle=CreateButton("Rect",200,400,75,75,main,1) PokeInt bank,16,rectsize=CreateButton("Rect size",300,400,75,75,main,1) PokeInt bank,20,freehand=CreateButton("Freehand",400,400,75,75,main,1) ;Variables FREE_HAND=1 RECT_DRAW=2 OVAL_DRAW=3 Repeat ;Function for handling events and such HandleGUI() ;Function for handling help menus HandleMenu() ;Function for handling colors ReceiveColor() ;This function is for painting Pinto() ;This function is for modifying canvas width, and height ModifyCanvas(canvas) ;Function for saving and loading SaveLoad() Forever |
| ||
yea.. could be.. As long as: * you put the WaitEvent() in that repeat loop, NOT in the functions you're calling * add whitelines * you give the appropriate bankhandle as function argument when calling those functions (e.g. HandleGUI GUIbank HandleMenu Menubank etc. unless you have everything in one bank of course, but that's not so very good from a modular point of view..) ) |
| ||
Ok thanks, that's all the help I'll need for now. |
| ||
What do you mean when you say could be? You mean if I code the functions well? I'm just asking if its a good frame for a program. So I don't need a loop for each function? |
| ||
"could be" as in, when you stick to those points I mentioned. So I don't need a loop for each function? nope. Blitz+ events work as follow: step 1: Wait for an event, if there's NO event, then NOTHING happens, your program is doing nothing, standing still, being idle. step 2: After an event of any kind occured then all the relevant ID, SOURCE, DATA, X, Y etc. fields are filled. These are global variables, so you can read them out anywhere step 3: Jump to your functions to see which events have been triggered and act according to it. Ofcourse, functions are not mandatory, but stuffing your whole application in your main loops is a bad idea. repeat these 3 steps. What it looks like in code: Repeat Waitevent() ; <- Here it waits, if nothing happens then the program counter is still here, and nowhere else. ; obviously something happened, so we continue DoThis() DoThat() If EventID()=$803 quit=1 Until quit Function DoThis() ; right here you can read out all the events you want ; You don't have to WaitEvent() here, because there's no need to wait, the reason you're here is because an Event has already occurred. It's in the global Event variables. End Function Function DoThis() ; right here you can read out all the events you want ; You don't have to WaitEvent() here, because there's no need to wait, the reason you're here is because an Event has already occurred. It's in the global Event variables. Function etc. |