How to create a togglebutton[SOLVED]

Started by Borislav, June 09, 2018, 18:13:41

Previous topic - Next topic

Borislav

Like a menubar button.

https://gyazo.com/2db7a865ee0015832f9e78a34e9cfba3

EDIT: I realised that it is possible to do this by adding 1 to buttonval with each MouseHit and then getting the remainder of buttonval divided by 2(Buttonval Mod 2).

Scaremonger

How about something like this:

SuperStrict

Import maxgui.drivers
AppTitle = "Togglebutton Example"
Local window:TGadget = CreateWindow( AppTitle, 100, 100, 320, 240, Null, WINDOW_TITLEBAR )

'# CREATE A DUMMY TOOLBAR IMAGE
If FileType( "iconstrip.png" )=0 Then
Local pixmap:TPixmap = CreatePixmap( 96,24, PF_RGBA8888)
ClearPixels( pixmap,$ffcccccc )
For Local x:Int = 3 To 21
WritePixel( pixmap,x,8,$FF000000 )
WritePixel( pixmap,x,12,$FF000000 )
WritePixel( pixmap,x,16,$FF000000 )
WritePixel( pixmap,24+x,8,$FFFFFFFF )
WritePixel( pixmap,24+x,12,$FFFFFFFF )
WritePixel( pixmap,24+x,16,$FFFFFFFF )
Next
SavePixmapPNG( pixmap, "iconstrip.png" )
End If

'# CREATE A TOOLBAR
Global toolbar:TGadget = CreateToolbar( Null, 0, 0, 0, 0, window )
SetGadgetIconStrip( toolbar, LoadIconStrip( "iconstrip.png" ) )
AddGadgetItem toolbar, "", 0, GADGETITEM_DEFAULT

'# CREATE A TREEVIEW
Global treeview:TGadget = CreateTreeView( 0,0,100,ClientHeight(window),window)
HideGadget( treeview )
Local root:TGadget=TreeViewRoot(treeview)
AddTreeViewNode( "Project1", root )
AddTreeViewNode( "Project2", root )
AddTreeViewNode( "Project3", root )
AddTreeViewNode( "Project4", root )
AddTreeViewNode( "Project5", root )

While WaitEvent()
Print CurrentEvent.ToString()
Select EventID()
Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE
End
Case EVENT_GADGETACTION
Select EventSource()
Case toolbar
Select EventData()
Case 0 '# Menu button
'# Flip the icon
If( GadgetItemIcon( toolbar,0) = 0 ) Then
HideGadget( treeview )
ModifyGadgetItem( toolbar,0,"",0,1 )
Else
ShowGadget( treeview )
ModifyGadgetItem( toolbar,0,"",0,0 )
End If
End Select
EndSelect
End Select
Wend

Borislav

#2
Quote from: Scaremonger on June 10, 2018, 20:19:29
How about something like this:

SuperStrict

Import maxgui.drivers
AppTitle = "Togglebutton Example"
Local window:TGadget = CreateWindow( AppTitle, 100, 100, 320, 240, Null, WINDOW_TITLEBAR )

'# CREATE A DUMMY TOOLBAR IMAGE
If FileType( "iconstrip.png" )=0 Then
Local pixmap:TPixmap = CreatePixmap( 96,24, PF_RGBA8888)
ClearPixels( pixmap,$ffcccccc )
For Local x:Int = 3 To 21
WritePixel( pixmap,x,8,$FF000000 )
WritePixel( pixmap,x,12,$FF000000 )
WritePixel( pixmap,x,16,$FF000000 )
WritePixel( pixmap,24+x,8,$FFFFFFFF )
WritePixel( pixmap,24+x,12,$FFFFFFFF )
WritePixel( pixmap,24+x,16,$FFFFFFFF )
Next
SavePixmapPNG( pixmap, "iconstrip.png" )
End If

