Dynamically define highlight colour

Just starting out? Need help? Post your questions and find answers here.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Dynamically define highlight colour

Post by IdeasVacuum »

By default, my program has a near black background and white text. Gadgets (e.g. ListIcon row) are highlighted on hover by changing the background colour to a blue-gray.

That's all fine and dandy, but if I give the User the tools to set background and text colour, it would be good if the highlight colour was automatic. Has anyone calculated a highlight colour for this type of scenario?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: Dynamically define highlight colour

Post by BarryG »

Don't know if this is exactly what you mean, but here's what I do to automatically set the grid line color in ListIconGadgets to match what the background color of the ListIconGadget is:

Code: Select all

Procedure SetBackColorAndLines(gad,color)
  r=Red(color)-20 : If r<0 : r=0 : EndIf
  g=Green(color)-20 : If g<0 : g=0 : EndIf
  b=Blue(color)-20 : If b<0 : b=0 : EndIf
  SetGadgetColor(gad,#PB_Gadget_BackColor,color)
  SetGadgetColor(gad,#PB_Gadget_LineColor,RGB(r,g,b))
EndProcedure

If OpenWindow(0, 100, 100, 300, 150, "ListIcon Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ListIconGadget(0, 5, 5, 290, 105, "Name", 100, #PB_ListIcon_GridLines | #PB_ListIcon_AlwaysShowSelection)
  AddGadgetColumn(0, 1, "Address", 250)
  AddGadgetItem(0, -1, "Harry Rannit"+Chr(10)+"12 Parliament Way, Battle Street, By the Bay")
  AddGadgetItem(0, -1, "Ginger Brokeit"+Chr(10)+"130 PureBasic Road, BigTown, CodeCity")
  AddGadgetItem(0, -1, "Someone Else"+Chr(10)+"130 PureBasic Road, BigTown, CodeCity")
  ButtonGadget(1, 50, 118, 200, 25, "Change to random color")
  Repeat
    Event = WaitWindowEvent()
    If Event = #PB_Event_Gadget And EventGadget() = 1
      SetBackColorAndLines(0, RGB(Random(255), Random(255), Random(255)))
    EndIf
  Until Event = #PB_Event_CloseWindow
EndIf

Some examples of how the grid lines look from their automatic coloring:

Image
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Dynamically define highlight colour

Post by IdeasVacuum »

Nice work BarryG but it's not what I'm looking for 8) . Actually my mention of a ListView Gadget is one of many gadgets that can have highlighting on mouse hover/mouse over. So, when the mouse is over, the list row or StringGadget background colour is changed to the highlight colour and back to it's original colour when the mouse is not over it. Another example would be an HTML table.

Now, the changing of the background colour is straight forward, but the highlight colour must not "wash out" the text - this is what I want to calculate, the best highlight colour to work with the text colour and still be quite different to the existing background colour:

Image
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
ChrisR
Addict
Addict
Posts: 1127
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: Dynamically define highlight colour

Post by ChrisR »

Something like this, maybe, as a start point, to nuance with the background color
newRed = 255 - Red
newGreen = 255 - Green
newBlue = 255 - Blue
=>
newRed = 255 - (RedText + RedBack)/2
newGreen = 255 - (GreenText+ GreenBack)/2
newBlue = 255 - (BlueText+ BlueBack)/2

Or maybe with a Fade Color based on your BackGround Color

Code: Select all

Define R.i, G.i, B.i, FadeColor.i = $FF9933
R = Red(FadeColor)   * 0.2 + Red(BackGroundColor)   * 0.8
G = Green(FadeColor) * 0.2 + Green(BackGroundColor) * 0.8
B = Blue(FadeColor)  * 0.2 + Blue(BackGroundColor)  * 0.8
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: Dynamically define highlight colour

Post by BarryG »

IdeasVacuum, do not my calculations in my example give you a starting point, though? It shows how to make a new highlight colour blend in with a defined one. Just add or subtract to lighten or darken the highlight? Show us some code with a hover routine in it, and I'll see what I can do?
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Dynamically define highlight colour

Post by IdeasVacuum »

Hi Guys, I think ChrisR has absolutely nailed it with the fade colour idea :mrgreen:

Thanks for your help both.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: Dynamically define highlight colour

Post by RASHAD »

Hi

Code: Select all

Procedure SetBackColorAndLines(gad,color,percent)
  nred = Red(color) + percent:  If nred > 255 :nred = 255 : EndIf:  If nred < 0 : nred = 0 : EndIf
  ngreen = Green(color) + percent:  If ngreen > 255 :ngreen = 255 : EndIf:  If ngreen < 0 : ngreen = 0 : EndIf
  nblue = Blue(color) + percent:  If nblue > 255 :nblue = 255 : EndIf:  If nblue < 0 : nblue = 0 : EndIf
  ncolor = RGB(nred,ngreen,nblue)
  SetGadgetColor(gad,#PB_Gadget_BackColor,color)
  SetGadgetColor(gad,#PB_Gadget_LineColor,ncolor)
EndProcedure

If OpenWindow(0, 100, 100, 300, 150, "ListIcon Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ListIconGadget(0, 5, 5, 290, 105, "Name", 100, #PB_ListIcon_GridLines | #PB_ListIcon_AlwaysShowSelection)
  AddGadgetColumn(0, 1, "Address", 250)
  AddGadgetItem(0, -1, "Harry Rannit"+Chr(10)+"12 Parliament Way, Battle Street, By the Bay")
  AddGadgetItem(0, -1, "Ginger Brokeit"+Chr(10)+"130 PureBasic Road, BigTown, CodeCity")
  AddGadgetItem(0, -1, "Someone Else"+Chr(10)+"130 PureBasic Road, BigTown, CodeCity")
  ButtonGadget(1, 50, 118, 200, 25, "Change to random color")
  Repeat
    Event = WaitWindowEvent()
    If Event = #PB_Event_Gadget And EventGadget() = 1
      SetBackColorAndLines(0, RGB(Random(255), Random(255), Random(255)),25)
    EndIf
  Until Event = #PB_Event_CloseWindow
EndIf
Egypt my love
User avatar
ChrisR
Addict
Addict
Posts: 1127
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: Dynamically define highlight colour

Post by ChrisR »

Minor addition to the 2 previous examples, we can adjust the text color, white or black, depending on the perception of the background color, following the values (0.299, 0.587, 0.114), > 125 can be changed to a higher value

Code: Select all

Procedure SetBackColorAndLines(gad,color,percent)
  nred = Red(color) + percent:  If nred > 255 :nred = 255 : EndIf:  If nred < 0 : nred = 0 : EndIf
  ngreen = Green(color) + percent:  If ngreen > 255 :ngreen = 255 : EndIf:  If ngreen < 0 : ngreen = 0 : EndIf
  nblue = Blue(color) + percent:  If nblue > 255 :nblue = 255 : EndIf:  If nblue < 0 : nblue = 0 : EndIf
  ncolor = RGB(nred,ngreen,nblue)
  If (Red(color)*0.299 + Green(color)*0.587 + Blue(color)*0.114) > 125 : tcolor = #Black : Else : tcolor = #White :EndIf
  SetGadgetColor(gad,#PB_Gadget_BackColor,color)
  SetGadgetColor(gad,#PB_Gadget_FrontColor,tcolor)
  SetGadgetColor(gad,#PB_Gadget_LineColor,ncolor)
EndProcedure

If OpenWindow(0, 100, 100, 300, 150, "ListIcon Example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ListIconGadget(0, 5, 5, 290, 105, "Name", 100, #PB_ListIcon_GridLines | #PB_ListIcon_AlwaysShowSelection)
  AddGadgetColumn(0, 1, "Address", 250)
  AddGadgetItem(0, -1, "Harry Rannit"+Chr(10)+"12 Parliament Way, Battle Street, By the Bay")
  AddGadgetItem(0, -1, "Ginger Brokeit"+Chr(10)+"130 PureBasic Road, BigTown, CodeCity")
  AddGadgetItem(0, -1, "Someone Else"+Chr(10)+"130 PureBasic Road, BigTown, CodeCity")
  ButtonGadget(1, 50, 118, 200, 25, "Change to random color")
  Repeat
    Event = WaitWindowEvent()
    If Event = #PB_Event_Gadget And EventGadget() = 1
      SetBackColorAndLines(0, RGB(Random(255), Random(255), Random(255)),25)
    EndIf
  Until Event = #PB_Event_CloseWindow
EndIf
User avatar
kenmo
Addict
Addict
Posts: 1967
Joined: Tue Dec 23, 2003 3:54 am

Re: Dynamically define highlight colour

Post by kenmo »

You might be interested in this IncludeFile I put on GitHub, "OSTheme"
https://github.com/kenmo-pb/includes/bl ... STheme.pbi

You could use GetOSSelectionColor() and GetOSSelectionTextColor() to color the highlighted item,
or perhaps GetOSAccentColor() and do some color blending as already discussed.

And check out OSThemeBasicComplement(BackgroundColor) which returns either a dark or light text color to contrast with a given background color, using its weighted R/G/B brightness.
(basically the same as ChrisR's function above!)
BarryG
Addict
Addict
Posts: 3292
Joined: Thu Apr 18, 2019 8:17 am

Re: Dynamically define highlight colour

Post by BarryG »

Nice addition, ChrisR! Thank you.
User avatar
Demivec
Addict
Addict
Posts: 4086
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: Dynamically define highlight colour

Post by Demivec »

Here is a link to a slightly related topic that has to do with selecting an appropriate matching foreground/background color for text.
User avatar
ChrisR
Addict
Addict
Posts: 1127
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: Dynamically define highlight colour

Post by ChrisR »

Interesting subject, where we find the same values for the human perception of which I do not know the origin!
My source was on stackoverflow


Another example to show the difference between Fade Color and Accent Color
Fade Color is not really good when approaching the fade color, here $FF9933
Accent Color is not really good when approaching the white color by adding or the black color by subtracting

Code: Select all

EnableExplicit

Global Event, BackGroundColor.i, TextColor.i

Procedure FadeColor(Color.i, Percent.i)
  Protected R.i, G.i, B.i, FadeColor.i = $FF9933
  R = Red(FadeColor)   * Percent/100 + Red(Color)   * (100-Percent)/100
  G = Green(FadeColor) * Percent/100 + Green(Color) * (100-Percent)/100
  B = Blue(FadeColor)  * Percent/100 + Blue(Color)  * (100-Percent)/100
  ProcedureReturn RGB(R, G, B)
EndProcedure

Procedure AccentColor(Color.i, AddColorValue.i)
  Protected R.i, G.i, B.i
  R = Red(Color)   + AddColorValue : If R > 255 : R = 255 : EndIf : If R < 0 : R = 0 : EndIf
  G = Green(Color) + AddColorValue : If G > 255 : G = 255 : EndIf : If G < 0 : G = 0 : EndIf
  B = Blue(Color)  + AddColorValue : If B > 255 : B = 255 : EndIf : If B < 0 : B = 0 : EndIf
  ProcedureReturn RGB(R, G, B)
EndProcedure

Procedure IsDarkColor(Color.i)
  If Red(Color)*0.299 + Green(Color)*0.587 +Blue(Color)*0.114 < 128   ; Based on Human perception of color, following the RGB values (0.299, 0.587, 0.114)
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

If OpenWindow( 0, 0, 0, 240, 180, "Fade or Accent Color", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 30, 20, 180, 60)
  CanvasGadget(1, 30, 100, 180, 60)
  
  Repeat
    Event = WaitWindowEvent()
    Select EventGadget()
      Case 0, 1
        Select EventType()
          Case #PB_EventType_LeftClick, #PB_EventType_MouseEnter
            If EventType() = #PB_EventType_LeftClick
              BackGroundColor = RGB(Random(255), Random(255), Random(255))
              If IsDarkColor(BackGroundColor) : TextColor = #White : Else : TextColor = #Black : EndIf
            EndIf
            If StartDrawing(CanvasOutput(0))
              Box(0, 0, OutputWidth(), OutputHeight(), BackGroundColor)
              RoundBox(10, 10, OutputWidth()-20, OutputHeight()-20, 8, 8, FadeColor(BackGroundColor, 25))
              DrawingMode(#PB_2DDrawing_Transparent) : DrawText(55, 20, "Fade Color", TextColor)
              StopDrawing()
            EndIf
            If StartDrawing(CanvasOutput(1))
              Box(0, 0, OutputWidth(), OutputHeight(), BackGroundColor)
              RoundBox(10, 10, OutputWidth()-20, OutputHeight()-20, 8, 8, AccentColor(BackGroundColor, 25))
              DrawingMode(#PB_2DDrawing_Transparent) : DrawText(55, 20, "Accent Color", TextColor)
              StopDrawing()
            EndIf

            Case #PB_EventType_MouseLeave
              If StartDrawing(CanvasOutput(0))
                Box(0, 0, OutputWidth(), OutputHeight(), BackGroundColor)
                DrawingMode(#PB_2DDrawing_Transparent ) : DrawText(55, 20, "Fade Color", TextColor)
                StopDrawing()
              EndIf
              If StartDrawing(CanvasOutput(1))
                Box(0, 0, OutputWidth(), OutputHeight(), BackGroundColor)
                DrawingMode(#PB_2DDrawing_Transparent ) : DrawText(55, 20, "Accent Color", TextColor)
                StopDrawing()
              EndIf
              
          EndSelect
      EndSelect
    Until Event = #PB_Event_CloseWindow
EndIf
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Dynamically define highlight colour

Post by IdeasVacuum »

Hi Rashad, good to know you are still here 8)

Using random is not ideal because of the lack of control - some of the random colours just "wash out" the text.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
IdeasVacuum
Always Here
Always Here
Posts: 6425
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Dynamically define highlight colour

Post by IdeasVacuum »

Phew! Overwhelming response Guys! Thank you for this.

"we can adjust the text color" - ideally I do not want to do that. In the program, the User selects the Text Colour and the Background colour. From that, I expected to be able to apply the ideal highlight programmatically, but it's not as easy as I imagined. Of course, I could present the User with a preview so that they also choose the highlight colour. I guess that is the bullet-proof approach and I'm more inclined to take that route now as there doesn't seem to be a formula that can cover all bases :mrgreen:

On the other hand, the target Users are my age (old!) and many are not great at using software, which is why I wanted to make it as easy as possible. It's important that they can choose text colour and background colour because when your eyesight is deteriorating with age, you need maximum clarity. There isn't a one-size-fits all solution.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
Post Reply