Better ColorRequester()
Re: Better ColorRequester()
It is not 24 bit for RGB and 32 bit for RGBA? anyway long seems enough
#
It is probably best to open ChooseColor non-expanded by default, without #CC_FULLOPEN flag.
The Define Custom Color button is here to display the custom color controls, if needed.
Once expanded, the button is disabled and we can not go back to display it non-expanded.
#
It is probably best to open ChooseColor non-expanded by default, without #CC_FULLOPEN flag.
The Define Custom Color button is here to display the custom color controls, if needed.
Once expanded, the button is disabled and we can not go back to display it non-expanded.
- Kwai chang caine
- Always Here
- Posts: 5357
- Joined: Sun Nov 05, 2006 11:42 pm
- Location: Lyon - France
Re: Better ColorRequester()
Thanks at you two for sharing
The happiness is a road...
Not a destination
Not a destination
-
- Enthusiast
- Posts: 143
- Joined: Fri Mar 29, 2013 4:55 pm
- Location: The Netherland
Re: Better ColorRequester()
Thanks Chris,
Question:
How can I change the text of the title bar ?
Little_man
Question:
How can I change the text of the title bar ?
Little_man
Re: Better ColorRequester()
32 bits / 8 (Bits for 1 Byte) -> 4 BytesChrisR wrote:It is not 24 bit for RGB and 32 bit for RGBA?.
-
- Always Here
- Posts: 6425
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: Better ColorRequester()
How can the position of the FullColorRequester be set?
If my program is Screen Centred, the requester @ x0 y0 on a wide screen is miles away
If my program is Screen Centred, the requester @ x0 y0 on a wide screen is miles away
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: Better ColorRequester()
If you use the last code here, without the test at the bottom.
Edit: I added a parameter for the initial color selected and CompilerIf (#PB_Compiler_IsMainFile) for the exemple.
Just sends the X and Y position to FullColorRequester(InitialColor, X, Y). ex:
Edit: I added a parameter for the initial color selected and CompilerIf (#PB_Compiler_IsMainFile) for the exemple.
Just sends the X and Y position to FullColorRequester(InitialColor, X, Y). ex:
Code: Select all
Removed, see code 4 post below
Last edited by ChrisR on Thu Dec 08, 2022 4:30 pm, edited 1 time in total.
-
- Always Here
- Posts: 6425
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: Better ColorRequester()
Thanks ChrisR, I didn't study your update of the code
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
-
- Always Here
- Posts: 6425
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: Better ColorRequester()
[deleted]
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: Better ColorRequester()
Going through an extra window for the position is not really great because the main window is not locked. You can click on the buttons,... while the color requester is still open.
I found better for the position and optionally the requester backgound color, by using #CC_ENABLEHOOK in ChooseColor\flags.
I will publish tomorrow.
I found better for the position and optionally the requester backgound color, by using #CC_ENABLEHOOK in ChooseColor\flags.
I will publish tomorrow.
Re: Better ColorRequester()
FullColorRequester revision with its position and optionally the background color of the Requester.
See Usage in FullColorRequester.pb
A small demo is already included but if needed, here is another demo with the call from a window:
See Usage in FullColorRequester.pb
Code: Select all
;- Top
;============================================================================
; Author: blueb
; Date: May 8, 2017 - Rev. Dec 8, 2022
; Explain: Create a new ColorRequester that saves User Colors (between calls)
; Forum: http://www.purebasic.fr/english/viewtopic.php?f=12&t=68450
; Saved as: FullColorRequester.pb
; Addition: ChrisR: COLORREF array
; EnableHook for the ColorRequester Position and Set the ColorRequester Background Color.
; For Windows 10 and up, Buttons use the DarkMode_Explorer theme If the Background Color is Dark.
; ---------------------------------------------------------------------------
; Goal - write a 'Unique' preference file in the temporary directory that
; stays in the temporary directory even when user switches to other programs.
; It will keep the special colors the user last adjusted.
; ---------------------------------------------------------------------------
; msdn ChooseColor function: https://msdn.microsoft.com/en-us/library/windows/desktop/ms646912%28v=vs.85%29.aspx
;============================================================================
; Usage:
; FullColorRequester([Color = #PB_Default [, X = #PB_Default [, Y = #PB_Default [, BackColor = #PB_Default]]]])
;
; - Color : Default Color Selected
; | #PB_Default = No Color pre-selected
; - X, Y : Requester's position.
; | If Called from an active Window :
; | X, Y position inside the Window, scaling inside based on DPI
; | #PB_Default = Mouse position in the window's internal area.
; | Else
; | X, Y position, scaling inside based on DPI
; | #PB_Default = Desktop mouse position
; | EndIf
;
; - BackColor : Requester Background Color
; | #PB_Default = Default Background Color
;============================================================================
EnableExplicit
Declare IsDarkCColor(Color)
Declare CColorEnumChild(hWnd, lParam)
Declare ChooseColorProc(hWnd, uMsg, wParam, lParam)
Declare InitColorPrefs()
Declare ExitColorPrefs()
Declare FullColorRequester(Color = #PB_Default, X = #PB_Default, Y = #PB_Default, BackColor = #PB_Default)
Structure COLORREF
RGB.l[16]
EndStructure
; Structure CHOOSECOLOR ; see PB toolbox
; lStructSize.l
; hwndOwner.i
; hInstance.i
; rgbResult.l
; *lpCustColors
; Flags.l
; lCustData.i
; *lpfnHook
; *lpTemplateName
; EndStructure
; Needed for preferences file.
Global.i Dim COLORPREF(15)
Global CColorX, CColorY, CColorBackGround
Procedure IsDarkCColor(Color)
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
Procedure CColorEnumChild(hWnd, lParam)
Protected sClassName.s{64}
GetClassName_(hWnd, @sClassName, SizeOf(sClassName))
;Protected sText.s{1024} : GetWindowText_(hWnd, @sText, SizeOf(sText)) : Debug " CHILD: Class=" + sClassName + " - " + "Text=" + sText
If sClassName = "Button"
SetWindowTheme_(hWnd, "DarkMode_Explorer", 0)
EndIf
ProcedureReturn #True
EndProcedure
Procedure ChooseColorProc(hWnd, uMsg, wParam, lParam)
Protected DesktopRect.Rect, Rect.Rect
Static CColorBrush, CCFrontColor
Select uMsg
Case #WM_NCDESTROY
If CColorBackGround <> #PB_Default
DeleteObject_(CColorBrush)
EndIf
Case #WM_INITDIALOG
; Mini and Maxi position X, Y to stay in Desktop work area
SystemParametersInfo_(#SPI_GETWORKAREA, 0, @DesktopRect, 0)
GetWindowRect_(hWnd, Rect)
; X, Y > 0
If CColorX < DesktopRect\left : CColorX = DesktopRect\left : EndIf
If CColorY < DesktopRect\top : CColorY = DesktopRect\top : EndIf
; Positioned the other way, from the right and bottom side, if too large to fit in the desktop work area
If CColorX + (Rect\right - Rect\left) > (DesktopRect\right - DesktopRect\left) : CColorX - (Rect\right - Rect\left) : EndIf
If CColorY + (Rect\bottom - Rect\top) > (DesktopRect\bottom - DesktopRect\top) : CColorY - (Rect\bottom - Rect\top) : EndIf
; If X, Y are always too large, set the maximum position to stay in Desktop work area
If CColorX + (Rect\right - Rect\left) > (DesktopRect\right - DesktopRect\left) : CColorX = (DesktopRect\right - DesktopRect\left) - (Rect\right - Rect\left) : EndIf
If CColorY + (Rect\bottom - Rect\top) > (DesktopRect\bottom - DesktopRect\top) : CColorY = (DesktopRect\bottom - DesktopRect\top) - (Rect\bottom - Rect\top) : EndIf
SetWindowPos_(hWnd, #HWND_TOPMOST, CColorX, CColorY, 0, 0, #SWP_NOSIZE)
If CColorBackGround <> #PB_Default
CColorBrush = CreateSolidBrush_(CColorBackGround)
If IsDarkCColor(CColorBackGround)
CCFrontColor = #White
If OSVersion() >= #PB_OS_Windows_10
EnumChildWindows_(hWnd, @CColorEnumChild(), 0)
EndIf
Else
CCFrontColor = #Black
EndIf
EndIf
ProcedureReturn #False
Case #WM_CTLCOLORDLG, #WM_CTLCOLORSTATIC, #WM_CTLCOLOREDIT
If CColorBackGround <> #PB_Default
SetTextColor_(wParam, CCFrontColor)
SetBkMode_(wParam, #TRANSPARENT)
ProcedureReturn CColorBrush
EndIf
EndSelect
ProcedureReturn #False
EndProcedure
Procedure InitColorPrefs() ;Color Preference file - Storage information
Protected I.l
If OpenPreferences(GetTemporaryDirectory() + "GetUserColors.prefs") ;It exists, retrieve the GetUserColors.prefs information
For I = 0 To 15
COLORPREF(I) = ReadPreferenceInteger("COLORREF"+Str(I+1), COLORPREF(I))
Next
Else ; Does not exist, "GetUserColors.prefs" is erased. So create it with Default values
CreatePreferences(GetTemporaryDirectory() + "GetUserColors.prefs")
For I = 0 To 15
WritePreferenceInteger("COLORREF"+Str(I+1), COLORPREF(I))
Next
ClosePreferences()
EndIf
EndProcedure
Procedure ExitColorPrefs()
Protected I.i
If OpenPreferences(GetTemporaryDirectory() + "GetUserColors.prefs")
For I = 0 To 15
WritePreferenceInteger("COLORREF"+Str(I+1), COLORPREF(I))
Next
ClosePreferences()
EndIf
EndProcedure
Procedure FullColorRequester(Color = #PB_Default, X = #PB_Default, Y = #PB_Default, BackColor = #PB_Default) ;Place CHOOSECOLOR Info into requester()
Protected CHOOSECOLOR.CHOOSECOLOR, COLORREF.COLORREF, I
Protected hwnd = GetActiveWindow()
InitColorPrefs()
CColorBackGround = BackColor
;Place saved colors inside requester()
For I = 0 To 15
COLORREF\RGB[I] = COLORPREF(I)
Next
CHOOSECOLOR\LStructSize = SizeOf(CHOOSECOLOR)
If IsWindow(hwnd) ;Window Owner
CHOOSECOLOR\hwndOwner = WindowID(hwnd)
If X = #PB_Default
CColorX = DesktopScaledX(WindowX(hwnd, #PB_Window_InnerCoordinate)) + WindowMouseX(hwnd) ; WindowX() + Horizontal mouse position in the window's internal area
Else
CColorX = DesktopScaledX(WindowX(hwnd, #PB_Window_InnerCoordinate) + X) ; WindowX() + X value after scaling, based on Horizontal DPI
EndIf
If Y = #PB_Default
CColorY = DesktopScaledY(WindowY(hwnd, #PB_Window_InnerCoordinate)) + WindowMouseY(hwnd) ; WindowY() + Vertical mouse position in the window's internal area
Else
CColorY = DesktopScaledY(WindowY(hwnd, #PB_Window_InnerCoordinate) + Y) ; WindowY() + Y value after scaling, based on Horizontal DPI
EndIf
Else ;No Owner
CHOOSECOLOR\hwndOwner = 0
If X = #PB_Default
CColorX = DesktopMouseX() ; Absolute Horizontal position of the desktop mouse
Else
CColorX = DesktopScaledX(X) ; X value after scaling, based on Horizontal DPI
EndIf
If Y = #PB_Default
CColorY = DesktopMouseY() ; Absolute Y position of the desktop mouse
Else
CColorY = DesktopScaledY(Y) ; Y value after scaling, based on Vertical DPI
EndIf
EndIf
CHOOSECOLOR\rgbResult = Color ;Default color
CHOOSECOLOR\lpCustColors = COLORREF
CHOOSECOLOR\lpfnHook = @ChooseColorProc()
;CHOOSECOLOR\flags = #CC_ANYCOLOR | #CC_RGBINIT | #CC_ENABLEHOOK
CHOOSECOLOR\flags = #CC_FULLOPEN |#CC_ANYCOLOR | #CC_RGBINIT | #CC_ENABLEHOOK ;#CC_FULLOPEN to display the additional controls
If ChooseColor_(@CHOOSECOLOR)
For I = 0 To 15
COLORPREF(I) = COLORREF\RGB[I]
Next
ExitColorPrefs() ;Save info and Return Color Selected
ProcedureReturn CHOOSECOLOR\rgbResult
Else ;No color was selected
ExitColorPrefs() ;Save info and Return Default Color
ProcedureReturn #PB_Default
EndIf
EndProcedure
;- example
CompilerIf (#PB_Compiler_IsMainFile)
Macro DebugColor(_Color_)
If _Color_ = #PB_Default
Debug "Canceled by User or No Color Selected, Default Color (#PB_Default)"
Else
Debug "Color Selected: " + _Color_ +
" - Hex: " + "$" + RSet(Hex(Blue(_Color_)), 2, "0") + RSet(Hex(Green(_Color_)), 2, "0") + RSet(Hex(Red(_Color_)), 2, "0") +
" - RGB(" + Str(Red(_Color_)) + ", " + Str(Green(_Color_)) + ", " + Str(Blue(_Color_)) + ")"
EndIf
EndMacro
Define Color
Color = FullColorRequester() ; No color pre-selected, Desktop mouse position. No Background Color
DebugColor(Color)
Color = FullColorRequester($2C0408, 300, 200, $160204)
DebugColor(Color)
Color = FullColorRequester(Color, #PB_Default, #PB_Default, Color) ; Desktop mouse position (previous click on Close, OK or Cancel Button)
;Color = FullColorRequester(Color) ; Desktop mouse position (previous click on Close, OK or Cancel Button). No Background Color
DebugColor(Color)
Color = FullColorRequester(Color, -20, -20, Color)
DebugColor(Color)
Color = FullColorRequester(Color, 3840+20, 2160+20)
DebugColor(Color)
CompilerEndIf
A small demo is already included but if needed, here is another demo with the call from a window:
Code: Select all
EnableExplicit
Enumeration Window
#Window_0
EndEnumeration
Enumeration Gadgets
#Btn_Pick_Color
#Txt_Color
EndEnumeration
XIncludeFile "FullColorRequester.pb"
Procedure Resize_Window_0()
Protected.f ScaleX, ScaleY
Static Window_0_WidthIni, Window_0_HeightIni
If Window_0_WidthIni = 0
Window_0_WidthIni = WindowWidth(#Window_0) : Window_0_HeightIni = WindowHeight(#Window_0)
EndIf
ScaleX = WindowWidth(#Window_0) / Window_0_WidthIni : ScaleY = WindowHeight(#Window_0) / Window_0_HeightIni
ResizeGadget(#Btn_Pick_Color, ScaleX * 40, ScaleY * 40, ScaleX * (Window_0_WidthIni - 80), ScaleY * (Window_0_HeightIni - 90))
ResizeGadget(#Txt_Color, 10, WindowHeight(#Window_0) - 30, WindowWidth(#Window_0) - 20, #PB_Ignore)
EndProcedure
Procedure SetColor(Color)
SetWindowColor(#Window_0, Color)
SetGadgetText(#Txt_Color, "RGB(" + Str(Red(Color)) + ", " + Str(Green(Color)) + ", " + Str(Blue(Color)) + ")" +
" or $" + RSet(Hex(Blue(Color)), 2, "0") + RSet(Hex(Green(Color)), 2, "0") + RSet(Hex(Red(Color)), 2, "0"))
SetGadgetColor(#Txt_Color, #PB_Gadget_BackColor, Color)
If IsDarkCColor(Color) : SetGadgetColor(#Txt_Color, #PB_Gadget_FrontColor, #White) : Else : SetGadgetColor(#Txt_Color, #PB_Gadget_FrontColor, #Black) : EndIf
EndProcedure
Procedure Open_Window_0(X = 0, Y = 0, Width = 200, Height = 140)
If OpenWindow(#Window_0, X, Y, Width, Height, "Color", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
ButtonGadget(#Btn_Pick_Color, 40, 40, 120, 50, "Pick Color", #PB_Button_Default)
TextGadget(#Txt_Color, 10, 110, 180, 17, "", #PB_Text_Center)
BindEvent(#PB_Event_SizeWindow, @Resize_Window_0(), #Window_0)
PostEvent(#PB_Event_SizeWindow, #Window_0, 0)
EndIf
EndProcedure
CompilerIf (#PB_Compiler_IsMainFile)
Define Color = $160204
Open_Window_0()
SetColor(Color)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
Select EventGadget()
Case #Btn_Pick_Color
;- Exemple
;Color = FullColorRequester(Color, GadgetX(#Btn_Pick_Color) + GadgetWidth(#Btn_Pick_Color), GadgetY(#Btn_Pick_Color) + GadgetHeight(#Btn_Pick_Color), Color)
Color = FullColorRequester(Color, #PB_Default, #PB_Default, Color) ; Mouse position in the window's internal area
;Color = FullColorRequester(Color) ; Mouse position in the window's internal area. Default Background Color
;Color = FullColorRequester() ; No Color pre-selected. Mouse position in the window's internal area. Default Background Color
SetColor(Color)
EndSelect
EndSelect
ForEver
CompilerEndIf