'# CREATE A TOOLBAR
Global toolbar:TGadget = CreateToolbar( Null, 0, 0, 0, 0, window )
SetGadgetIconStrip( toolbar, LoadIconStrip( "iconstrip.png" ) )
AddGadgetItem toolbar, "", 0, GADGETITEM_DEFAULT

'# CREATE A TREEVIEW
Global treeview:TGadget = CreateTreeView( 0,0,100,ClientHeight(window),window)
HideGadget( treeview )
Local root:TGadget=TreeViewRoot(treeview)
AddTreeViewNode( "Project1", root )
AddTreeViewNode( "Project2", root )
AddTreeViewNode( "Project3", root )
AddTreeViewNode( "Project4", root )
AddTreeViewNode( "Project5", root )

While WaitEvent()
Print CurrentEvent.ToString()
Select EventID()
Case EVENT_WINDOWCLOSE, EVENT_APPTERMINATE
End
Case EVENT_GADGETACTION
Select EventSource()
Case toolbar
Select EventData()
Case 0 '# Menu button
'# Flip the icon
If( GadgetItemIcon( toolbar,0) = 0 ) Then
HideGadget( treeview )
ModifyGadgetItem( toolbar,0,"",0,1 )
Else
ShowGadget( treeview )
ModifyGadgetItem( toolbar,0,"",0,0 )
End If
End Select
EndSelect
End Select
Wend

Thank you for the answer, but that is the Blitz3D forum and your code is BlitzMax.
And also, what you have gave me is really nice, I ran it on BlitzMax.


Derron

You get what you ask for - and you did not give enough clues on what ways are allowed to achieve the desired thing.

if you need a programmatical way (your own widget, so no GUI) it is a simple two state thing:

- check for clicks on a specific area (eg. the rectangle area "x, y, x+w, y+h")
- if the mouse is clicked (or just "hit", depends on your wish), set a variable "buttonToggleOn" to "1 minus buttonToggleOn")
- "buttonToggleOn" now describes if the switch is toggled on or not


bye
Ron

Borislav

#4
Quote from: Derron on June 11, 2018, 06:33:41
You get what you ask for - and you did not give enough clues on what ways are allowed to achieve the desired thing.

if you need a programmatical way (your own widget, so no GUI) it is a simple two state thing:

- check for clicks on a specific area (eg. the rectangle area "x, y, x+w, y+h")
- if the mouse is clicked (or just "hit", depends on your wish), set a variable "buttonToggleOn" to "1 minus buttonToggleOn")
- "buttonToggleOn" now describes if the switch is toggled on or not


bye
Ron
I tried to do that once.

DrawImage button, 100, 100
btnval = 0
If MouseX() > 100 And MouseX() < 200 And MouseY() > 100 And MouseY() < 150 Then
DrawImage buttonhover, 100, 100
If MouseDown(1) And btnval = 0
DrawImage buttonactive, 100, 100
btnval = 1
EndIf
If MouseDown(1) And btnval = 1
DrawImage buttonactive, 100, 100
btnval = 0
EndIf
EndIf



It doesn't work.
I also used numerous other methods.

Derron

This is because your code contains flaws:

Code (BlitzMax) Select

DrawImage button, 100, 100
btnval = 0

So you reset the "btnval" in each loop? Means right before your checks you reset... it is always "0" then.

Code (BlitzMax) Select

If MouseX() > 100 And MouseX() < 200 And MouseY() > 100 And MouseY() < 150 Then
  DrawImage buttonhover, 100, 100
  If MouseDown(1) And btnval = 0
    DrawImage buttonactive, 100, 100
    btnval = 1
  EndIf
  If MouseDown(1) And btnval = 1
    DrawImage buttonactive, 100, 100
    btnval = 0
  EndIf
EndIf

Ok, that "if within rectangle" check on the first line is ok.
Then you draw the hover button image ... and draw the active button image _on_top_ two times. Yes, two times.

