Page 1 of 1

colored button

Posted: Fri Sep 02, 2016 8:49 pm
by ludoke
I a'm new to PB.I have a problem with colored buttons.
I found this example and I try to change it,the buttons gets the wanted color ,but when toggled the text is invissible

Code: Select all

;COLORED button
;needed :when selected background and textcolor must change
;PROBLEM : background change but text is invissible ???

EnableExplicit
Define text                                                     ;textcolor button
Define back                                                     ;backgroundcolor button
Define mywin,ev,width,height,x,y

Declare SetButtonColor(hGadget, text, back)        ;procedure declaration

mywin= OpenWindow (0,0,0,500,468, "color button" , #PB_Window_SystemMenu|#PB_Window_ScreenCentered )

If mywin   
  ButtonGadget(1, 10,  10, 250, 60, "Button 1")   
         back=RGB(255,0,0)                                    ;back=red
         text=RGB(0,255,0)                                    ;text=green
         SetButtonColor(1, text, back)                      ;call procedure
         
         ButtonGadget(2, 10,  100, 250, 60, "Button 2") ; button 2
         back=RGB(255,0,0)                                    ;back=red
         text=RGB(0,255,0)                                     ; text=green
         SetButtonColor(2, text, back)                      ;call procedure with desired colors
         Repeat 
           ev=WaitWindowEvent ()
           Select ev
             Case #PB_Event_Gadget                           
               Select EventGadget()
                 Case 1:   back=RGB(255,0,0) 
                              text=RGB(0,0,255)               ;change textcolor when pressed
                              SetButtonColor(1, text,back) ;if button1 pressed change color to blue text
                  Case 2:  back=RGB(255,255,0)           ;change to yellow
                              text=RGB(0,0,255) 
                              SetButtonColor(2, text,back);if button2 pressed change color to blue text         
                EndSelect
           EndSelect
           
         Until ev= #PB_Event_CloseWindow
EndIf
;---------------------------------------------------------------------------------------------------------
Procedure SetButtonColor(Id, text, back)
    Define txt.s
    Define width.I,height.i,x.i,y.i,result.i
    
         Txt.s=GetGadgetText(Id)
         width=GadgetWidth(Id)
         Height=GadgetHeight(Id)
         x=GadgetX(Id)
         y=GadgetY(Id)
         FreeGadget(Id)
         If IsFont(Id)
                  FreeFont(Id)
         EndIf
         If IsImage(Id)
                  FreeImage(Id)
         EndIf
         LoadFont(Id, "Arial 24", 18, #PB_Font_Bold) 
         If CreateImage(Id, width, height)                        
                  StartDrawing(ImageOutput(Id))
                           DrawingMode(#PB_2DDrawing_Transparent)                  
                           Box(0, 0,width, height, back)
                           DrawingFont(FontID(Id))
                           FrontColor(text)                     
                           DrawText((width-TextWidth(txt))/2,(height-TextHeight(txt))/2,Txt.s)                  
                  StopDrawing()
         EndIf         
         ButtonImageGadget(Id,x,y,width,Height,ImageID( Id))      
         ProcedureReturn result
EndProcedure
__________________________________________________
Code tags added
02.09.2016
RSBasic

Re: colored button

Posted: Fri Sep 02, 2016 9:47 pm
by IdeasVacuum
Hi ludoke. It's because the button should always be a ButtonImageGadget() in this case but part of your code uses ButtonGadget(). Should be fine if change all to ButtonImageGadget().

Re: colored button

Posted: Fri Sep 02, 2016 9:52 pm
by netmaestro
A ButtonImageGadget has no useful response to GetGadgetText. So the first time through, txt.s holds something useful because it came from GetGadgetText on a ButtonGadget. However, after it's been through the routine once, the gadget with that id is now a ButtonImageGadget, so GetGadgetText is returning nothing you can use. DrawText on the image is drawing an empty string.

Re: colored button

Posted: Fri Sep 02, 2016 10:26 pm
by BasicallyPure
hi ludoke,

Are you using Linux?
If so, this is probably the reason you don't see any text.
http://www.purebasic.fr/english/viewtop ... 23&t=66446
Apparently GetGadgetText() is broken in 5.50, the latest version of PB.

I have verified that text is visible when run under version 5.42.
(until you click on the buttons then the text goes away for the reasons given by IdeasVacuum and netmaestro.)

Re: colored button

Posted: Fri Sep 02, 2016 10:31 pm
by netmaestro
GetGadgetText is always broken on a ButtonImageGadget. That won't change anytime soon.

Re: colored button

Posted: Fri Sep 02, 2016 10:36 pm
by BasicallyPure
netmaestro wrote:GetGadgetText is always broken on a ButtonImageGadget. That won't change anytime soon.
You are correct.
I was just pointing out another possible problem if the OS is Linux.
I updated my previous post for clarity.

Re: colored button

Posted: Sat Sep 03, 2016 12:11 am
by mk-soft
I think the best way is draw own button with CanvasGadget...

Re: colored button

Posted: Sat Sep 03, 2016 6:29 am
by TI-994A
ludoke wrote:...I have a problem with colored buttons ... the buttons gets the wanted color ,but when toggled the text is invissible...
Your approach is workable, but requires some modification:

Code: Select all

EnableExplicit

Structure customButton
  state.i
  caption.s
  fontOn.i
  fontOff.i
  gadgetNo.i
  onForeColor.i
  onBackColor.i
  offForeColor.i
  offBackColor.i
EndStructure

Declare setButton(*button.customButton)
Define gadgetFontOn = LoadFont(#PB_Any, "Arial", 14, #PB_Font_Bold),
       gadgetFontOff = LoadFont(#PB_Any, "Arial", 14), appQuit

If OpenWindow (0, 0, 0, 250, 150, "Coloured Buttons", #PB_Window_SystemMenu |
                                                      #PB_Window_ScreenCentered )
  Define button1.customButton
  With button1
    \gadgetNo = ButtonImageGadget(#PB_Any, 10, 10, 230, 60, 0)
    \state = #True
    \caption = "Button 1"
    \fontOn = FontID(gadgetFontOn)
    \fontOff = FontID(gadgetFontOff)
    \offBackColor = RGB(255, 0, 0)
    \offForeColor = RGB(0, 255, 0)
    \onBackColor = RGB(255, 255, 0)
    \onForeColor = RGB(255, 0, 255)
  EndWith
  setButton(@button1)
  
  Define button2.customButton
  With button2
    \gadgetNo = ButtonImageGadget(#PB_Any, 10, 80, 230, 60, 0)
    \state = #True
    \caption = "Button 2"
    \fontOn = FontID(gadgetFontOn)
    \fontOff = FontID(gadgetFontOff)
    \offBackColor = RGB(255, 0, 0)
    \offForeColor = RGB(0, 255, 0)
    \onBackColor = RGB(0, 255, 255)
    \onForeColor = RGB(255, 0, 0)
  EndWith
  setButton(@button2)
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        appQuit = 1
      Case #PB_Event_Gadget
        Select EventGadget()
          Case button1\gadgetNo
            setButton(@button1)    
          Case button2\gadgetNo
            setButton(@button2)    
        EndSelect
    EndSelect
  Until appQuit = 1 
  
EndIf

Procedure setButton(*button.customButton)
  Protected width, height, btnImage, font,
            foreColor, backColor, caption.s
  With *button
    
    If \state
      \state = #False
      font = \fontOff
      caption = \caption
      foreColor = \offForeColor
      backColor = \offBackColor
    Else
      \state = #True
      font = \fontOn
      caption = UCase(\caption)
      foreColor = \onForeColor
      backColor = \onBackColor
    EndIf
    
    width = GadgetWidth(\gadgetNo)
    height = GadgetHeight(\gadgetNo)
    btnImage = CreateImage(#PB_Any, width, height)
    
    If btnImage
      StartDrawing(ImageOutput(btnImage))
        DrawingMode(#PB_2DDrawing_Transparent)                  
        Box(0, 0, width, height, backColor)
        DrawingFont(font)
        FrontColor(foreColor)
        DrawText((width - TextWidth(caption)) / 2, 
                 (height - TextHeight(caption)) / 2, caption)
      StopDrawing()
    EndIf     
    
    SetGadgetAttribute(\gadgetNo, #PB_Button_Image, ImageID(btnImage))
    
  EndWith
  
EndProcedure
It's still using PureBasic's standard ButtonImageGadget(), but implements a custom gadget structure to store and pass the custom attributes.

Although it's technically cross-platform, there seems to be some gadget-sizing issues when testing on Ubuntu 15.10.

Hope it helps. :wink:

Re: colored button

Posted: Sat Sep 03, 2016 8:37 am
by ludoke
I use windows10 64bit.
Thanks, it works now as I wanted, I still need to learn a lot.
PB is a wonderful programming language

Re: colored button

Posted: Sat Sep 03, 2016 11:07 am
by mk-soft
CanvasGadget is a nice way to create owner gadget. It´s perhaps to much for beginner, but "F1" from PB-IDE can help.

Code: Select all

;-TOP

; ButtonColorGadget
; Version 1.01
; By mk-soft
; From 02.09.2016

; ***************************************************************************************

EnableExplicit

Structure udtBCG
  state.i
  text.s
  fontid.i
  backcolor.i
  textcolor.i
EndStructure

; -------------------------------------------------------------------------------------

Procedure DrawColorButton(gadget, *data.udtBCG)
  Protected dx, dy
  
  If StartDrawing(CanvasOutput(gadget))
    With *data
      dx = GadgetWidth(gadget)
      dy = GadgetHeight(gadget)
      If \fontid
        DrawingFont(\fontid)
      EndIf
      Select \state
        Case #PB_EventType_MouseEnter
          Box(0, 0, dx, dy, \backcolor)
          DrawingMode(#PB_2DDrawing_Outlined)
          Box(0, 0, dx, dy, $D0D0D0)
          DrawingMode(#PB_2DDrawing_Transparent)
          DrawText((dx-TextWidth(\text))/2,(dy-TextHeight(\text))/2,\text,\textcolor)
          
        Case #PB_EventType_LeftButtonDown
          Box(1, 1, dx, dy, \backcolor)
          DrawingMode(#PB_2DDrawing_Outlined)
          Box(1, 1, dx, dy, $808080)
          DrawingMode(#PB_2DDrawing_Transparent)
          DrawText((dx+1-TextWidth(\text))/2,(dy+2-TextHeight(\text))/2,\text,\textcolor)
          
        Case #PB_EventType_LeftButtonUp, #PB_EventType_LeftClick
          Box(0, 0, dx, dy, \backcolor)
          DrawingMode(#PB_2DDrawing_Outlined)
          Box(0, 0, dx, dy, $D0D0D0)
          DrawingMode(#PB_2DDrawing_Transparent)
          DrawText((dx-TextWidth(\text))/2,(dy-TextHeight(\text))/2,\text,\textcolor)
          
        Case #PB_EventType_MouseLeave
          Box(0, 0, dx, dy, \backcolor)
          DrawingMode(#PB_2DDrawing_Outlined)
          Box(0, 0, dx, dy, $808080)
          DrawingMode(#PB_2DDrawing_Transparent)
          DrawText((dx-TextWidth(\text))/2,(dy-TextHeight(\text))/2,\text,\textcolor)
          
      EndSelect
      \state = 0
      StopDrawing()
    EndWith
  EndIf
  
EndProcedure

; -------------------------------------------------------------------------------------

Procedure EventHandlerColorButton()
  Protected gadget, event, *Data.udtBCG
  event = EventType()
  Select event
    Case #PB_EventType_MouseEnter, #PB_EventType_MouseLeave, #PB_EventType_LeftButtonDown, 
         #PB_EventType_LeftButtonUp, #PB_EventType_LeftDoubleClick
      ; Do
      gadget = EventGadget()
      *data = GetGadgetData(gadget)
      *data\state = event
      DrawColorButton(gadget, *data)
  EndSelect
  
EndProcedure

; -------------------------------------------------------------------------------------

Procedure ButtonColorGadget(Gadget, x, y, Width, Height, Text.s)
  Protected result, id, *Data.udtBCG
  
  result = CanvasGadget(Gadget, x, y, Width, Height)
  If result
    If Gadget = #PB_Any
      id = result
    Else
      id = Gadget
    EndIf
    *data = AllocateStructure(udtBCG)
    *data\state = #PB_EventType_MouseLeave
    *data\text = text
    *data\backcolor = $C0C0C0
    *data\textcolor = 0
    SetGadgetData(id, *data)
    DrawColorButton(id, *data)
    BindGadgetEvent(id, @EventHandlerColorButton())
  EndIf
  
  ProcedureReturn result
  
EndProcedure

; -------------------------------------------------------------------------------------

Procedure SetButtonColor(Gadget, TextColor, BackColor)
  Protected *Data.udtBCG
  
  If IsGadget(Gadget)
    If GadgetType(Gadget) = #PB_GadgetType_Canvas
      *data = GetGadgetData(Gadget)
      If *Data
        *data\state = #PB_EventType_MouseLeave
        If TextColor <> #PB_Ignore : *data\textcolor = TextColor : EndIf
        If BackColor <> #PB_Ignore : *Data\backcolor = BackColor : EndIf
        DrawColorButton(Gadget, *data)
      EndIf
    EndIf
  EndIf

EndProcedure

; -------------------------------------------------------------------------------------

Procedure SetButtonFont(Gadget, FontID)
  Protected *Data.udtBCG
  
  If IsGadget(Gadget)
    If GadgetType(Gadget) = #PB_GadgetType_Canvas
      *data = GetGadgetData(Gadget)
      If *Data
        *data\state = #PB_EventType_MouseLeave
        *data\fontid = FontID
        DrawColorButton(Gadget, *data)
      EndIf
    EndIf
  EndIf

EndProcedure

; -------------------------------------------------------------------------------------

Procedure SetButtonSize(Gadget, x, y, width, height)
  Protected *Data.udtBCG
  
  If IsGadget(Gadget)
    If GadgetType(Gadget) = #PB_GadgetType_Canvas
      *data = GetGadgetData(Gadget)
      If *Data
        *data\state = #PB_EventType_MouseLeave
        ResizeGadget(Gadget, x, y, width, height)
        DrawColorButton(Gadget, *data)
      EndIf
    EndIf
  EndIf

EndProcedure

; -------------------------------------------------------------------------------------

Procedure DestroyGadget(Gadget)
  Protected *data
  
  If IsGadget(gadget)
    If GadgetType(gadget) = #PB_GadgetType_Canvas
      *data = GetGadgetData(gadget)
      If *Data
        UnbindGadgetEvent(Gadget, @EventHandlerColorButton())
        FreeStructure(*data)
      EndIf
    EndIf
    FreeGadget(Gadget)
  EndIf
    
EndProcedure

; ***************************************************************************************

If OpenWindow(0, #PB_Ignore, #PB_Ignore, 400, 120, "ButtonColorGadget", #PB_Window_SystemMenu)
  
  ButtonColorGadget(0, 10, 10, 160, 25, "Hello")
  ButtonColorGadget(1, 180, 10, 160, 25, "World")
  SetButtonColor(0, $00F0F0, $F00000)
  ;SetButtonColor(1, #PB_Ignore, $00F000)
  
  LoadFont(0, "Arial", 16)
  SetButtonFont(0, FontID(0))
  SetButtonSize(0, #PB_Ignore, #PB_Ignore, #PB_Ignore, 30)
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Break
        
    EndSelect
    
  ForEver
  
  DestroyGadget(0)
  DestroyGadget(1)
  
EndIf
:wink: