Seite 1 von 1

Hintergrundfarbe des Fensters/Gadges ermitteln

Verfasst: 30.07.2023 19:55
von jogo
Moin,
ich habe es bisher nicht geschafft, mit GetGadgetColor() die Hintergrundfarbe eines Fensters oder Gadges zu ermitteln, wenn ich sie zuvor NICHT mit SetGadgetColor() gesetzt habe. Die Hintergrundfarbe wird also abhänging vom eingestellten Theme gesetzt.

Da wollte ich dann bei Programmstart entsprechend der aktuellen Hintergrundfarbe eine passende Schriftfarbe wählen.
Hat da jemand einen Lösungsansatz?

Re: Hintergrundfarbe des Fensters/Gadges ermitteln

Verfasst: 08.08.2023 11:06
von RSBasic
Hallo,

mit der WinAPI-Funktion GetSysColor_() kannst du die Standard-Hintergrundfarbe ermitteln.
Für GetSysColor_() gibt es zahlreiche Konstanten für jede einzelne Systemfarbe, z.B. Fenster-Hintergrundfarbe, Farbe der Schrift, der Titelleiste usw.
Beispielcode: https://www.rsbasic.de/aktualisierung/w ... mitteln.pb
Auflistung einiger Systemfarben mit den jeweiligen Konstanten, die du verwenden kannst: https://learn.microsoft.com/de-de/windo ... etsyscolor
Die Konstante, die du für Fensterhintergrund suchst, ist: #COLOR_3DFACE

Re: Hintergrundfarbe des Fensters/Gadges ermitteln

Verfasst: 08.08.2023 11:46
von Macros
@RSBasic: Gut gemeint, aber guck mal auf den Forumnamen ;)

@jogo:
Das keine Farbe zurückgegeben wird, solang keine gesetzt wurde steht ja auch in der Hilfe.

Ähnlich wie es RSBasic für Windows demonstriert hat, kannst du auch unter Linux die Farbe mittels der APIs ermitteln.
Falls du GTK verwendest, ist hier ein Ansatz: https://stackoverflow.com/questions/303 ... ound-color
Für das QT Subsystem hier: https://stackoverflow.com/questions/174 ... log-window
Jemand, der geübter damit ist die Apis zu nutzen als ich, kann dir sicher mit einem Beispiel helfen.

z.B. hat sich im Englischen Forum "wombats" einem ähnlichen Problem für QTgestellt:
https://www.purebasic.fr/english/viewtopic.php?t=73874
Und mk-soft hat ein Beispiel für die Nutzung der GTK API hier:
http://forums.purebasic.com/english/vie ... hp?t=77261

Interessant wäre auch was du erreichen willst. Willst du z.B. die Farbe einfach wieder auf die Systemfarbe zurückändern, kannst du sie im QT Subsystem einfach wieder auf -1 setzen.

Re: Hintergrundfarbe des Fensters/Gadges ermitteln

Verfasst: 08.08.2023 11:54
von RSBasic
Arg, verdammt, danke für den Hinweis, Macros.
Dann bitte meinen Beitrag ignorieren.

Re: Hintergrundfarbe des Fensters/Gadges ermitteln

Verfasst: 27.08.2023 18:51
von jogo
Mein Problem ist folgendes:
ich habe für das Fenster keine Hintergrundfarbe gesetzt // ist also bei mir standardmäßig grau bzw weiß bei den StringGadgets.
In diesem Fenster habe einige Text- bzw. Stringgadgets platziert.
Diese Gadgets haben verschiedene Schriftfarben, um gewisse Zustände besser zu signalisieren.
Das Probelem ist, dass es dann auf anderen Systemen vorkommen kann, auf denen zum Beispiel ein dunkles Theme eingestellt ist, dass die Schrift in einigen Farben sehr schlecht zu lesen ist.

Meine Idee ist deshalb, beim Programmstart die Hintergrundfarbe des Fensters oder des Gadgets zu ermitteln (zB. die Pixelposition 1,1 oder ähnlich // wie auch immer).
Und wenn sie dunkel ist, setzte ich für die Schrift dann andere Farben, die für den dunklen Hintergrund geeignet sind.
Was besseres ist mit dafür halt erstmal nicht eingefallen. :)

Re: Hintergrundfarbe des Fensters/Gadges ermitteln

Verfasst: 27.08.2023 20:15
von mk-soft
Sollte so laufen ...

Code: Alles auswählen

;-TOP

; GTK DarkMode by mk-soft, v1.02.1, 18.12.2022
; Link: https://www.purebasic.fr/english/viewtopic.php?t=80298

Procedure.s GetThemeName()
  Protected ThemeName.s, *Settings, *Theme
  
  *Settings = gtk_settings_get_default_()
  If *Settings
    g_object_get_(*Settings, "gtk-theme-name", @strVal);
    ThemeName.s = PeekS(strVal, -1, #PB_UTF8)
    g_free_(strVal)
    ProcedureReturn ThemeName
  EndIf
EndProcedure

Procedure SetThemeName(ThemeName.s)
  Protected *Settings, *Theme
  
  *Settings = gtk_settings_get_default_()
  If *Settings
    *Theme = UTF8(ThemeName)
    g_object_set_(*Settings, "gtk-theme-name", *Theme);
    FreeMemory(*Theme)
    ProcedureReturn #True
  EndIf
EndProcedure

; ----

Procedure IsDarkMode()
  Protected boolVal, *Settings, *Theme
  
  *Settings = gtk_settings_get_default_()
  If *Settings
    g_object_get_(*Settings, "gtk-application-prefer-dark-theme", @boolVal);
    ProcedureReturn boolVal
  EndIf
EndProcedure

Procedure SetDarkMode(State)
  Protected boolVal, *Settings
  
  *Settings = gtk_settings_get_default_()
  If *Settings
    g_object_get_(*Settings, "gtk-application-prefer-dark-theme", @boolVal)
    g_object_set_(*Settings, "gtk-application-prefer-dark-theme", State);
    ProcedureReturn boolVal
  EndIf
EndProcedure

; ****

;-TOP

; GTK GetWindowColor by mk-soft, v1.01.1, 27.08.2023

ImportC ""
  gtk_widget_get_style_context(Widget)
  gtk_style_context_get_background_color(context, state, pcolor)
EndImport

#GTK_STATE_FLAG_NORMAL       = 0
#GTK_STATE_FLAG_ACTIVE       = 1 << 0
#GTK_STATE_FLAG_PRELIGHT     = 1 << 1
#GTK_STATE_FLAG_SELECTED     = 1 << 2
#GTK_STATE_FLAG_INSENSITIVE  = 1 << 3
#GTK_STATE_FLAG_INCONSISTENT = 1 << 4
#GTK_STATE_FLAG_FOCUSED      = 1 << 5
#GTK_STATE_FLAG_BACKDROP     = 1 << 6
#GTK_STATE_FLAG_DIR_LTR      = 1 << 7
#GTK_STATE_FLAG_DIR_RTL      = 1 << 8

Structure GdkRGBA
  red.d;
  green.d;
  blue.d;
  alpha.d;
EndStructure

Procedure.l GetWindowColorEx(Window)
  Protected r1, context, color.GdkRGBA
  
  context = gtk_widget_get_style_context(WindowID(Window))
  gtk_style_context_get_background_color(context, #GTK_STATE_FLAG_NORMAL, @color)
  r1 = RGBA(color\red * 255, color\green * 255, color\blue * 255, color\alpha * 255)
  ProcedureReturn r1
EndProcedure

; ****

Enumeration Windows
  #Main
EndEnumeration

Enumeration MenuBar
  #MainMenu
EndEnumeration

Enumeration MenuItems
  
EndEnumeration

Enumeration Gadgets
  #MainEdit
  #MainButton1
  #MainButton2
EndEnumeration

Enumeration StatusBar
  #MainStatusBar
EndEnumeration

Procedure UpdateWindow()
  Protected dx, dy
  dx = WindowWidth(#Main)
  dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar)
  ; Resize gadgets
  ResizeGadget(#MainEdit, 5, 5, dx -10, dy - 45)
  ResizeGadget(#MainButton1, 10, dy - 35, 120, 30)
  ResizeGadget(#MainButton2, dx - 130, dy - 35, 120, 30)
EndProcedure

Procedure Main()
  Protected dx, dy, Theme.s
  
  #MainStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, 800, 600, "Window" , #MainStyle | #PB_Window_Invisible)
    ; Menu
    CreateMenu(#MainMenu, WindowID(#Main))
    
    ; StatusBar
    CreateStatusBar(#MainStatusBar, WindowID(#Main))
    AddStatusBarField(#PB_Ignore)
    
    ; Gadgets
    dx = WindowWidth(#Main)
    dy = WindowHeight(#Main) - StatusBarHeight(#MainStatusBar)
    EditorGadget(#MainEdit, 5, 5, dx -10, dy - 45)
    ButtonGadget(#MainButton1, 10, dy - 35, 120, 30, "Set Dark")
    ButtonGadget(#MainButton2, dx - 130, dy - 35, 120, 30, "Clear Dark")
    
    Theme = GetThemeName()
    Theme = RemoveString(Theme, "-dark", #PB_String_NoCase)
    SetThemeName(Theme)
    
    If Not IsDarkMode()
      SetDarkMode(#True)
    EndIf
    
    SetGadgetText(#MainEdit, "ThemeName: " +  GetThemeName())
    ; Bind Events
    BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), #Main)
    
    HideWindow(#Main, 0)
    
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Break
          
        Case #PB_Event_Menu
          Select EventMenu()
            CompilerIf #PB_Compiler_OS = #PB_OS_MacOS   
              Case #PB_Menu_About
                
              Case #PB_Menu_Preferences
                
              Case #PB_Menu_Quit
                PostEvent(#PB_Event_CloseWindow, #Main, #Null)
                
            CompilerEndIf
              
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #MainEdit
              Select EventType()
                Case #PB_EventType_Change
                  ;
              EndSelect
              
            Case #MainButton1
              Select EventType()
                Case #PB_EventType_LeftClick
                  If SetDarkMode(#True)
                    StatusBarText(#MainStatusBar, 0, " Old DarkMode: True")
                  Else
                    StatusBarText(#MainStatusBar, 0, " Old DarkMode: False")
                  EndIf
                  
              EndSelect
              Debug "$" + RSet(Hex(GetWindowColorEx(#Main), #PB_Long), 8, "0")
              
            Case #MainButton2
              Select EventType()
                Case #PB_EventType_LeftClick
                  If SetDarkMode(#False)
                    StatusBarText(#MainStatusBar, 0, " Old DarkMode: True")
                  Else
                    StatusBarText(#MainStatusBar, 0, " Old DarkMode: False")
                  EndIf
                  
              EndSelect
              Debug "$" + RSet(Hex(GetWindowColorEx(#Main), #PB_Long), 8, "0")
              
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()