1) Ok, you draw the hover image
2) if mouse down and btnval = 0 ... draw the active image and btnval becomes 1
3) ohh, mouse still down and btnval is now 1 (in the very same loop!) so it gets drawn too!

Your if loop needs to be a bit different

Code (Blitzmax) Select

if withinButtonRectangle
  if not MouseDown(1)
    drawnormal
    btnval = 0
  else
     drawactive
     if btnval = 0 then HandleClickOnButton()
     btnval = 1
  endif
endif


and of course there could be a different kind of handling: checking the mouse down on the first "mouse down" and from then it is no longer important if the mouse is in the rectangle of the button. And when releasing the mouse button (mouse up) you check again if the mouse is in the button rectangle. In Windows you see this behaviour when clicking a button and keeping the mouse button pressed while moving out of the button area.


bye
Ron

ENAY

Quote
I tried to do that once.

:O
Well, you're calling MouseDown twice in the same bit of code and not using ELSE
So you're setting the button on and then immediately off again each time you click the mouse....

Borislav

#7
Quote from: ENAY on June 12, 2018, 11:02:35
Quote
I tried to do that once.

:O
Well, you're calling MouseDown twice in the same bit of code and not using ELSE
So you're setting the button on and then immediately off again each time you click the mouse....
Well, I did multiple of other ways, I did this one in a rush so it is not really good.
I found my original way I did it.
If Checkbox1 = 0 Then

DrawImage CheckBoxOff, 950,700

EndIf

If Checkbox1 = 1 Then

DrawImage CheckBox, 950,700

EndIf

If MouseX() > 950 And MouseX() < 982 And MouseY() > 700 And MouseY() < 732 Then
If Checkbox1 = 1
DrawImage CheckBoxHover,950,700
EndIf

If Checkbox1 = 0
DrawImage CheckBoxOffHover,950,700
EndIf

EndIf

If MouseX() > 950 And MouseX() < 982 And MouseY() > 700 And MouseY() < 732 And Checkbox1 = 1 And MouseDown(1) Then
DrawImage CheckBoxOff, 950,700
Checkbox1 = 0
EndIf

If MouseX() > 950 And MouseX() < 982 And MouseY() > 700 And MouseY() < 732 And Checkbox1 = 0 And MouseDown(1) Then
DrawImage CheckBox,950,700
Checkbox1 = 1
EndIf

Didn't work.
I did an another version.
If checkboxstate=1
DrawImage CheckBox, 950,700
EndIf
If checkboxstate=0
DrawImage CheckBoxOff, 950,700
EndIf

If MouseX() > 950 And MouseX() < 982 And MouseY() > 700 And MouseY() < 732 Then

If MouseDown(1)
If checkboxstate=0 checkboxstate=1
If checkboxstate=1 checkboxstate=0
EndIf
EndIf

Didn't work either.
:(

Derron

Id did not work because of this:

Code (BlitzMax) Select

If MouseDown(1)
If checkboxstate=0 checkboxstate=1
If checkboxstate=1 checkboxstate=0
EndIf
EndIf


What it does is:

if mouse is down do all the following things:
- if checkboxstate is 0 then set it to 1
- if checkboxstate is 1 (it is 1 if it was 1 or if it just was set to 1 a line above) set it to 0

You need to learn "else" and "elseif"  - to avoid that both checkboxstate-if's are executed right after another.


bye
Ron

Borislav

Quote from: Derron on June 12, 2018, 14:56:56
It did not work because of this:

Code (BlitzMax) Select

If MouseDown(1)
If checkboxstate=0 checkboxstate=1
If checkboxstate=1 checkboxstate=0
EndIf
EndIf


What it does is:

if mouse is down do all the following things:
- if checkboxstate is 0 then set it to 1
- if checkboxstate is 1 (it is 1 if it was 1 or if it just was set to 1 a line above) set it to 0

You need to learn "else" and "elseif"  - to avoid that both checkboxstate-if's are executed right after another.


bye
Ron
I know else and elseif but I didn't realise that using it would actually make it work.