Is this a bug?

BlitzPlus Forums/BlitzPlus Beginners Area/Is this a bug?

Siopses(Posted 2007) [#1]
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.


Adam Novagen(Posted 2007) [#2]
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.


CS_TBL(Posted 2007) [#3]
..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..


Gabriel(Posted 2007) [#4]
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.


Adam Novagen(Posted 2007) [#5]
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.


CS_TBL(Posted 2007) [#6]
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.


Gabriel(Posted 2007) [#7]
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.


Siopses(Posted 2007) [#8]
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 



CS_TBL(Posted 2007) [#9]
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)


Adam Novagen(Posted 2007) [#10]
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 Function
This 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!


Siopses(Posted 2007) [#11]
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.


CS_TBL(Posted 2007) [#12]
do you know what a scope is?


Siopses(Posted 2007) [#13]
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



CS_TBL(Posted 2007) [#14]
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.


Siopses(Posted 2007) [#15]
Thank you for the help, but do you know why CreateButton()
is'nt working on my Blitz Plus application?


Adam Novagen(Posted 2007) [#16]
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.


Siopses(Posted 2007) [#17]
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?


Siopses(Posted 2007) [#18]
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.


Matty(Posted 2007) [#19]
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.


Siopses(Posted 2007) [#20]
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.


CS_TBL(Posted 2007) [#21]
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)


Siopses(Posted 2007) [#22]
Thank you, I tested it and you were right. I'm going to write
those rules down.
Thanks,
Siopses


H&K(Posted 2007) [#23]
;-----------------------------------------------------------
;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
This 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?


Matty(Posted 2007) [#24]
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.


CS_TBL(Posted 2007) [#25]
Generally one wants functions in another file, to include into your main code, so in the end this function location is irrelevant anyway.


H&K(Posted 2007) [#26]
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)
End
to 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



CS_TBL(Posted 2007) [#27]
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


Siopses(Posted 2007) [#28]
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.


CS_TBL(Posted 2007) [#29]
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.


CS_TBL(Posted 2007) [#30]
; 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



CS_TBL(Posted 2007) [#31]
same shit, now with canvas..



Siopses(Posted 2007) [#32]
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.


Siopses(Posted 2007) [#33]
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


CS_TBL(Posted 2007) [#34]
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.


Siopses(Posted 2007) [#35]
Ok thanks, I'll look into that CreateBank function.


Siopses(Posted 2007) [#36]
I have one question though, using banks how come you cannot use banks for text areas? My code is below
window=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 



CS_TBL(Posted 2007) [#37]
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".


CS_TBL(Posted 2007) [#38]
Actually there are countless o' bugs..


CS_TBL(Posted 2007) [#39]
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.


CS_TBL(Posted 2007) [#40]
Oh never mind the tab 4 thing, it's this lousy codebox that's doing tab 8..


Siopses(Posted 2007) [#41]
So basically I make TextAreaText(texto) into a Float and all
then process it through the adding and such?


CS_TBL(Posted 2007) [#42]
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?


Siopses(Posted 2007) [#43]
Why does it have to be a float?


CS_TBL(Posted 2007) [#44]
If you divide 3/2 the int way, then you get 1 as result, not 1.5, because 1.5 is a float value.


Siopses(Posted 2007) [#45]
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 



CS_TBL(Posted 2007) [#46]
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..)
)


Siopses(Posted 2007) [#47]
Ok thanks, that's all the help I'll need for now.


Siopses(Posted 2007) [#48]
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?


CS_TBL(Posted 2007) [#49]
"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.