Seite 1 von 1

TextGadget als Buttons missbrauchen (Hover/Toggle)

Verfasst: 27.01.2021 04:31
von Hoto
Ein simples Beispiel wie man TextGadgets als Buttons missbrauchen kann. Mit Hovereffekt und einem Toggle Button.

Einschränkungen bei dem Beispiel:

- Tab Taste geht nicht
- Im Gegensatz zu echten Buttons wird #PB_Event_Gadget schon beim runterdrücken der Taste getriggert und nicht erst beim loslassen

Beides wäre sicherlich fixbar, wollte mich an dem Beispiel aber nicht zu lange aufhalten. Eventuell auch Optimierungsfähig.

Der Haupttrick liegt an #SS_NOTIFY, der Text Gadgets klickbar macht (mit dem Trick funktionieren auch Tooltips bei Text Gadgets) und an #SS_CENTERIMAGE, was den Text vertical zentriert und es so wie ein Button aussehen lässt. Ein Rahmen kann man nach belieben selbst setzen, wenn gezeichnet auch in beliebiger Farbe, dann ist wirklich alles nach belieben einfärbbar und ziemlich frei gestaltbar.

Über GetGadgetData(GadgetID) kann man zudem den Status eines Toggle Buttons auslesen, 1 = gedrückt / 0 = nicht gedrückt.

Ich hab es für ein paar seitliche Buttons genutzt um daneben unterschiedliche Setting Tabs zu öffnen.

Gibt natürlich auch noch andere Lösungen für die Problematik, dass ButtonGadgets noch immer nicht einfärbbar sind, was nicht so schön ist wenn man einen DarkMode für seine App anbieten will.

Edit: Thread entfernt und flickern gefixt

Code: Alles auswählen

EnableExplicit

Define Event, GID.c
Global MState.b

Global ButtonFGColor.l = $FFFFFF, ButtonBGColor.l = $2F2822, ButtonBGColorHL.l = $8F6842, ButtonBGColorTOG.l = $BFA882 ; DarkMode
;Global ButtonFGColor.l = $000000, ButtonBGColor.l = $E0E0E0, ButtonBGColorHL.l = $FFF0E0, ButtonBGColorTOG.l = $F8E4D0 ; LightMode

Procedure CheckButton()
  Define re.RECT, pt.POINT, GID.c
  
  GID = 1
  While IsGadget(GID)
    If GadgetType(GID) = #PB_GadgetType_Text
      GetWindowRect_(GadgetID(GID),re.RECT)
      GetCursorPos_(pt.POINT)
      If PtInRect_(re, pt\y << 32 + pt\x) = 1
        If MState = 1
          If GetGadgetColor(GID,#PB_Gadget_BackColor) <> ButtonBGColorTOG 
            SetGadgetColor(GID,#PB_Gadget_BackColor,ButtonBGColorTOG)
          EndIf
        ElseIf GetGadgetData(GID) = 0
          If GetGadgetColor(GID,#PB_Gadget_BackColor) <> ButtonBGColorHL 
            SetGadgetColor(GID,#PB_Gadget_BackColor,ButtonBGColorHL)
          EndIf
        EndIf
      Else
        If GetGadgetData(GID) = 0
          If GetGadgetColor(GID,#PB_Gadget_BackColor) <> ButtonBGColor
            SetGadgetColor(GID,#PB_Gadget_BackColor,ButtonBGColor)
          EndIf
        Else
          If GetGadgetColor(GID,#PB_Gadget_BackColor) <> ButtonBGColorTOG 
            SetGadgetColor(GID,#PB_Gadget_BackColor,ButtonBGColorTOG)
          EndIf
        EndIf
      EndIf
    EndIf
    GID + 1
  Wend
EndProcedure

If OpenWindow(0,0,0,240,220,"Window",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)

  TextGadget(1,20,10,200,40,"Gadget 1",#PB_Text_Center|#SS_CENTERIMAGE|#SS_NOTIFY|#WS_BORDER)
  SetGadgetColor(1,#PB_Gadget_FrontColor,ButtonFGColor)
  SetGadgetColor(1,#PB_Gadget_BackColor,ButtonBGColor)
 
  TextGadget(2,20,60,200,40,"Gadget 2 (Toggle)",#PB_Text_Center|#SS_CENTERIMAGE|#SS_NOTIFY|#WS_BORDER)
  SetGadgetColor(2,#PB_Gadget_FrontColor,ButtonFGColor)
  SetGadgetColor(2,#PB_Gadget_BackColor,ButtonBGColor)
 
  ButtonGadget(3,20,110,200,40,"Gadget 3")
  ButtonGadget(4,20,160,200,40,"Gadget 4 (Toggle)",#PB_Button_Toggle)

  Repeat
   
    Event = WaitWindowEvent(20)
   
    Select Event
      Case #WM_LBUTTONDOWN
        MState = 1
      Case #WM_LBUTTONUP
        MState = 0
      Case #PB_Event_Gadget
        Select EventType()
          Case #PB_EventType_LeftClick
            Select EventGadget()
              Case 1
                Debug "Fake Button pressed"
              Case 2
                If GetGadgetData(2) = 0
                  SetGadgetData(2,1)
                  Debug "Fake Button toggled (activated)"
                Else
                  SetGadgetData(2,0)
                  Debug "Fake Button toggled (deactivated)"
                EndIf
              Case 3
                Debug "Real Button pressed"
              Case 4
                Debug "Real Button toggled"
            EndSelect
        EndSelect
    EndSelect
    
    CheckButton()
   
  Until Event = #PB_Event_CloseWindow
EndIf

Re: TextGadget als Buttons missbrauchen (Hover/Toggle)

Verfasst: 27.01.2021 20:00
von ccode_new
Kleine Anmerkung:

Warum muss das über einen extra Thread laufen?
-> Das Ganze (1. Button) flackert ohne Ende.

Re: TextGadget als Buttons missbrauchen (Hover/Toggle)

Verfasst: 28.01.2021 00:05
von Hoto
Naja, ich hab den Teil von RSBasic.de WinApi Teil rausgenommen um zu prüfen ob die Maus über dem Button ist oder nicht.

In meinem eigenen Programm habe ich das mit einer extra Variable gefixt. Funktioniert bei dem Beispiel hier aber nicht so gut, da der Anklick-Effekt dann fehlt.

Hier ohne Thread und dem Flicker Fix:

Edit: noch mal umgebaut, jetzt funktioniert auch wieder der Anklick-Effekt. Hab nun lediglich vorher immer eine Abfrage eingebaut ob das ändern der Farbe überhaupt nötig ist.

Danke für den Hinweis, hab es nun auch in meinem Programm schnell umgebaut.

Re: TextGadget als Buttons missbrauchen (Hover/Toggle)

Verfasst: 28.01.2021 19:44
von mk-soft
MouseOver für alle fast Gadgets und für alle OS

Link: Module System

Re: TextGadget als Buttons missbrauchen (Hover/Toggle)

Verfasst: 28.01.2021 21:25
von Hoto
Hm, sieht nützlich aus um den Mouse Over unter Linux/Mac zum laufen zu kriegen. Der Rest müsste auch unter Linux/Mac laufen.