corz.org text viewer..
[currently viewing: /public/machine/source/windows/color pickin chooser free.au3 - raw]
global $cpc_my_version = "1.8.1"
#cs

    corz color pickin chooser
    a color picker to use on your desktop, or in your AutoIt applications.

    for information, see here..

        http://corz.org/windows/software/color-pickin-chooser/

    have fun!

    ;o)

    If you are compiling this yourself, you need to use "AutoIt Wrapper"
    to add the extra icons. You will also need to use AT LEAST version
    1.9.3 of AutoIt Wrapper for the paths to work correctly. You can
    download it here..

        http://www.autoitscript.com/autoit3/scite/downloads.shtml

    © 2007-> Cor @ corz.org ;o)

#ce


 ; if you don't have these includes, go here..
 ; http://corz.org/engine?section=windows%2FAutoIt%20Includes

#include ".\Include\corz_essentials.au3"
#include ".\Include\corz_gui_fx.au3"
#include ".\Include\corz_colors.au3"
#include ".\Include\corz_tips.au3"


; Establish whether we are running stand-alone or included in some other app..
$cpc_stand_alone = true    ;distro

; or..
;
;if StringInStr(@ScriptName, "color pickin chooser") then $cpc_stand_alone = true
;
; Setting this up makes it a breeze to develop this and (your app) simultaneously.
; Running either, works. It also enables us to pull-off a few other tricks.
; The downside is that if you compile a "final" stand-alone version with the
; conditional code in-place, renaming color pickin chooser to something else
; would prevent it from running. It's for the development process, only.


; Constantinos..
;
##include <Constants.au3>
##include <GuiConstants.au3>
    ; it's no problem to delete all the constants below and simply uncomment the two constants file include lines (above)

    ; these constants are unique to the color pickin chooser..
    const $CC_ANYCOLOR = 0x100
    const $CC_FULLOPEN = 0x2
    const $CC_RGBINIT = 0x1

    const $TRAY_CHECKED = 1
    const $TRAY_UNCHECKED = 4

    const $BS_AUTOCHECKBOX = 0x0003
    const $BS_ICON = 0x0040

    const $WS_TABSTOP = 0x00010000
    const $WS_MINIMIZEBOX = 0x00020000
    const $WS_SYSMENU = 0x00080000
    const $WS_SIZEBOX = 0x00040000

    const $ES_MULTILINE = 4

    const $SS_SUNKEN    = 0x1000
    const $SS_LEFTNOWORDWRAP    = 12

    const $GUI_BKCOLOR_TRANSPARENT = -2
    const $GUI_WS_EX_PARENTDRAG = 0x00100000
    const $GUI_DOCKBORDERS = 0x0066
    const $GUI_DOCKLEFT = 0x0002
    const $GUI_DOCKRIGHT = 0x0004
    const $GUI_DOCKBOTTOM = 0x0040
    const $GUI_DOCKWIDTH = 0x0100
    const $GUI_DOCKHEIGHT = 0x0200
    const $GUI_DEFBUTTON = 512
    const $GUI_ONTOP            = 2048

    ; these constants are also in the master app (e.g. clock)..
    ; (we only load them when running in stand-alone mode)
    ; if your app doesn't declare any of these.. you will need
    ; to move those constants to the "unique" section above.
    if $cpc_stand_alone then
        const $TRAY_EVENT_PRIMARYDOWN = -7

        const $GUI_EVENT_CLOSE = -3
        const $GUI_EVENT_DROPPED = -13
        const $GUI_CHECKED = 1
        const $GUI_UNCHECKED = 4
        const $GUI_DROPACCEPTED = 8
        const $GUI_FOCUS = 256

        const $CBS_DROPDOWN = 0x0002
        const $CBS_AUTOHSCROLL = 0x0040
        const $CBS_SORT = 0x0100

        const $ES_NUMBER = 8192

        const $WS_VSCROLL = 0x00200000
        const $WS_CAPTION = 0x00C00000
        const $WS_MINIMIZE = 0x20000000
        const $WS_POPUP = 0x80000000
        const $WS_EX_ACCEPTFILES = 0x00000010
        const $WS_EX_TOOLWINDOW = 0x00000080
        const $WS_EX_TOPMOST = 0x00000008

        const $SS_NOTIFY    = 0x0100

        const $BS_CENTER = 0x0300
        const $BS_VCENTER = 0x0C00
        const $BS_PUSHLIKE = 0x1000

        const $TBS_NOTICKS = 0x0010
    endif

; so, we are on our own..
if $cpc_stand_alone then
    ce_Singleton("ColorPickinChooser")
    ColorPickinChooser()
    exit
endif


; main function..
;
func ColorPickinChooser($set_color=""$scheme=""$autoit_val=false, $func="")

    ; initialize variables and GUI
    cpc_Setup()

    cpc_InitColorWells()

    if $scheme <> "" then
        if InArray($group_names$scheme) then
            $cpc_my_group = $scheme
            GUICtrlSetData($combo_custom_groups$cpc_my_group)
            cpc_LoadColorGroup()
        endif
    endif

    if $set_color <> "" then
        if StringLen($set_color) <> 6 then $set_color = StringRight($set_color, 6)
        $cpc_my_color = $set_color
    endif

    global $do_func = $func

    cpc_UpdateImageContextMenu()
    cpc_SwitchImage($cpc_picker_image)

    ; get the colors ready..
    cpc_UpdateHexOutput($cpc_my_color)
    cpc_AddHex()
    cpc_SetColor(true) ; true for first run

    local $last_event_mode = AutoItSetOption("GUIOnEventMode", 1)
    local $last_traymenu_mode = AutoItSetOption("TrayMenuMode", 1)
    local $last_trayonevent_mode = AutoItSetOption("TrayOnEventMode", 1)

    ; show the gui..
    corz_GUIAnimateOpen($gui_color$cpc_gui_fx)

    cpc_ToggleOnTopWin(true)
    cpc_ToggleOnTopWin(true)

    cpc_ToggleLiveTitleBar(true)
    cpc_ToggleLiveTitleBar(true)

    if $cpc_stand_alone then
        cpc_ToggleDoneQuits(true)
        cpc_ToggleDoneQuits(true)
    endif

    cpc_LoadMag()

    GUICtrlSetState($combo_custom_groups$GUI_FOCUS)

    $color_set = 0
    global $do_quit = false
    global $cpc_killed = false
    global $super_mag = false
    $left_window = false

    ; tricks and tips..
    if $cpc_no_tips = $GUI_UNCHECKED or ce_IsPressed(10) then
        cpc_HotKeyShowTips()
    endif


    ; main loop..
    ;
    while not $do_quit

        if $do_func <> "" then
            Call($do_func)
        endif

        sleep(75)
        local $mouse_info = GUIGetCursorInfo() ; help file page for this command needs a decent hover example!
        ; in fact, *any* decent examples would be good.

        if $mouse_info = 0 then
            $left_window = true
            cpc_UnSetHotKeys()
        else
            cpc_SetHotKeys()
            if $super_mag and $left_window = true then ; back inside the gui
                cpc_SwitchOffSuperMag()
            endif
            $left_window = false
        endif

        if not IsArray($mouse_info) then continueloop ; outside gui
        local $MousePos = MouseGetPos()
        if not IsArray($MousePos) then continueloop

        ; inside picker, grad, or mag (or dragable info label)..
        if $mouse_info[4] = $pic_color_picker or $mouse_info[4] >= $info_dummy then
            if $mouse_info[4] = $info_dummy or $mouse_info[4] = $label_colorwell then
                GUISetCursor(9, 1, $gui_color)    ; feel free to use something like this for the GUIGetCursorInfo() manual page.
                continueloop                    ; no credit required! ;o)
            endif

            GUISetCursor(3, 1, $gui_color"+"
            $cpc_live_color = StringRight(Hex(PixelGetColor($MousePos[0],$MousePos[1])), 6)
            cpc_UpdateLiveColorBox()

            ; hold down left mouse button for live effects..
            if $live_luminance = $GUI_CHECKED or ce_IsPressed(01) then cpc_UpdateLumGrad($cpc_live_color)
            if $live_mag = $GUI_CHECKED or ce_IsPressed(01) then cpc_UpdateMag()

            if $live_hex = $GUI_CHECKED then
                if ce_IsPressed(10) then
                    ToolTip(ConvertColorValue($cpc_live_color$cpc_output_mode$add_prefix), $MousePos[0]+2, $MousePos[1]+2)
                else
                    ToolTip($cpc_live_color$MousePos[0]+2, $MousePos[1]+2)
                endif
            endif
            $color_set = 1

        elseif $super_mag then

            cpc_UpdateMag()
            GUISetCursor(3, 1, $gui_color)

        else ; outside picker areas or window..

            GUISetCursor()
            ToolTip ("")
            if $color_set = 1 then
                if $hold_live_color = $GUI_UNCHECKED then
                    GUICtrlSetBkColor($label_live_color"0x" & $cpc_my_color)
                    if $live_luminance = $GUI_CHECKED then cpc_UpdateLumGrad($cpc_my_color)
                endif
                $color_set = 0
            endif
        endif
    wend

    ; all done..
    cpc_KillWindow()

    AutoItSetOption("GUIOnEventMode"$last_event_mode)
    AutoItSetOption("TrayMenuMode"$last_traymenu_mode)
    AutoItSetOption("TrayOnEventMode"$last_trayonevent_mode)

    $return_val = $cpc_my_color

    ; nothing changed, return the original color..
    if $cpc_killed then $return_val = $set_color

    if $autoit_val then
        return '0x' & $return_val
    else
        return $return_val
    endif
endfunc


; initial setup..
;
func cpc_Setup()

    global $cpc_my_name = "color pickin chooser"
    global $cpc_data_parent = @AppDataDir & "\corz\" & $cpc_my_name

    global $cpc_ini_path = $cpc_data_parent & "\" & $cpc_my_name & ".ini"
    global $colors_ini_path = $cpc_data_parent & "\custom colors.ini"

    global $default_picker_img_dir = $cpc_data_parent & "\picker images"
    global $picker_img_dir = IniRead($cpc_ini_path$cpc_my_name"picker_images_folder"$default_picker_img_dir)

    global $previous_combo_groups[501] = [500] ; for storing previous combobox selections
    global $ini_process = false
    global $group_process = false
    global $no_colorwells = 64 ; it won't do anything good if you change this (at least, not yet)

    global $sort_flags[11] = [10]

    if not FileExists($picker_img_dir) then DirCreate($picker_img_dir)
    ; install sample images..
    if $picker_img_dir = $default_picker_img_dir then cpc_InstallSampleImages()

    ; tips setup..
    global $tips_file = $cpc_data_parent & "\tips.txt"
    ;if StringInStr(@OSVersion, 'VISTA') then global $tips_file = @TempDir & "\color-pickin-tips.txt" ; not required
    FileInstall(".\stuff\tips.txt"$tips_file, 0)
    global $cpc_no_tips = IniReadCheckboxValue($cpc_ini_path$cpc_my_name"no_tips"$GUI_UNCHECKED)

    global $cpc_live_color$red_index$green_index$blue_index
    global $cpc_my_color = IniRead($cpc_ini_path$cpc_my_name"my_color""FF50A3")
    global $cpc_my_group = IniRead($cpc_ini_path$cpc_my_name"my_group""empty")
    global $current_group_index$cpc_previous_mode
    global $cpc_picker_image = IniRead($cpc_ini_path$cpc_my_name"picker_image"$picker_img_dir & "\Spectrums\Spectrum.jpg")
    global $cpc_last_mag = IniRead($cpc_ini_path$cpc_my_name"last_mag""0|0")

    global $live_luminance = IniReadCheckboxValue($cpc_ini_path$cpc_my_name"live_luminance"$GUI_UNCHECKED)
    global $live_hex = IniReadCheckboxValue($cpc_ini_path$cpc_my_name"live_hex"$GUI_UNCHECKED)
    global $live_mag = IniReadCheckboxValue($cpc_ini_path$cpc_my_name"live_mag"$GUI_UNCHECKED)
    global $hold_live_color = IniReadCheckboxValue($cpc_ini_path$cpc_my_name"hold_live_color"$GUI_UNCHECKED)

    global $cpc_auto_copy = IniReadCheckboxValue($cpc_ini_path$cpc_my_name"auto_copy"$GUI_UNCHECKED)
    global $cpc_on_top = IniReadCheckboxValue($cpc_ini_path$cpc_my_name"always_on_top"$GUI_CHECKED)
    global $cpc_live_titlebar = IniReadCheckboxValue($cpc_ini_path$cpc_my_name"colors_in_titlebar"$GUI_UNCHECKED)

    global $cpc_output_mode = IniRead($cpc_ini_path$cpc_my_name"output_mode""Web Hex")
    global $cpc_output_modes[9] = [    "Web Hex", _        ; You can change the menu order by changing the order here.
                                    "Autoit RGB Hex", _    ; You can also disable any options you don't want to use.
                                    "Autoit BGR Hex", _    ; If you do, don't forget to alter the total (currently 9).
                                    "Visual C++ Hex", _ ; The full text of the items is important; if you want to
                                    "Delphi Hex", _        ; alter any items, check/hack ConvertColorValue() first.
                                    "RGB Integer", _
                                    "RGB Float", _
                                    "HSL", _
                                    "CMYK" ]
    global $cpc_menu_output_modes[uBound($cpc_output_modes)]
    global $add_prefix = IniReadCheckBoxValue($cpc_ini_path$cpc_my_name"add_prefix"$GUI_UNCHECKED)

    global $gui_fx = IniRead($cpc_ini_path$cpc_my_name"gui_fx""Slide Right")
    global $cpc_gui_fx = corz_GUIGetFX($gui_fx$cpc_ini_path$cpc_my_name)

    global $done_quits = IniReadCheckboxValue($cpc_ini_path$cpc_my_name"done_quits"$GUI_UNCHECKED)
    global $dont_pop_up_comments = IniReadCheckBoxValue($cpc_ini_path$cpc_my_name"dont_pop_up_comments"$GUI_UNCHECKED)

    global $cpc_width = 395
    global $cpc_height = 215
    global $cpc_x = IniRead($cpc_ini_path$cpc_my_name"x", @DesktopWidth-$cpc_width-16)    ; not -1. we need a real number
    global $cpc_y = IniRead($cpc_ini_path$cpc_my_name"y",  26)                            ; for later calculations

    global $cpc_picker_size = 150
    global $cpc_mag_top = $cpc_picker_size + 10

    global $cpc_lum_width = 16
    global $cpc_lum_height = $cpc_picker_size
    global $cpc_grad_step = $cpc_lum_height / 2

    global $cpc_uncheck_img_idx
    global $cpc_current_img_idx

    cpc_MakeGUI()
endfunc


; create the main gui and controls..
;
func cpc_MakeGUI()

    ; the main gui..
    ;
    local $last_coord_mode = AutoItSetOption("GUICoordMode", 0)

    global $dummy_container = GUICreate(-1,-1,-1,-1,-1, $WS_EX_TOOLWINDOW; no taskbar entry required
    global $gui_color = GUICreate($cpc_my_name & ".."$cpc_width , $cpc_height , $cpc_x , $cpc_y, _
            BitOr($WS_CAPTION$WS_POPUP$WS_SYSMENU), $WS_EX_ACCEPTFILES$dummy_container)

    if not $cpc_stand_alone then GuiSetIcon(@ScriptFullPath, 6) ; set correct icon (see #compile section @ foot)

    ; GUI Events..
    GUISetOnEvent($GUI_EVENT_CLOSE"cpc_ExitDoQuit"$gui_color)
    GUISetOnEvent($GUI_EVENT_DROPPED"cpc_GetDroppedItem"$gui_color)

    global $pic_color_picker = GUICtrlCreatePic("", 6, 6, $cpc_picker_size , $cpc_picker_size)
    GUICtrlSetOnEvent(-1, "cpc_ClickMouseSetColor")
    GUICtrlSetState(-1, $GUI_DROPACCEPTED)


    ; live toggles..
    global $check_lumlive = GUICtrlCreateCheckbox(""$cpc_picker_size+5, $cpc_lum_height+5, 15, 15, _
                        BitOr($BS_AUTOCHECKBOX$BS_PUSHLIKE$BS_ICON$BS_VCENTER$BS_CENTER))
    GUICtrlSetOnEvent(-1, "cpc_ToggleLiveLum")
    GUICtrlSetTip(-1, " click this switch to toggle the live luminance gradient  [F5]")
    GUICtrlSetState(-1, $live_luminance)
    if @compiled then
        GUICtrlSetImage(-1, @ScriptFullPath, -4, 0)
    else
        GUICtrlSetImage(-1, ".\img\icons\grad.ico", -1, 0)
    endif


    global $check_maglive = GUICtrlCreateCheckbox("", 0, 17, 15, 15, _
        BitOr($BS_AUTOCHECKBOX$BS_PUSHLIKE$BS_ICON$BS_VCENTER$BS_CENTER))
    GUICtrlSetOnEvent(-1, "cpc_ToggleLiveMag")
    GUICtrlSetTip(-1, " click this switch to toggle the live magnifier (it will revert once you select an area)  [F6] " _
            & @CRLF & " [ shift-click for super-mag ] ")
    GUICtrlSetState(-1, $live_mag)
    if @compiled then
        GUICtrlSetImage(-1, @ScriptFullPath, -5, 0)
    else
        GUICtrlSetImage(-1, ".\img\icons\mag.ico", -1, 0)
    endif


    global $check_hexlive = GUICtrlCreateCheckbox("#", 0, 17, 15, 15, _
        BitOr($BS_AUTOCHECKBOX$BS_PUSHLIKE$BS_ICON$BS_VCENTER$BS_CENTER))
    GUICtrlSetOnEvent(-1, "cpc_ToggleLiveHex")
    GUICtrlSetTip(-1, " click this switch to toggle the live hex color readout tip  [F7] " & @CRLF & _
                        " while running, hold down the SHIFT key to see the converted output")
    GUICtrlSetState(-1, $live_hex)
    if @compiled then
        GUICtrlSetImage(-1, @ScriptFullPath, -6, 0)
    else
        GUICtrlSetImage(-1, ".\img\icons\hex.ico", -1, 0)
    endif


    GUISetCoord(5, $cpc_mag_top)
    global $label_live_color = GUICtrlCreateLabel(""$cpc_picker_size/3, 0, $cpc_picker_size/3, $cpc_picker_size/3)
    GUICtrlSetOnEvent(-1, "cpc_ToggleLiveColorHold")
    GUICtrlSetTip(-1, " this is the current live color " & @CRLF & _
                      " [as well as a readout, you can click it to toggle the live color hold] ")

    global $label_my_color = GUICtrlCreateLabel(""$cpc_picker_size/3, 0, $cpc_picker_size/3, $cpc_picker_size/3)
    GUICtrlSetOnEvent(-1, "cpc_AddMyColor")
    GUICtrlSetTip(-1, " your currently selected color, aka 'my color' " & @CRLF & _
                      " [click this box (or press F2) to add this color to the end of your current color group] ")


    GUISetCoord(184, 10)

    global $cpc_label_red = GUICtrlCreateLabel("Red: ", 0, 3, 32, 20, -1, $GUI_WS_EX_PARENTDRAG)
    global $cpc_input_red = GUICtrlCreateInput(" ", 40, -4, 32, 20, $ES_NUMBER)
    GUICtrlSetOnEvent(-1, "cpc_AddRed")
    GUICtrlSetTip(-1, " red input/output. here you can enter a decimal value for red (0-255) ")

    global $cpc_label_green = GUICtrlCreateLabel("Green: ", -40, 47, 32, 20, -1, $GUI_WS_EX_PARENTDRAG)
    global $cpc_input_green = GUICtrlCreateInput(" ", 40, -4, 32, 20, $ES_NUMBER)
    GUICtrlSetOnEvent(-1, "cpc_AddGreen")
    GUICtrlSetTip(-1, " green input/output. here you can enter a decimal value for green (0-255) ")

    global $cpc_label_blue = GUICtrlCreateLabel("Blue: ", -40, 47, 32, 20, -1, $GUI_WS_EX_PARENTDRAG)
    global $cpc_input_blue = GUICtrlCreateInput(" ", 40, -4, 32, 20, $ES_NUMBER)
    GUICtrlSetOnEvent(-1, "cpc_AddBlue")
    GUICtrlSetTip(-1, " blue input/output. here you can enter a decimal value for blue (0-255) ")


    global $cpc_slider_red = GUICtrlCreateSlider( -40, -65, 85 , 20 , BitOr($TBS_NOTICKS$WS_TABSTOP))
    GUICtrlSetOnEvent(-1, "cpc_SlideRed")
    GUICtrlSetLimit (-1, 255, 0)
    GUICtrlSetTip(-1, " red slider. slide it up and down to chage the red value (0-255) ")

    global $cpc_slider_green = GUICtrlCreateSlider( 0, 43, 85 , 20 , BitOr($TBS_NOTICKS$WS_TABSTOP))
    GUICtrlSetOnEvent(-1, "cpc_Slidegreen")
    GUICtrlSetLimit (-1, 255, 0)
    GUICtrlSetTip(-1, " green slider. sliding it chages the green value (0-255) ")

    global $cpc_slider_blue = GUICtrlCreateSlider( 0, 43, 85 , 20 , BitOr($TBS_NOTICKS$WS_TABSTOP))
    GUICtrlSetOnEvent(-1, "cpc_Slideblue")
    GUICtrlSetLimit (-1, 255, 0)
    GUICtrlSetTip(-1, " blue slider. give it a slide to chage the blue value (0-255) ")


    global $label_hex_in_out = GUICtrlCreateLabel("Hex: ", 0, 28, 32, 20, -1, $GUI_WS_EX_PARENTDRAG)
    GUICtrlSetTip(-1, " current output: " & ConvertColorValue($cpc_my_color$cpc_output_mode$add_prefix) _
            & @CRLF & " right-click me for a menu of various clipboard output formats ")
    global $input_hex_in_out = GUICtrlCreateInput("", 27, -3, 53, 20)
    GUICtrlSetOnEvent(-1, "cpc_AddHex")
    GUICtrlSetData(-1, $cpc_my_color)
    GUICtrlSetTip(-1, " RGB hex input/output. here you can enter a standard RGB hex color value, eg. 'FF00FF' " & @CRLF & _
                      " (note: you can copy to the clipboard in a number of formats; right-click the 'Hex' label to choose) ")


    global $check_autocopy = GUICtrlCreateCheckbox("auto", -27, 24, 28, 19, _
        BitOr($BS_AUTOCHECKBOX$BS_PUSHLIKE$BS_VCENTER$BS_CENTER))
    GUICtrlSetOnEvent(-1, "cpc_ToggleAutoCopy")
    GUICtrlSetTip(-1, " click this switch to automatically copy the " & $cpc_output_mode & " value of all selected colors to the clipboard, or not  [F3] ")
    GUICtrlSetState(-1, $cpc_auto_copy)

    global $check_special_clip_copy = GUICtrlCreateCheckbox("copy hex", 28, 0, 50, 19, _
                                        BitOr($BS_AUTOCHECKBOX$BS_PUSHLIKE$BS_VCENTER$BS_CENTER))
    GUICtrlSetOnEvent(-1, "cpc_ButtCopyColor")
    GUICtrlSetTip(-1, " click this button to copy the " & $cpc_output_mode &" value to the clipboard  [F4] ")
    if $cpc_auto_copy = $GUI_CHECKED then GUICtrlSetState(-1, $GUI_CHECKED)


    ; all done..
    GUISetCoord($cpc_width-44, $cpc_height-25)
    $butt_all_done = GUICtrlCreateButton( "&done!", 0, 0, 40, 20 )
    GUICtrlSetOnEvent(-1, "cpc_Done")



    GUISetCoord(269, 8)

    ; we'll duplicate the context menu on these three controls..
    global $combo_custom_groups = GUICtrlCreateCombo( "", 0, 0, 86, 18, BitOR($CBS_SORT$CBS_DROPDOWN$CBS_AUTOHSCROLL$WS_VSCROLL))
    GUICtrlSetOnEvent(-1, "cpc_LoadColorGroup")
    GUICtrlSetState(-1, $GUI_DROPACCEPTED)
    GUICtrlSetTip(-1, " your color groups " & @CRLF & _
        " you can drag palettes and ini files (even folders of ini files) into here (and the picker image) to import their colors ")

    global $butt_delete_group = GUICtrlCreateButton("-", 88, 1, 16, 18)
    GUICtrlSetOnEvent(-1, "cpc_DeleteColorGroup")
    GUICtrlSetTip(-1, " remove this color group ")
    GUICtrlSetFont(-1, Default , 800)

    global $butt_add_group = GUICtrlCreateButton("+", 18, 0, 16, 18)
    GUICtrlSetOnEvent(-1, "cpc_AddColorGroup")
    GUICtrlSetTip(-1, " add a new color group ")


    ; color wells..
    ;

    GUISetCoord(374, 17)
    global $custom_color_box[$no_colorwells+1] = [$no_colorwells; 1-64 (0 is total)
    $box = 1
    for $i = 1 to 8 ; eight main rows, we'll make a grid
        ; need $*CHECKBOX to get colors on pushlike radio buttons
        ;$custom_color_box[$box] = GUICtrlCreateRadio("", -105, 16, 16, 17, BitOr($BS_AUTOCHECKBOX$BS_PUSHLIKE)) ; first box
        $custom_color_box[$box] = GUICtrlCreateLabel("", -105, 16, 16, 17, BitOr($SS_NOTIFY$SS_SUNKEN))
        GUICtrlSetOnEvent(-1, "cpc_SelectColorWell"; labels also work fine (and look *much* better in XP style - which I
        GUICtrlSetBkColor(-1, Default)                 ; don't use) but you can't see the (almost invisible) checkbox selections.
        $box += 1                                     ; Feck it, labels it is! I'll add some other kind of visual feedback.
        for $t = 1 to 7 ; the other seven boxes..
            $custom_color_box[$box] = GUICtrlCreateLabel("", 15, 0, 16, 17, BitOr($SS_NOTIFY$SS_SUNKEN))
            GUICtrlSetOnEvent(-1, "cpc_SelectColorWell")
            GUICtrlSetBkColor(-1, Default)
            $box += 1
        next
    next

    global $input_color_name = GUICtrlCreateInput("", -106, 20, 122, 20)
    GUICtrlSetTip(-1, " the color name input. enter something here to save a color by that name. " & @CRLF & _
                      " to rename a color: click it, type a new name, click it again (or hit F2/Enter) ")


    ; information area (dragable)
    ;
    global $info_dummy = GUICtrlCreateLabel("", -83, 21, 164, 30, -1, $GUI_WS_EX_PARENTDRAG)
    global $label_colorwell = GUICtrlCreateLabel("", 0, 9, 164, 15, $SS_LEFTNOWORDWRAP$GUI_WS_EX_PARENTDRAG)
    GUICtrlSetTip(-1, " information appears here. you can click and drag the window around from here, too ")
    GUICtrlSetFont(-1, 7, 200)



    ; magnifier (Cheers to CodeMaster Rapture)
    ;
    AutoItSetOption("GUICoordMode", 1)
    $count = 0
    global $mag_x = 5
    $mag_size = 5
    global $mag_block[200] ; yeah, we only need 100, but still. try it.
    global $mag_save_blocks[200] = [100]

    for $iterX = 0 to 49 step $mag_size
        for $iterY = 0 to 49 step $mag_size
            $mag_block[$count] = GUICtrlCreateLabel(""$iterX+$mag_x$iterY+$cpc_mag_top$mag_size$mag_size)
            GUICtrlSetOnEvent(-1, "cpc_ClickMouseSetColor"; otherwise first click on mag doesn't stick
            GUICtrlSetBkColor(-1, Default)
            GUICtrlSetTip(-1, "the magnifier area, aka. 'mag box'. you can magnify this, too ")
            $count += 1
        next
    next

    ; a new style luminance gradient..
    ;
    global $grad_bars[151] = [150]
    for $bar = 1 to 150
        $grad_bars[$bar] = GuiCtrlCreateLabel(""$cpc_picker_size+10, 4 + $bar$cpc_lum_width, 1)
        GUICtrlSetOnEvent(-1, "cpc_ClickMouseSetColor")
    next


    ; end of visible gui controls



    ; context menus..
    ;
    global $cpc_MenuHex = GUICtrlCreateContextMenu($label_hex_in_out)
    GUICtrlCreateMenuitem("Clipboard Copy Modes.."$cpc_MenuHex)
    GUICtrlCreateMenuitem(""$cpc_MenuHex)

        for $i = 0 to uBound($cpc_output_modes)-1
            $cpc_menu_output_modes[$i] = GUICtrlCreateMenuitem($cpc_output_modes[$i], $cpc_MenuHex)
            GUICtrlSetOnEvent(-1, "cpc_SwitchMode")
            if $cpc_output_modes[$i] = $cpc_output_mode then
                GUICtrlSetState($cpc_menu_output_modes[$i], $GUI_CHECKED)
                $cpc_previous_mode = $i
            endif
        next
    GUICtrlCreateMenuitem(""$cpc_MenuHex)
    global $menu_hex_prefix = GUICtrlCreateMenuitem("Add Prefix"$cpc_MenuHex)
    GUICtrlSetOnEvent(-1, "cpc_MenuTogglePrefix")
    GUICtrlSetState(-1, $add_prefix)

    ; three identical context menus..
    for $i = $combo_custom_groups to $butt_add_group
        GUICtrlCreateContextMenu($i)
        GUICtrlCreateMenuitem("Export Color Group.."$i)
        GUICtrlSetOnEvent(-1, "cpc_ExportGroup")
        GUICtrlCreateMenuitem("Export Gimp Palette.."$i)
        GUICtrlSetOnEvent(-1, "cpc_ExportGimpPalette")
        GUICtrlCreateMenuitem("Export JASC Palette.."$i)
        GUICtrlSetOnEvent(-1, "cpc_ExportJASCPalette")
        GUICtrlCreateMenuitem(""$i)

        GUICtrlCreateMenuitem("Sort Colors by Name..    Ctrl + KeyPad 0"$i)
        GUICtrlSetOnEvent(-1, "cpc_MenuSortColorsName")
        GUICtrlCreateMenuitem(""$i)

        GUICtrlCreateMenuitem("Sort Colors by Red..    Ctrl + KeyPad 1"$i)
        GUICtrlSetOnEvent(-1, "cpc_MenuSortColorsRed")
        GUICtrlCreateMenuitem("Sort Colors by Green..    Ctrl + KeyPad 2"$i)
        GUICtrlSetOnEvent(-1, "cpc_MenuSortColorsGreen")
        GUICtrlCreateMenuitem("Sort Colors by Blue..    Ctrl + KeyPad 3"$i)
        GUICtrlSetOnEvent(-1, "cpc_MenuSortColorsBlue")
        GUICtrlCreateMenuitem(""$i)

        GUICtrlCreateMenuitem("Sort Colors by Hue..    Ctrl + KeyPad 4"$i)
        GUICtrlSetOnEvent(-1, "cpc_MenuSortColorsHue")
        GUICtrlCreateMenuitem("Sort Colors by Saturation..    Ctrl + KeyPad 5"$i)
        GUICtrlSetOnEvent(-1, "cpc_MenuSortColorsSat")
        GUICtrlCreateMenuitem("Sort Colors by Lightness..    Ctrl + KeyPad 6"$i)
        GUICtrlSetOnEvent(-1, "cpc_MenuSortColorsLum")

        GUICtrlCreateMenuitem(""$i)
        GUICtrlCreateMenuitem("Group notes and comments..    Alt+C"$i)
        GUICtrlSetOnEvent(-1, "cpc_MenuGroupComments")
    next

    ; picker image menu built and re-built later.
    global $cpc_MenuColorPicker = GUICtrlCreateContextMenu($pic_color_picker)


    ; system tray..
    ; only for stand-alone mode
    ;
    if $cpc_stand_alone then
        $TrayItemAbout = TrayCreateItem("About color pickin chooser..")
        TrayItemSetOnEvent(-1, "cpc_DoAbout")


        global $TrayItemDoneQuits= TrayCreateItem("Tips and Tricks..    F1", -1)
        TrayItemSetOnEvent(-1, "cpc_HotKeyShowTips")

        TrayCreateItem("")

        global $TrayItemOpenDataFolder = TrayCreateItem("Open data folder..    F10")
        TrayItemSetOnEvent(-1, "cpc_OpenDataFolder")

        TrayCreateItem("")

        global $TrayItemToggleOnTop= TrayCreateItem("Always on top")
        TrayItemSetOnEvent(-1, "cpc_MenuToggleOnTopWin")
        GUICtrlSetState(-1, $cpc_on_top)

        global $TrayItemLiveTitleBar= TrayCreateItem("Color output in title bar")
        TrayItemSetOnEvent(-1, "cpc_MenuToggleLiveTitleBar")
        GUICtrlSetState(-1, $cpc_live_titlebar)

        TrayCreateItem("")
        global $TrayMenuWinAnim = TrayCreateMenu("Window animation..")
        local $win_anims[11] = ["Slide Left""Slide Right""Slide Top""Slide Bottom", _
                                "Slide Top Left""Slide Top Right""Slide Bottom Right""Slide Bottom Left", _
                                "Explode/Implode""Fade""Disable window animation"]
        global $menu_items_win_anim[11]
        for $i = 0 to 10
            $menu_items_win_anim[$i] = TrayCreateItem($win_anims[$i], $TrayMenuWinAnim, -1, 1)
            TrayItemSetOnEvent(-1, "cpc_MenuSetWinAnim")
        next
        for $i in $menu_items_win_anim
            if TrayItemGetText($i) = $gui_fx then TrayItemSetState($i$TRAY_CHECKED)
        next
        TrayCreateItem("")

        global $TrayItemDoneQuits= TrayCreateItem("'Done!' quits the program", -1)
        TrayItemSetOnEvent(-1, "cpc_MenuToggleDoneQuits")
        GUICtrlSetState(-1, $done_quits)

        TrayCreateItem("")

        $TrayItemExit = TrayCreateItem("Exit    (Esc)", -1)
        TrayItemSetOnEvent(-1, "cpc_ExitDoQuit")

        TraySetToolTip (" left-click to toggle the color pickin chooser   [Ctrl+F1]" & _
                                            @CRLF & " right-click to bring up the menu ")
        TraySetOnEvent($TRAY_EVENT_PRIMARYDOWN"cpc_ToggleWindow")
        TraySetState()
        TraySetClick(8) ; right-click only to bring up the menu
    endif
    AutoItSetOption("GUICoordMode"$last_coord_mode)
endfunc


; update our cpc_gui_fx array and save the new setting to the ini..
func cpc_MenuSetWinAnim()
    $cpc_gui_fx = corz_GUIGetFX(TrayItemGetText(@TRAY_ID), $cpc_ini_path$cpc_my_name)
    ;$cpc_gui_fx = corz_GUIAnimateOpen("", TrayItemGetText(@TRAY_ID), $cpc_ini_path$cpc_my_name) ;same thing, but a tad slower
endfunc


func cpc_HotKeyShowTips()
    if $tips_live then return ; prevents F1 causing trouble when tips are running
    cpc_DialogOpen()
    corz_TipsSystem($tips_file$gui_color$cpc_ini_path$cpc_my_name"color pickin tips"""""$do_func)
    cpc_DialogClose()
endfunc


func cpc_ClickMouseSetColor()
    cpc_MouseSetColor()
    if $live_mag = $GUI_CHECKED then cpc_UnliveMag()
    cpc_UpdateMag()
endfunc

func cpc_MouseSetColor()
    $mouse_info = GUIGetCursorInfo()
    if not IsArray($mouse_info) then return
    if $mouse_info[4] = $pic_color_picker or $mouse_info[4] >= $mag_block[0] then
        cpc_SetColor()
        ; replace a color well with the current color..
        if ce_IsPressed(10) then cpc_AddNewColor($cpc_my_color, GUICtrlRead($input_color_name))
        if ($mouse_info[4] >= $grad_bars[1] and $mouse_info[4] < $grad_bars[150]) _
            and $live_mag = $GUI_CHECKED then cpc_UnliveMag()
    endif
endfunc

func cpc_SetColor($first=false)
    if cpc_MakeNewColor($first) then
        cpc_UpdateInputs()
        cpc_UpdateLiveColorBox()
    endif
endfunc

func cpc_MakeNewColor($first=false)
    if $first = false and $cpc_my_color = $cpc_live_color then return 0
    cpc_MakeRGBFromCurrentColor()
    $cpc_my_color = $cpc_live_color
    if $cpc_auto_copy = $GUI_CHECKED then cpc_ClipCopyHex($cpc_my_color)
    return 1
endfunc

func cpc_SlideRed()
    $red_index = Hex(GUICtrlRead($cpc_slider_red), 2)
    cpc_Update()
endfunc
func cpc_Slidegreen()
    $green_index = Hex(GUICtrlRead($cpc_slider_green), 2)
    cpc_Update()
endfunc
func cpc_Slideblue()
    $blue_index = Hex(GUICtrlRead($cpc_slider_blue), 2)
    cpc_Update()
endfunc

func cpc_AddRed()
    $red_index = Hex(GUICtrlRead($cpc_input_red), 2)
    cpc_Update()
endfunc
func cpc_AddGreen()
    $green_index = Hex(GUICtrlRead($cpc_input_green), 2)
    cpc_Update()
endfunc
func cpc_AddBlue()
    $blue_index = Hex(GUICtrlRead($cpc_input_blue), 2)
    cpc_Update()
endfunc

func cpc_AddHex()
    if cpc_CheckBigHex(GUICtrlRead($input_hex_in_out)) then
        cpc_MakeRGBFromHex()
        cpc_Update()
    else
        cpc_UpdateHexOutput($cpc_my_color)
    endif
endfunc

func cpc_MakeRGBFromHex()
    $red_index = StringLeft(GUICtrlRead($input_hex_in_out), 2)
    $green_index = StringMid(GUICtrlRead($input_hex_in_out), 3, 2)
    $blue_index = StringRight(GUICtrlRead($input_hex_in_out), 2)
endfunc

func cpc_MakeColorFromRGB()
    $cpc_live_color = $red_index & $green_index & $blue_index
endfunc

func cpc_MakeRGBFromCurrentColor()
    $red_index = StringLeft($cpc_live_color, 2)
    $green_index = StringMid($cpc_live_color, 3, 2)
    $blue_index = StringRight($cpc_live_color, 2)
endfunc

func cpc_Update()
        cpc_MakeColorFromRGB()
        if cpc_MakeNewColor() then
            cpc_UpdateInputs()
            cpc_UpdateLiveColorBox()
        endif
endfunc

func cpc_UpdateInputs()
    ; sadly, this deselects the text in the control you tab to. hmm.
    ; who keys in colors manually these days, huh?
    GUICtrlSetData($cpc_slider_red, Dec($red_index))
    GUICtrlSetData($cpc_slider_green, Dec($green_index))
    GUICtrlSetData($cpc_slider_blue, Dec($blue_index))

    GUICtrlSetData($cpc_input_red, Dec($red_index))
    GUICtrlSetData($cpc_input_green, Dec($green_index))
    GUICtrlSetData($cpc_input_blue, Dec($blue_index))
    cpc_UpdateHexOutput($cpc_my_color)

    GUICtrlSetBkColor($label_my_color"0x" & $cpc_my_color)
    cpc_UpdateLumGrad($cpc_my_color)
endfunc


func cpc_UpdateHexOutput($web_hex)
    GUICtrlSetData($input_hex_in_out$web_hex)

    $c_color = ConvertColorValue($web_hex$cpc_output_mode$add_prefix)
    if $cpc_live_titlebar = $GUI_CHECKED then _
        WinSetTitle($gui_color"""color pickin chooser..     " & $cpc_output_mode & ": " & $c_color & "" )

    GUICtrlSetTip($label_hex_in_out" current output: " & $c_color & @CRLF & _
                                    " right-click me for a menu of various clipboard output formats ")
endfunc


func cpc_UpdateLiveColorBox()
    GUICtrlSetBkColor($label_live_color"0x" & $cpc_live_color)
endfunc


; two gradients, one from the target color up to white, the other down to black..
; (crafty luminance selection ;o)
func cpc_UpdateLumGrad($target_color)
    $target_color = "0x" & $target_color
    GUICtrlSetBkColor($grad_bars[1], 0xFFFFFF) ; Oh! The math!
    for $i = 2 to $cpc_grad_step
        $color_str = cpc_MakeGradLineColors(0xFFFFFF, $target_color$i)
        GUICtrlSetBkColor($grad_bars[$i], $color_str)
    next
    for $i = 1 to $cpc_grad_step
        $color_str = cpc_MakeGradLineColors($target_color, 0x000000, $i)
        GUICtrlSetBkColor($grad_bars[$cpc_grad_step+$i], $color_str)
    next
endfunc

func cpc_MakeGradLineColors($start_color$target_color$i)
    local $g_red = GetColorRed($start_color)
    local $g_green = GetColorGreen($start_color)
    local $g_blue = GetColorBlue($start_color)
    local $g_r_step = (GetColorRed($target_color) - $g_red) / $cpc_grad_step
    local $g_g_step = (GetColorGreen($target_color) - $g_green) / $cpc_grad_step
    local $g_b_step = (GetColorBlue($target_color) - $g_blue) / $cpc_grad_step
    return "0x" & StringFormat("%02X%02X%02X"$g_red + $g_r_step * $i$g_green + $g_g_step * $i$g_blue + $g_b_step * $i)
endfunc


func cpc_UpdateMag($firstrun=false)
    if $firstrun then
        if $cpc_last_mag then
            ; this is a back-up for the regular "fool-proof" approach (store an array of the label colors in the ini)
            ; if they move the GUI (or switch image) after clicking, it spoils the effect, but it's still fun.
            ; this only kicks in if they have no 'mag_save' data in their ini, and the mag array could not be built.
            ; on first run, it will create a cute mag of the top-left corner of your desktop.
            ; we leave the 'last_mag' pref (and this Plan B) hanging around, to confound users of the compiled app ;o)
            $mag_xy = StringSplit($cpc_last_mag"|")
            local $MousePos[2] = [$mag_xy[1], $mag_xy[2]] ; minus x/y
        else
            return
        endif
    else
        $MousePos = MouseGetPos()
        if IsArray($MousePos) then $cpc_last_mag = $MousePos[0] & "|" & $MousePos[1]
    endif
    $count = 0
    for $iterX = -5 to 4
        for $iterY = -5 to 4
            $mag_save_blocks[$count+1] = PixelGetColor($MousePos[0]+$iterX$MousePos[1]+$iterY; so we can store it, later
            GUICtrlSetBkColor($mag_block[$count], $mag_save_blocks[$count+1])
            $count += 1
        next
    next
endfunc

; a few sample picker images..
func cpc_InstallSampleImages()
    if IniReadCheckBoxValue($cpc_ini_path$cpc_my_name"samples_installed"$GUI_UNCHECKED) = $GUI_UNCHECKED then
        if not FileExists($picker_img_dir) then return
        FileInstall(".\img\picker images\Homer X-Ray.jpg"$picker_img_dir & "\Homer X-Ray.jpg")
        FileInstall(".\img\picker images\New York.jpg"$picker_img_dir & "\New York.jpg")
        FileInstall(".\img\picker images\Biker.jpg"$picker_img_dir & "\Biker.jpg")
        FileInstall(".\img\picker images\Reds.jpg"$picker_img_dir & "\Reds.jpg")
        FileInstall(".\img\picker images\Sarah.jpg"$picker_img_dir & "\Sarah.jpg")
        FileInstall(".\img\picker images\Tropical bed and breakfast.jpg"$picker_img_dir & "\Tropical bed and breakfast.jpg")
        ; will anyone spot the ordering by extension type? they might spot this..
        FileInstall(".\img\picker images\Shoreline.jpeg"$picker_img_dir & "\Shoreline.jpeg")

        if not FileExists($picker_img_dir & "\Spectrums") then DirCreate($picker_img_dir & "\Spectrums")
        FileInstall(".\img\picker images\Spectrums\Gimp.jpg"$picker_img_dir & "\Spectrums\Gimp.jpg")
        FileInstall(".\img\picker images\Spectrums\Microsoft.jpg"$picker_img_dir & "\Spectrums\Microsoft.jpg")
        FileInstall(".\img\picker images\Spectrums\Spectrum.jpg"$picker_img_dir & "\Spectrums\Spectrum.jpg")
        FileInstall(".\img\picker images\Spectrums\Primary-Secondary.jpg"$picker_img_dir & "\Spectrums\Primary-Secondary.jpg")

        if not FileExists($picker_img_dir & "\Stretchies") then DirCreate($picker_img_dir & "\Stretchies")
        FileInstall(".\img\picker images\Stretchies\Primary Stretchie 1.bmp"$picker_img_dir & "\Stretchies\Primary Stretchie 1.bmp")
        FileInstall(".\img\picker images\Stretchies\Primary Stretchie 2.bmp"$picker_img_dir & "\Stretchies\Primary Stretchie 2.bmp")
        FileInstall(".\img\picker images\Stretchies\Stretchie [blue-green].jpg"$picker_img_dir & "\Stretchies\Stretchie [blue-green].jpg")
        FileInstall(".\img\picker images\Stretchies\Stretchie [red-yellow].jpg"$picker_img_dir & "\Stretchies\Stretchie [red-yellow].jpg")
        FileInstall(".\img\picker images\Stretchies\Stretchie [yellow-green].jpg"$picker_img_dir & "\Stretchies\Stretchie [yellow-green].jpg")
        IniWrite($cpc_ini_path$cpc_my_name"samples_installed", 1)
    endif
endfunc


func cpc_ImportImage($some_image)

        $new_image = $picker_img_dir & "\Imported\" & BaseName($some_image)
        $current_picker_images = RecurseDir($picker_img_dir"*.jpg,*.jpeg,*.gif,*.bmp")
        for $i in $current_picker_images
            if BaseName($i) = BaseName($some_image) and FileGetSize($i) = FileGetSize($some_image) then
                cpc_DoInfo("import failed: image already exists")
                AdlibEnable("cpc_SwitchOffInfo", 4000)
                return
            endif
        next

        FileCopy($some_image$new_image, 8)
        if FileExists($new_image) then
            cpc_DoInfo("image imported successfully")
            AdlibEnable("cpc_SwitchOffInfo", 4000)
            cpc_UpdateImageContextMenu()
            cpc_SwitchImage($new_image)
        endif
endfunc

func cpc_MenuUpdateImageContextMenu()
    cpc_UpdateImageContextMenu()
    ; immediately pop up the refreshed menu..
    ; also means folk can use F8 to pop up the menu anywhere on screen
    ControlFocus ($gui_color""$pic_color_picker)
    ControlSend($gui_color""$pic_color_picker"{APPSKEY}")
endfunc

func cpc_UpdateImageContextMenu()
        GUICtrlDelete($cpc_MenuColorPicker)
        global $cpc_MenuColorPicker = GUICtrlCreateContextMenu($pic_color_picker)
        global $cpc_picker_images = RecurseDir($picker_img_dir"*.jpg,*.jpeg,*.gif,*.bmp")

        if IsArray($cpc_picker_images) and FileExists($picker_img_dir) then

            global $img_menu_items[$cpc_picker_images[0]+1]
            $current_picker_path = $picker_img_dir

            for $i = 1 to $cpc_picker_images[0]

                ; check if we need a separator..
                if $current_picker_path <> GetParent($cpc_picker_images[$i]) then
                    $current_picker_path = GetParent($cpc_picker_images[$i])
                    GUICtrlCreateMenuItem(""$cpc_MenuColorPicker)
                endif

                if $cpc_picker_images[$i] <> '' then
                    $img_menu_items[$i] = GUICtrlCreateMenuItem(CleanName($cpc_picker_images[$i]), $cpc_MenuColorPicker)
                    GUICtrlSetOnEvent(-1, "cpc_Menucpc_SwitchImage")
                    if $cpc_picker_images[$i] = $cpc_picker_image then
                        $cpc_current_img_idx = $i
                        GUICtrlSetState($img_menu_items[$i], $GUI_CHECKED)
                    endif
                endif
            next
        else
            $img_menu_item = GUICtrlCreateMenuItem("[no images in this folder]"$cpc_MenuColorPicker)
            GUICtrlSetOnEvent(-1, "cpc_NewPickerFolder")
        endif

        GUICtrlCreateMenuitem(""$cpc_MenuColorPicker)

        $MenuSchemePrefs = GUICtrlCreateMenuitem("Open Picker Images Folder.."$cpc_MenuColorPicker)
        GUICtrlSetOnEvent(-1, "cpc_OpenPickersFolder")

        $MenuSchemePrefs = GUICtrlCreateMenuitem("New Picker Images Folder.."$cpc_MenuColorPicker)
        GUICtrlSetOnEvent(-1, "cpc_NewPickerFolder")

        $MenuSchemePrefs = GUICtrlCreateMenuitem("Refresh this menu..    F8"$cpc_MenuColorPicker)
        GUICtrlSetOnEvent(-1, "cpc_MenuUpdateImageContextMenu")

        GUICtrlCreateMenuitem(""$cpc_MenuColorPicker)

        $MenuSchemePrefs = GUICtrlCreateMenuitem("Use System Picker..    F9"$cpc_MenuColorPicker)
        GUICtrlSetOnEvent(-1, "cpc_SystemPicker")

        GUICtrlCreateMenuitem(""$cpc_MenuColorPicker)

        $MenuSchemePrefs = GUICtrlCreateMenuitem("About corz color pickin chooser"$cpc_MenuColorPicker)
        GUICtrlSetOnEvent(-1, "cpc_DoAbout")

        ; grab this again..
        $cpc_picker_image = IniRead($cpc_ini_path$cpc_my_name"picker_image"$picker_img_dir & "\Spectrums\Spectrum.jpg")

endfunc



func cpc_Menucpc_SwitchImage()
if not IsArray($cpc_picker_images) then return
    for $s = 1 to $cpc_picker_images[0]
        select
            case @GUI_CtrlId = $img_menu_items[$s]
                if ce_IsPressed(10) then ; delete an image from the folder
                    FileRecycle($cpc_picker_images[$s]) ; well, almost delete
                    cpc_UpdateImageContextMenu()
                    return
                endif
                $cpc_current_img_idx = $s
                cpc_SwitchImage($cpc_picker_images[$s])
        endselect
    next
endfunc

func cpc_SwitchImage($new_image)
    if FileExists($new_image) then

        GUICtrlSetState($img_menu_items[$cpc_uncheck_img_idx], $GUI_UNCHECKED)
        $cpc_picker_image = $new_image

        for $i = 1 to $cpc_picker_images[0]
            if $cpc_picker_images[$i] = $cpc_picker_image then
                $cpc_current_img_idx = $i
                $cpc_uncheck_img_idx = $i
                GUICtrlSetState($img_menu_items[$i], $GUI_CHECKED)
            endif
        next
        if not ce_IsPressed(11) then GUICtrlSetImage($pic_color_picker""; if Ctrl key not down, clear the image
        GUICtrlSetImage($pic_color_picker$cpc_picker_image)
        IniWrite($cpc_ini_path$cpc_my_name"picker_image"$cpc_picker_image; set as current picker image
    elseif IsArray($cpc_picker_images) then
        GUICtrlSetImage($pic_color_picker , $cpc_picker_images[1])
    else
        cpc_NewPickerFolder() ; WHAT HAPPENED? Vista user?

    endif
endfunc


func cpc_OpenPickersFolder()
    ShellExecute ("Explorer.exe"$picker_img_dir)
    WinWaitActive($picker_img_dir"" , 5)
    ; activate thumbnails (how dare we!)..
    Send("!vh")
endfunc

func cpc_NewPickerFolder()
    if $cpc_on_top = $GUI_CHECKED then WinSetOnTop($gui_color"", 0)
    $new_dir = FileSelectFolder( "Select a folder to use for picker images (subfolders will also be scanned)", _
                                                                                      "" , 6 , $picker_img_dir)
    if $new_dir <> "" then
        $picker_img_dir = $new_dir
        IniWrite($cpc_ini_path$cpc_my_name"picker_images_folder"$picker_img_dir)
        cpc_UpdateImageContextMenu()
    endif
    if $cpc_on_top = $GUI_CHECKED then WinSetOnTop($gui_color"", 1)
endfunc


func cpc_SwitchMode()
    GUICtrlSetState($cpc_menu_output_modes[$cpc_previous_mode], $GUI_UNCHECKED)
    for $i = 0 to uBound($cpc_output_modes)-1
        select
            case @GUI_CtrlId = $cpc_menu_output_modes[$i]
                $cpc_output_mode = $cpc_output_modes[$i]
                GUICtrlSetState($cpc_menu_output_modes[$i], $GUI_CHECKED)
                GUICtrlSetTip($check_special_clip_copy" click this button to copy the " & $cpc_output_modes[$i] & _
                                                                                        " value to the clipboard  [F4] ")
                GUICtrlSetTip($check_autocopy" click this switch to automatically copy the " & $cpc_output_modes[$i] & _
                                                            " value of all selected colors to the clipboard, or not  [F3] ")
                $cpc_previous_mode = $i
                IniWrite($cpc_ini_path$cpc_my_name"output_mode"$cpc_output_mode)
        endselect
    next
    if $cpc_auto_copy = $GUI_CHECKED then ControlClick($gui_color""$check_special_clip_copy)
    cpc_UpdateHexOutput($cpc_my_color)
endfunc


func cpc_HotAutoKeyCopyHex()
    ControlClick($gui_color""$check_autocopy)
endfunc

func cpc_HotKeyCopyHex()
    ControlClick($gui_color""$check_special_clip_copy)
endfunc

func cpc_ButtCopyColor()
    cpc_ClipCopyHex(GUICtrlRead($input_hex_in_out))
endfunc

func cpc_ClipCopyHex($color)

    if $color = "" then $color = GUICtrlRead($input_hex_in_out)
    $color = ConvertColorValue($color$cpc_output_mode$add_prefix)
    ClipPut($color)
    ;EnvSet("color_pickin_color"$color)

    if $cpc_auto_copy = $GUI_UNCHECKED then
        GUICtrlSetState($check_special_clip_copy$GUI_UNCHECKED)
    else
        GUICtrlSetState($check_special_clip_copy$GUI_CHECKED)
    endif
endfunc

func cpc_ToggleAutoCopy()
        if $cpc_auto_copy = $GUI_UNCHECKED then
        $cpc_auto_copy = $GUI_CHECKED
        ControlClick($gui_color""$check_special_clip_copy)
    else
        $cpc_auto_copy = $GUI_UNCHECKED
        GUICtrlSetState($check_special_clip_copy$GUI_UNCHECKED)
    endif
    IniWriteCheckboxValue($cpc_ini_path$cpc_my_name"auto_copy"$cpc_auto_copy)
endfunc


func cpc_MenuToggleDoneQuits()
    cpc_ToggleDoneQuits()
endfunc

func cpc_ToggleDoneQuits($flip=0)
    if $done_quits <> $GUI_CHECKED then
        $done_quits = $GUI_CHECKED
    else
        $done_quits = $GUI_UNCHECKED
    endif
    TrayItemSetState($TrayItemDoneQuits$done_quits)
    if not $flip then IniWriteCheckboxValue($cpc_ini_path$cpc_my_name"done_quits"$done_quits)
endfunc


func cpc_HotKeyToggleLiveLum()
    ControlClick($gui_color""$check_lumlive)
endfunc

func cpc_ToggleLiveLum()
    if $live_luminance = $GUI_CHECKED then
        $live_luminance = $GUI_UNCHECKED
    else
        $live_luminance = $GUI_CHECKED
    endif
    IniWriteCheckboxValue($cpc_ini_path$cpc_my_name"live_luminance"$live_luminance)
endfunc


func cpc_HotKeyToggleLiveMag()
    ControlClick($gui_color""$check_maglive)
endfunc

; user clicked the mag (pushbutton) checkbox..
func cpc_ToggleLiveMag()
    select
        ; regardless of whether it was on or off, it's super-mag time!..
        case ce_IsPressed(10)
            cpc_GetXYPrefs(1)
            ToolTip(" click somewhere to grab that region " & @CRLF & _
                    " or even right-click, if it's an active thing "$cpc_x$cpc_y"super mag activated", 1)
            AdlibEnable("cpc_SwitchOffInfo", 4000)
            $super_mag = true
            GUISetCursor(3, 1, $gui_color"+"
            $live_mag = $GUI_CHECKED
            GUICTrlSetState($check_maglive$GUI_CHECKED)

        case $live_mag = $GUI_CHECKED
            $live_mag = $GUI_UNCHECKED
            if $super_mag = true then
                $super_mag = false
                GUISetCursor()
            endif

        case $live_mag = $GUI_UNCHECKED
            $live_mag = $GUI_CHECKED
    endselect
    IniWriteCheckboxValue($cpc_ini_path$cpc_my_name"live_mag"$live_mag)
endfunc

func cpc_UnliveMag()
    $live_mag = $GUI_UNCHECKED
    GUICtrlSetState($check_maglive$GUI_UNCHECKED)
    ; don't write to ini. in practice, you may have quit right after getting your color, live mag
    ; enabled means you probably like it that way, and were just grabbing a color. so let's leave
    ; it that way for when you begin again. however, if you physically switch it off (with HotKey
    ; or mag button click), it will remain off.
endfunc

func cpc_SwitchOffSuperMag()
    cpc_UnliveMag()
    $super_mag = false
endfunc

func cpc_HotKeyToggleLiveHex()
    ControlClick($gui_color""$check_hexlive)
endfunc

func cpc_ToggleLiveHex()
    if $live_hex = $GUI_CHECKED then
        $live_hex = $GUI_UNCHECKED
        ToolTip("")
    else
        $live_hex = $GUI_CHECKED
    endif
    IniWriteCheckboxValue($cpc_ini_path$cpc_my_name"live_hex"$live_hex)
endfunc

func cpc_ToggleLiveColorHold()
    if $hold_live_color = $GUI_UNCHECKED then
        $hold_live_color = $GUI_CHECKED
    else
        $hold_live_color = $GUI_UNCHECKED
    endif
    IniWriteCheckboxValue($cpc_ini_path$cpc_my_name"hold_live_color"$hold_live_color)
endfunc


func cpc_MenuToggleOnTopWin()
    cpc_ToggleOnTopWin()
endfunc

func cpc_ToggleOnTopWin($flip=0)
    if $cpc_on_top <> $GUI_CHECKED then ; I like to mix it up!
        $cpc_on_top = $GUI_CHECKED
        WinSetOnTop($gui_color"", 1)
    else
        $cpc_on_top = $GUI_UNCHECKED
        WinSetOnTop($gui_color"", 0)
    endif
    if $cpc_stand_alone then TrayItemSetState($TrayItemToggleOnTop$cpc_on_top)
    if not $flip then IniWriteCheckBoxValue($cpc_ini_path$cpc_my_name"always_on_top"$cpc_on_top)
endfunc


func cpc_MenuToggleLiveTitleBar()
    cpc_ToggleLiveTitleBar()
endfunc


func cpc_ToggleLiveTitleBar($flip=0)
    if $cpc_live_titlebar <> $GUI_CHECKED then
        $cpc_live_titlebar = $GUI_CHECKED ; *phew*!
        if not $flip then _
            WinSetTitle($gui_color"""color pickin chooser..     " & $cpc_output_mode & ": " & _
                ConvertColorValue(GUICtrlRead($input_hex_in_out), $cpc_output_mode$add_prefix) & "" )
    else
        $cpc_live_titlebar = $GUI_UNCHECKED
        if not $flip then _
            WinSetTitle($gui_color"""color pickin chooser..")
    endif
    if $cpc_stand_alone then TrayItemSetState($TrayItemLiveTitleBar$cpc_live_titlebar)
    if not $flip then IniWriteCheckBoxValue($cpc_ini_path$cpc_my_name"colors_in_titlebar"$cpc_live_titlebar)
endfunc


func cpc_MenuTogglePrefix()
    if $add_prefix = $GUI_CHECKED then
        $add_prefix = $GUI_UNCHECKED
    else
        $add_prefix = $GUI_CHECKED
    endif
    GUICtrlSetState($menu_hex_prefix$add_prefix)
    IniWriteCheckBoxValue($cpc_ini_path$cpc_my_name"add_prefix"$add_prefix)
    cpc_UpdateHexOutput($cpc_my_color)
    if $cpc_auto_copy = $GUI_CHECKED then cpc_ClipCopyHex($cpc_my_color)
endfunc

func cpc_InitColorWells()
    cpc_LoadAllSavedColors()
    cpc_FillGroupsCombo()
    cpc_LoadColorGroup()
endfunc

func cpc_LoadAllSavedColors()
    cpc_GetColorGroupNames()
    for $i = 1 to $group_names[0]
        local $a_group[$no_colorwells+1][2]
        local $tmp_array = IniReadSection($colors_ini_path$group_names[$i])
        if not IsArray($tmp_array) then local $tmp_array[1][2] = [[0]]
        ; fill first values from ini array (the remaining wells will be blank)..
        for $j = 0 to uBound($tmp_array)-1
            if $tmp_array[$j][0] <> ""  then
                $a_group[$j][0] = $tmp_array[$j][0]
                $a_group[$j][1] = $tmp_array[$j][1]
            endif
            if $j = $no_colorwells then exitloop    ; there may be more colors in the ini, but we'll load only 64 for now.
        next                                        ; if they delete one, the 65th will pop into the last well, and so on..
        $groups[$i] = $a_group
    next
endfunc


func cpc_GetColorGroupNames()
    global $group_names = IniReadSectionNames($colors_ini_path)

    if not IsArray($group_names) then
        global $group_names = MakeDummyArray("empty")
        global $groups[$group_names[0]+1] ; 1
        IniWrite($cpc_ini_path$cpc_my_name"my_group""empty")
        $cpc_my_group = "empty"
    else
        if not InArray($group_names$cpc_my_group) then; your last group is now gone..
            $cpc_my_group = $group_names[$group_names[0]]
            IniWrite($cpc_ini_path$cpc_my_name"my_group"$cpc_my_group)
        endif
        global $groups[$group_names[0]+1] = [$group_names[0]] ; set element 0 to total
    endif
endfunc


func cpc_FillGroupsCombo()
    GUICtrlSetData($combo_custom_groups"|")
    for $i = 1 to $group_names[0]
        GUICtrlSetData($combo_custom_groups$group_names[$i])
    next
    GUICtrlSetData($combo_custom_groups$cpc_my_group)
endfunc



func cpc_LoadColorGroup()
    global $current_box = 0 ; not 1-64
    RememberComboSelection($previous_combo_groups$cpc_my_group)
    $load_group = GUICtrlRead($combo_custom_groups)
    for $i = 1 to $group_names[0]
        if $load_group = $group_names[$i] then
            $current_group_index = $i
            $cpc_my_group = $group_names[$current_group_index; <- handy variable to set now, the group name.
            ; now a 2-dimensional array of all the colours (and their names) in the currently selected group..
            global $this_group = $groups[$i]
            cpc_UpdateColorWells()
            ; but leave the name and label as they are.
        endif
    next
endfunc


func cpc_UpdateColorWells()
    for $i = 1 to $no_colorwells
        GUICtrlSetBkColor($custom_color_box[$i], Default) ; aha! blankness!
        if $this_group[$i][0] <> "" then
            GUICtrlSetBkColor($custom_color_box[$i], '0x' & $this_group[$i][0])
            GUICtrlSetTip($custom_color_box[$i], $this_group[$i][1])
        else
            GUICtrlSetTip($custom_color_box[$i], "no color")
        endif
    next
endfunc


func cpc_SelectColorWell()
    $overwrite = false
    if ce_IsPressed(10) then $overwrite = true

    for $i = $custom_color_box[1] to $custom_color_box[$no_colorwells; just numbers, dudes! ;o)

        $box_idx = $i - ($custom_color_box[1]) + 1

        ; user clicked box no. $box_idx..
        if $i = @GUI_CtrlId then


            ; of course, this doesn't work with labels. erm..
            ;GUICtrlSetState($custom_color_box[$box_idx], $GUI_CHECKED)
            $flash_color = '0xffffff'    ; or perhaps.. $flash_color = Default
            if RGBToHSL($this_group[$box_idx][0], 3) > 0.9 then $flash_color = '0x000000'
            GUICtrlSetBkColor($custom_color_box[$box_idx], $flash_color)  ; there's your feedback!

            ; empty color well.. (add my color to group)
            if $this_group[$box_idx][0] = "" then
                $this_group[$box_idx][0] = $cpc_my_color
                $this_group[$box_idx][1] = GUICtrlRead($input_color_name)
                cpc_AddNewColor($this_group[$box_idx][0], $this_group[$box_idx][1])

            ; existing color..
            else
                ; update existing color with new name..
                if $current_box = $box_idx and GUICtrlRead($input_color_name) <> $this_group[$box_idx][1] and _
                                            GUICtrlRead($input_color_name) <> "" then    ; no removing names, only changing
                    $this_group[$box_idx][1] = GUICtrlRead($input_color_name)            ; if you really need to, use a space

                    cpc_AddNewColor($this_group[$box_idx][0], $this_group[$box_idx][1])
                    exitloop
                endif

                ; delete a color..
                if $cpc_my_color = $this_group[$box_idx][0] and $overwrite then
                    cpc_DeleteColor($this_group[$box_idx][0])
                    $this_group[$box_idx][0] = "" ; keep name, for moving colors
                    cpc_InitColorWells()

                ; replace a color with current picked colors..
                elseif $overwrite then
                    cpc_DeleteColor($this_group[$box_idx][0])
                    $this_group[$box_idx][0] = $cpc_my_color
                    $this_group[$box_idx][1] = GUICtrlRead($input_color_name)
                    cpc_AddNewColor($this_group[$box_idx][0], $this_group[$box_idx][1])
                else
                    ; update picked colors from selected color well..
                    GUICtrlSetData($input_color_name$this_group[$box_idx][1])
                    if GUICtrlRead($input_hex_in_out) <> $this_group[$box_idx][0] then
                        cpc_UpdateHexOutput($this_group[$box_idx][0])
                        cpc_AddHex()
                    endif
                    GUICtrlSetBkColor($custom_color_box[$box_idx],  $flash_color); if they clicked the active color well again
                    Sleep(100)
                    GUICtrlSetBkColor($custom_color_box[$box_idx], '0x' & $this_group[$box_idx][0])
                endif
            endif
            $current_box = $box_idx
        endif
    next
    ; no sticky visible selections, but at least we have this..
    cpc_DoInfo("Color Well " & $current_box & " :  " & $this_group[$current_box][1])
    GUICtrlSetState($input_color_name$GUI_FOCUS; you want to name the color, right? (then type, hit <enter>) Voila!
    Send("{RIGHT}"; it's too ugly when all the text is selected automatically (use Ctrl+SHIFT+LEFT!)
endfunc


func cpc_HotKeyDeleteColor()
    cpc_DeleteColor($this_group[$current_box][0])
    $save_box = $current_box
    cpc_InitColorWells()
    $current_box = $save_box
endfunc

func cpc_DeleteColor($color)
    IniDelete($colors_ini_path$cpc_my_group$color)
endfunc


func cpc_HotKeyAddChosenColor()
    cpc_AddMyColor()
endfunc

func cpc_AddMyColor()
    if GUICtrlRead($combo_custom_groups) = "" then
        ControlCommand($gui_color""$combo_custom_groups"SelectString"$cpc_my_group)
    endif
    $under_limit = false
    for $i = 1 to $no_colorwells
        if $this_group[$i][0] = "" then
            $this_group[$i][0] = $cpc_my_color
            $this_group[$i][1] = GUICtrlRead($input_color_name; this could be a rename

            GUICtrlSetBkColor($custom_color_box[$i], '0x' & $this_group[$i][0])
            cpc_AddNewColor($this_group[$i][0], $this_group[$i][1])
            ControlFocus ($gui_color""$custom_color_box[$i])
            $current_box = $i
            $under_limit = true
            exitloop
        endif
    next
    ; even if we're out of space in the color wells, we'll add it to the ini.
    ; the user may not realise yet and we DO NOT want to destroy user data.
    ; they might later copy the group and delete the first 64 colors, creating
    ; two groups out of the one big one (see cpc_LoadAllSavedColors() - above)
    ; or perhaps export it as a palette, with *all* the colors intact.
    if not $under_limit then cpc_AddNewColor($cpc_my_color, GUICtrlRead($input_color_name))
endfunc

func cpc_AddNewColor($color$name)
    ; prefs color-first, means leave the dupe-checking to IniWrite. However..
    ; if you launch cpc and "my_color" happens to be in the group (quite likely)
    ; this will prevent it having its name wiped if you happen to click an empty well, as folk do..
    $poss_old_name = IniRead($colors_ini_path$cpc_my_group$color"()*&(*&^*&^%*&^%(*&^")
    if $poss_old_name <> "()*&(*&^*&^%*&^%(*&^" and $name = "" then $name = $poss_old_name
    IniWrite($colors_ini_path$cpc_my_group$color$name)
    cpc_InitColorWells()
endfunc

func cpc_AddColorGroup()

    $new_group = StringReplace(GUICtrlRead($combo_custom_groups), "[""{")
    $new_group = StringReplace($new_group"]""}")

    for $i = 1 to $group_names[0] ; existing group..
        if $group_names[$i] = $new_group and $new_group <> "empty" then return
    next

    ; simple and effective, and 'extra' colors are passed across, comments are not..
    $old_group = IniReadSection($colors_ini_path$cpc_my_group)
    if IsArray($old_group) then
        IniWriteSection($colors_ini_path$new_group$old_group)
    else
        IniWrite($colors_ini_path$new_group"tmp""")
        IniDelete($colors_ini_path$new_group"tmp")
    endif

    cpc_LoadAllSavedColors()
    cpc_FillGroupsCombo()
    GUICtrlSetData($combo_custom_groups$new_group)
    cpc_LoadColorGroup()
endfunc

func cpc_DeleteColorGroup()
    if ce_IsPressed(10) then
        cpc_RecoverBackup($colors_ini_path)
        cpc_LoadAllSavedColors()
        cpc_FillGroupsCombo()
        return
    endif

    cpc_StoreBackup($colors_ini_path)
    IniDelete($colors_ini_path, GUICtrlRead($combo_custom_groups))

    cpc_LoadAllSavedColors()
    $cpc_my_group = GetLastComboSelection($previous_combo_groups$group_names)
    IniWrite($cpc_ini_path$cpc_my_name"my_group"$cpc_my_group)
    cpc_FillGroupsCombo()
    GUICtrlSetData($combo_custom_groups$cpc_my_group)
    cpc_LoadColorGroup()
    GUICtrlSetState($combo_custom_groups$GUI_FOCUS)
endfunc


func cpc_DoInfo($info_string)
    GUICtrlSetData($label_colorwell$info_string)
endfunc

func cpc_SwitchOffInfo()
    if $ini_process then return ; they may import another folder immediately, you see.
    GUICtrlSetData($label_colorwell"")
    ToolTip("")
    AdLibDisable()
endfunc


func cpc_GetDroppedItem()
    global $found_colors = false
    $ini_process = false
    WinActivate($gui_color)
    $new_group = ""

    if @GUI_DRAGID = -1 then ; a regular file or folder
        if not StringInStr(FileGetAttrib(@GUI_DRAGFILE), "D") then ; not a folder
            $import_file = @GUI_DRAGFILE
            switch GetExtension($import_file)
                case "ini"
                    $ini_process = true
                    $new_group = cpc_ImportIniColors(@GUI_DRAGFILE)
                case "jpg""jpeg""bmp""gif"
                    cpc_ImportImage(@GUI_DRAGFILE)
                case "gpl""pal"
                    $multiple_groups = true
                    if ce_IsPressed(10) then $multiple_groups = false
                    cpc_DoInfo("scanning palette.. " & BaseName(@GUI_DRAGFILE))
                    cpc_ImportPalette(@GUI_DRAGFILE, $multiple_groups)
                    GUICtrlSetState($combo_custom_groups$GUI_FOCUS)
            endswitch

        else ; a folder..
            $ini_process = true
            $group_process = true
            cpc_DoInfo("scanning for ini files in: " & BaseName(@GUI_DRAGFILE))
            $list_o_inis = RecurseDir(@GUI_DRAGFILE, "*.ini")
            if IsArray($list_o_inis) and FileExists(@GUI_DRAGFILE) then
                for $i = 1 to $list_o_inis[0]
                    if $list_o_inis[$i] <> '' then
                        cpc_DoInfo("assimilating colors in: " & BaseName($list_o_inis[$i]))
                        $new_group = cpc_ImportIniColors($list_o_inis[$i])
                    endif
                next
            endif
        endif
    endif

    if $ini_process then
        if $found_colors then
            if $group_process then
                cpc_GetXYPrefs(1)
                ToolTip(" Imported colors are now available in your color groups "$cpc_x$cpc_y, _
                                                                                            "Import Complete", 1)
                cpc_DoInfo("import complete: new colors added")
            endif
            cpc_InitColorWells()
            cpc_DoInfo("import complete")
        else
            cpc_DoInfo("no colors found")
        endif
    endif
    $ini_process = false
    AdlibEnable("cpc_SwitchOffInfo", 4000)
    if $new_group then
        if $dont_pop_up_comments = $GUI_UNCHECKED then cpc_PopUpComments($new_group)
        ; this next line is here because doing it beforehand isn't quick enough to activate the group! :/
        ; which is why cpc_PopUpComments() takes a variable instead of always working with cpc_my_group.
        ControlCommand($gui_color""$combo_custom_groups"SelectString"$new_group)
    endif
endfunc



; cpc_ImportIniColors()
;
; This function imports colours from any old ini file, as well as regular
; cpc color group files, and converts them into color groups. pretty neat.
;
func cpc_ImportIniColors($import_file)

    $new_group = $cpc_my_group    ; we will return this value, and use it to set the group combo
    $comment_string = ""        ; to the last $new_group loaded (it may only be one group)

    $imported_sections = IniReadSectionNames($import_file)
    if not IsArray($imported_sections) then ; bad ini file (prolly xml!)
            if not $group_process then
                cpc_GetXYPrefs(1)
                ToolTip(" The ini file is in a non-standard format. "$cpc_x$cpc_y"An error occurred.", 1)
                AdlibEnable("cpc_SwitchOffInfo", 3333)
            endif
        return
    endif

    ; it would get too slow to check all situations, this is probably enough..
    $removed = 0

    for $i = 1 to $imported_sections[0] ; run through each section of the ini file..
        $found_here = false
        $new_group = $imported_sections[$i]
        $ini_section = IniReadSection($import_file$new_group)
        if not IsArray($ini_section) then continueloop

        for $j = 0 to uBound($ini_section)-1

            select
                ; remove a color from a group (for "updates")..
                case StringLen($ini_section[$j][0]) = 6 and $ini_section[$j][1] = "-"
                    if IniRead($colors_ini_path$new_group$ini_section[$j][0], "foo") <> "foo" then $removed += 1
                    IniDelete($colors_ini_path$new_group$ini_section[$j][0])

                ; kinda back-to-front, but we like it that way..
                ; foo=FF0000    becomes..    FF0000=foo
                case StringLen($ini_section[$j][1]) = 6 and cpc_CheckBigHex($ini_section[$j][1])
                    IniWrite($colors_ini_path$new_group$ini_section[$j][1], _
                                                    StringReplace($ini_section[$j][0], "_"" "))
                    $found_colors = true
                    $found_here = true

                ; and for regular front-to-back cpc color groups..
                ; we get a lot of free energy out of the colors being stored value-first.
                case StringLen($ini_section[$j][0]) = 6 and cpc_CheckBigHex($ini_section[$j][0])
                    IniWrite($colors_ini_path$new_group$ini_section[$j][0], _
                                                    StringReplace($ini_section[$j][1], "_"" "))
                    $found_colors = true
                    $found_here = true
            endselect
        next
        if $found_here then
            ; we won't import comments for existing groups - this could potentially lead to massive duplication (when updating)..
            ; we could delete the existsing comments (good for 'updates'), but I just don't like detroying user data.
            if not InArray($group_names$new_group) then $comment_string = GrabCommentsFromIniSection($import_file$new_group)
            ; write out any comments for this section..
            if $comment_string then WriteCommentsToIniSection($colors_ini_path$new_group$comment_string)
        endif
    next

    if not $group_process then
        $tip_add = ""
        if $removed then $tip_add = @CRLF & $removed & " colors were removed."
        cpc_GetXYPrefs(1)
        ToolTip("All available colors have been added to your color groups. " & $tip_add$cpc_x$cpc_y"Import Complete", 1)
        AdlibEnable("cpc_SwitchOffInfo", 3333)

        $tip_add = ""
        if $removed then $tip_add = " (" & $removed & " colors removed)"
        cpc_DoInfo("import complete" & $tip_add)
        AdlibEnable("cpc_SwitchOffInfo", 4000)
    endif
    return $new_group
endfunc

func cpc_CheckBigHex($so_called_color)
    $tmp_dec = Dec($so_called_color)
    if $tmp_dec = 0 and $so_called_color = "000000" then return 1
    if $tmp_dec <> 0 then  return 1
    return 0
endfunc



; Import a Color Palette..
;
; Gimp palettes are the best, bar none; beautiful plain text, support for both palette and
; color names, as well as column information (which even cpc doesn't have). Vey nice indeed.
;
; JASC palettes are also pretty good; and plain text, which we love. Though they do have
; a couple of quirks. For instance, although IniWrite wouldn't write two blacks, we need
; to watch for them, anyway..
;
; Black is used as the "empty" color in JASC Palettes, so after we have one black, we need
; to skip the rest. HOWEVER, sometimes you will see dozens of black entries, and then more
; valid colors, and then another group of black entries, then more colors, and so on.
;
; Gimp palettes have their quirks, too. Duplicate colors are common (to fill columns), as
; are comments, both of which will be stripped when imported into color pickin chooser.
;
; Anyways, this simple function will grab all the colors, nomatter where they are, from
; either type of palette and store them in color pickin chooser groups.
;
func cpc_ImportPalette($file$multiple_groups=true)

    cpc_GetXYPrefs(1)
    $palfile = FileOpen($file, 0)
    if $palfile = -1 then
        ToolTip(" There was an error reading the file. Check its permissions."$cpc_x$cpc_y"Import Failed", 1)
        AdlibEnable("cpc_SwitchOffInfo", 3333)
        return 0
    endif

    $palette_values = FileRead($palfile)
    FileClose($palfile)
    $palette_values = StringSplit($palette_values, @LF)

    switch StringStripWS($palette_values[1], 3)
        case "JASC-PAL"
            $pal_type = "jasc"
            $new_group = StringReplace(CleanName($file), "[""{")
            $new_group = StringReplace($new_group"]""}")
            $got_colums = true
        case "GIMP Palette"
            $pal_type = "gimp"
            $new_group = StringStripWS(StringReplace($palette_values[2], "Name:"""), 3)
            $got_colums = false
        case else
            ToolTip(" The palette was of an unknown type"$cpc_x$cpc_y"Import Failed", 1)
            cpc_DoInfo("import failed: unknown palette type")
            AdlibEnable("cpc_SwitchOffInfo", 4000)
            return
    endswitch

    if InArray($group_names$new_group) then
        ToolTip(" '" & $new_group & "' already exists"$cpc_x$cpc_y"Import Failed", 1)
        cpc_DoInfo("failed: '" & $new_group & "' already exists")
        AdlibEnable("cpc_SwitchOffInfo", 4000)
        return
    endif

    $color_well = 1
    $name_count = 1
    $name_append = ""
    $comment_string = ""
    $partial = false
    $got_black = false
    local $check_array[$palette_values[0]] ; quicker than querying the ini for every value

    for $i = 3 to $palette_values[0] ; begin scanning at line 2
        if not StringInStr($palette_values[$i], " ") then continueloop


        if $palette_values[$i] <> "" then
            ; setting a flag now is quicker than checking on every loop..
            if not $got_colums and $pal_type = "gimp" and StringLeft($palette_values[$i], 8) = "Columns:" then
                $got_colums = true ;
                continueloop
            endif

            if $pal_type = "jasc" and StringStripWS($palette_values[$i], 3) = "0 0 0" then
                if $got_black then
                    continueloop
                else
                    $got_black = true
                endif
            endif

            if $pal_type = "gimp" and StringLeft($palette_values[$i], 1) = "#" then
                $comment_string &= StringStripWS($palette_values[$i], 3) & @CRLF
                continueloop
            endif

            ; holding down the shift key while importing enables you to force
            ; all the colors into the same group..
            if $multiple_groups then
                ; more than 64 colors in this group -> make another group..
                if $color_well = $no_colorwells+1 then
                    $name_count += 1
                    $color_well = 1 ; reset
                endif

                if $name_count > 1 then $name_append = " " & $name_count

                if InArray($group_names$new_group & $name_append) then
                    $partial = true
                    continueloop ; they are fooling around!
                endif ; seriously though, this enables you to re-import parts of a set

            endif
            ; convert the decimal RGB color to its hex equivalent, and save..
            switch $pal_type

                case "jasc" ; colors separated by spaces..
                    $dec_array = StringSplit(StringStripWS($palette_values[$i], 3), " ")
                    $hex_val = Hex($dec_array[1], 2) & Hex($dec_array[2], 2) & Hex($dec_array[3], 2)
                    $color_name = StringStripWS($palette_values[$i], 3)

                case "gimp" ; colors separated by spaces, followed by a tab, followed by the color name.
                    $gimp_col = StringSplit(StringStripWS($palette_values[$i], 3), "    ")
                    $color_name = $gimp_col[$gimp_col[0]]

                    $col_array = StringSplit(StringStripWS($gimp_col[1], 3), " ")
                    local $gimp_col[3] ; might as well re-use this
                    $count = 0
                    for $g = 1 to $col_array[0]
                        if StringStripWS($col_array[$g], 8) <> "" then
                            $gimp_col[$count] = $col_array[$g]
                            $count +=1
                        endif
                    next
                    $hex_val = Hex($gimp_col[0], 2) & Hex($gimp_col[1], 2) & Hex($gimp_col[2], 2)
            endswitch

            ; this is a new color....
            if not InArray($check_array$hex_val) then
                $check_array[$i] = $hex_val
                IniWrite($colors_ini_path$new_group & $name_append$hex_val$color_name)
                $color_well += 1 ; Next!
            elseif $color_well = 1 then ; duplicate gimp colors could fool our group counter, so..
                $color_well = $no_colorwells+1
                $name_count -= 1
            endif
        endif
    next
    if $comment_string then
        $comment_string = StringStripWS($comment_string, 2)
        WriteCommentsToIniSection($colors_ini_path$new_group$comment_string)
    endif
    $tip_append = ""
    $info_append = ""
    $pause = 3333
    if $name_append <> "" then
        $tip_append = @CRLF & " note: the palette has been split into " & $name_count & " groups"
        $info_append = "  (" & $name_count & " groups)"
        if $partial then $tip_append &= @CRLF & " note also: some groups already existed and were not overwritten "
        $pause = 6000
    endif

    cpc_GetXYPrefs(1)
    cpc_DoInfo("Success: added  '" & $new_group & "'" & $info_append)
    ToolTip(" The palette is now available as the group '" & $new_group & "'" & $tip_append$cpc_x$cpc_y, _
                                                                                        "Import Complete", 1)
    AdlibEnable("cpc_SwitchOffInfo"$pause)
    cpc_InitColorWells()
    if $dont_pop_up_comments = $GUI_UNCHECKED then cpc_PopUpComments($new_group)
    ControlCommand($gui_color""$combo_custom_groups"SelectString"$new_group)
endfunc



; export a color group..
;
func cpc_ExportGroup()
    cpc_DialogOpen()
    $save_to = IniRead($cpc_ini_path$cpc_my_name"save_inis", @MyDocumentsDir)
    $group_section = IniReadSection($colors_ini_path$cpc_my_group)
    $comment_string = GrabCommentsFromIniSection($colors_ini_path$cpc_my_group)
    $save_file = FileSaveDialog( "Export the Color Group.."$save_to"ini files (*.ini)" , 16 , $cpc_my_group & ".ini")
    cpc_DialogClose()
    if $save_file = "" then return
    IniWrite($cpc_ini_path$cpc_my_name"save_inis", GetParent($save_file))
    IniWriteSection ($save_file$cpc_my_group$group_section)
    if $comment_string then WriteCommentsToIniSection($save_file$cpc_my_group$comment_string)
endfunc

; export a JASC-compatible palette..
;
func cpc_ExportJASCPalette()
    $save_file = cpc_GetPalleteSaveLocation("JASC Palette files""save_jasc_palettes""pal")
    if not $save_file then return

    $group_section = IniReadSection($colors_ini_path$cpc_my_group)
    $pal_type = "256"
    if $group_section[0][0] <= 16 then $pal_type = "16"
    $pal_string = "JASC-PAL" & @CRLF & "0100" & @CRLF & $pal_type & @CRLF

    if IsArray($group_section) then
        if $pal_type = "256" then
            $pal_string &= "255 255 255" & @CRLF ; add a white
            $pal_type = "255"
        endif
        for $i = 1 to $group_section[0][0]
            $pal_string &= StringReplace(ConvertColorValue($group_section[$i][0], "int"), ","" ") & @CRLF
        next
        for $j = $i to $pal_type
            $pal_string &= "0 0 0" & @CRLF
        next
        ; the null character at the end isn't necessary.
        FileWrite($save_file$pal_string)
    endif
endfunc

; export a Gimp palette..
;
func cpc_ExportGimpPalette()
    $save_file = cpc_GetPalleteSaveLocation("Gimp Palette files""save_gimp_palettes""gpl")
    if not $save_file then return
    $group_section = IniReadSection($colors_ini_path$cpc_my_group)
    $comment_string = GrabCommentsFromIniSection($colors_ini_path$cpc_my_group"""exported color pickin chooser")

    $pal_string = "GIMP Palette" & @LF & "Name: " & $cpc_my_group & @LF & "# exported color pickin chooser color group" & @LF
    if $comment_string then $pal_string &= StringReplace(StringStripWS($comment_string, 1), @CRLF, @LF) & @LF

    if IsArray($group_section) then
        for $i = 1 to $group_section[0][0]
            $tmp_string = StringReplace(ConvertColorValue($group_section[$i][0], "int"), ","" ")
            $rgb = StringSplit($tmp_string" ")

            for $c = 1 to $rgb[0]
                ; pad the decimal string with spaces to take it up to 3 characters (perhaps StringFormat could do this)
                ; this is cute, though..
                ;for $a = StringLen($rgb[$c])+1 to 3
                ;    $rgb[$c] = " " & $rgb[$c]
                ;next

                ; yup..
                $rgb[$c] = StringFormat("% 3s"$rgb[$c])
            next

            $pal_string &= $rgb[1] & " " & $rgb[2] & " " & $rgb[3]
            ; add the name, if any..
            if $group_section[$i][1] = "" then $group_section[$i][1] = "Untitled"
            $pal_string &= "    " & $group_section[$i][1] & @LF
        next
        $save_file = FileOpen($save_file, 2)
        FileWrite($save_file$pal_string)
        FileClose($save_file)
    endif
endfunc

func cpc_GetPalleteSaveLocation($type_string$ini_save$ext)
    cpc_DialogOpen()
    $save_to = IniRead($cpc_ini_path$cpc_my_name$ini_save, @MyDocumentsDir)
    $save_file = FileSaveDialog( "Export the Color Group as a Palette.."$save_to$type_string & "(*" & "." & $ext & ")" , 16 , $cpc_my_group & "." & $ext)
    cpc_DialogClose()
    if $save_file = "" then return
    IniWrite($cpc_ini_path$cpc_my_name$ini_save, GetParent($save_file))
    if GetExtension($save_file) <> $ext then $save_file &= "." & $ext
    return $save_file
endfunc



; view/edit the comments for this group..
;

func cpc_PopUpComments($group)
    cpc_GroupComments($group, 1)
endfunc

func cpc_MenuGroupComments()
    cpc_GroupComments($cpc_my_group)
endfunc

func cpc_GroupComments($color_group$popped=0)

    $comment_string = ""
    $comment_array = GrabCommentsFromIniSection($colors_ini_path$color_group, true)

    ; strip "#" character (and any spaces) from left side of comment lines..
    if $comment_array[0] > 0 then
        for $i = 1 to $comment_array[0]
            $comment_array[$i] = StringTrimLeft($comment_array[$i], 1)
            $comment_array[$i] = StringStripWS($comment_array[$i], 1)
            $comment_string &= $comment_array[$i] & @CRLF
        next
        $comment_string = StringStripWS($comment_string, 2)
    endif
    ; no comments here, return..
    if $comment_string = "" and $popped then return

    $last_mode = AutoItSetOption("GUIOnEventMode", 0)
    $last_coord_mode = AutoItSetOption("GUICoordMode", 0)
    cpc_DialogOpen()

    $dont_pop_up_comments = IniReadCheckBoxValue($cpc_ini_path$cpc_my_name"dont_pop_up_comments"$GUI_UNCHECKED)

    cpc_GetXYPrefs(1)
    $com_x = $cpc_x - 55
    $com_y = $cpc_y + 75
    if $com_x < 0 then $com_x = 0
    if $com_y < 0 then $com_y = 0

    global $gui_comments = GUICreate("Notes and Comments for '" & $color_group & "'..", _
                                            450, 172, $com_x$com_y, -1, $WS_EX_TOOLWINDOW)
    WinSetOnTop($gui_comments"", 1)


    global $edit_comments = GUICtrlCreateEdit("", 7, 7, 440, 138)
    GUICtrlSetData(-1, $comment_string)


    $butt_done= GUICtrlCreateButton("&cancel", 0, 142, 46, 22)
    GUICtrlSetTip(-1, " close this dialog " )

    $check_no_comments_pop = GUICtrlCreateCheckBox("don't pop-up comments on import", 80, 0, 200)
    GUICtrlSetTip(-1, " check this box to prevent comments popping up when you import color groups " )
    GUICtrlSetState(-1, $dont_pop_up_comments)

    $butt_revert = GUICtrlCreateButton("&revert", 250, 0, 54, 22)
    GUICtrlSetTip(-1, " revert the comments back to the last saved version " )

    $butt_save = GUICtrlCreateButton("&save", 56, 0, 54, 22)
    GUICtrlSetTip(-1, " save the comments for this color group " )

    GUISetState()
    GUICtrlSetState($edit_comments$GUI_FOCUS; this command, and..
    WinActivate($gui_comments; this, prevents an <enter> popping the app menu (ALT key remnant?)
    ; perhaps we send an ALT keypress instead

    while 1
        sleep(50)

        $msg = GUIGetMsg()
        switch $msg

            case $GUI_EVENT_CLOSE$butt_done
                exitloop

            case $edit_comments

            case $butt_revert
                GUICtrlSetData($edit_comments$comment_string)

            case $check_no_comments_pop
                $dont_pop_up_comments = GUICtrlRead($check_no_comments_pop)
                if $dont_pop_up_comments = $GUI_CHECKED then
                    IniWrite($cpc_ini_path$cpc_my_name"dont_pop_up_comments""true")
                else
                    IniWrite($cpc_ini_path$cpc_my_name"dont_pop_up_comments""false")
                endif

            case $butt_save

                if StringStripWS(GUICtrlRead($edit_comments), 3) = "" then exitloop
                $comment_string = ""
                $new_comments_array = StringSplit(GUICtrlRead($edit_comments), @CRLF)
                for $i = 1 to $new_comments_array[0]
                    if StringStripWS($new_comments_array[$i], 3) <> "" then
                        $comment_string &= "# " & StringStripWS($new_comments_array[$i], 3) & @CRLF
                    endif
                next
                $tmp_colors = IniReadSection($colors_ini_path$color_group)
                if IsArray($tmp_colors) then
                    ; wipe and replace the ini section to remove its comments..
                    ; this is where AutoIt's lack of comment support works in our favour!
                    IniDelete($colors_ini_path$color_group)
                    IniWriteSection($colors_ini_path$color_group$tmp_colors)
                    ; add the new comments..
                    if $comment_string then WriteCommentsToIniSection($colors_ini_path$color_group, StringStripWS($comment_string, 2))
                endif
                exitloop
        endswitch
        if GUICtrlRead($edit_comments) <> $comment_string then
            GUICtrlSetData($butt_save"&save")
        else
            GUICtrlSetData($butt_save"&ok")
        endif
    wend

    AutoItSetOption("GUIOnEventMode"$last_mode)
    AutoItSetOption("GUICoordMode"$last_coord_mode)
    GUIDelete($gui_comments)
    cpc_DialogClose()

endfunc



#cs    (color sorting!)

    sort flags..

        1:    red sort
        2:    green sort
        3:    blue sort

        4:    hue sort
        5:    sat sort
        6:    lum sort

        10:    name sort

#ce;(critical entropy!)


func cpc_MenuSortColorsName()
    if $sort_flags[10] then
        cpc_ReverseColors()
        $sort_flags[10] = false
    else
        cpc_SetSortFlag(10)
        cpc_GetColorsToSort()
        cpc_ColorSortName($sort_colors)
    endif
    cpc_ShowSortedColors()
endfunc
; r/g/b..
func cpc_MenuSortColorsRed()
    if $sort_flags[1] then
        cpc_ReverseColors()
        $sort_flags[1] = false
    else
        cpc_SetSortFlag(1)
        cpc_GetColorsToSort()
        cpc_ColorSortRGB($sort_colors, 1)
    endif
    cpc_ShowSortedColors()
endfunc
func cpc_MenuSortColorsGreen()
    if $sort_flags[2] then
        cpc_ReverseColors()
        $sort_flags[2] = false
    else
        cpc_SetSortFlag(2)
        cpc_GetColorsToSort()
        cpc_ColorSortRGB($sort_colors, 2)
    endif
    cpc_ShowSortedColors()
endfunc
func cpc_MenuSortColorsBlue()
    if $sort_flags[3] then
        cpc_ReverseColors()
        $sort_flags[3] = false
    else
        cpc_SetSortFlag(3)
        cpc_GetColorsToSort()
        cpc_ColorSortRGB($sort_colors, 3)
    endif
    cpc_ShowSortedColors()
endfunc
; h/s/l..
func cpc_MenuSortColorsHue()
    if $sort_flags[4] then
        cpc_ReverseColors()
        $sort_flags[4] = false
    else
        cpc_SetSortFlag(4)
        cpc_GetColorsToSort()
        cpc_ColorSortHSL($sort_colors, 1)
    endif
    cpc_ShowSortedColors()
endfunc
func cpc_MenuSortColorsSat()
    if $sort_flags[5] then
        cpc_ReverseColors()
        $sort_flags[5] = false
    else
        cpc_SetSortFlag(5)
        cpc_GetColorsToSort()
        cpc_ColorSortHSL($sort_colors, 2)
    endif
    cpc_ShowSortedColors()
endfunc
func cpc_MenuSortColorsLum()
    if $sort_flags[6] then
        cpc_ReverseColors()
        $sort_flags[6] = false
    else
        cpc_SetSortFlag(6)
        cpc_GetColorsToSort()
        cpc_ColorSortHSL($sort_colors, 3)
    endif
    cpc_ShowSortedColors()
endfunc

func cpc_GetColorsToSort()
    global $sort_colors = IniReadSection($colors_ini_path$cpc_my_group)
endfunc

func cpc_ShowSortedColors()
    $comment_string = GrabCommentsFromIniSection($colors_ini_path$cpc_my_group)
    IniWriteSection($colors_ini_path$cpc_my_group , $sort_colors)
    if $comment_string then WriteCommentsToIniSection($colors_ini_path$cpc_my_group$comment_string)
    cpc_InitColorWells()
endfunc

; could be re-used (with a small modification) to reverse other 2D arrays..
func cpc_ReverseColors()
    cpc_GetColorsToSort()
    $limit = $sort_colors[0][0]
    local $tmp_array[$limit+1][2] = [[$limit]]
    $a = 1
    for $i = $limit to 1 step -1
        $tmp_array[$a][0] = $sort_colors[$i][0]
        $tmp_array[$a][1] = $sort_colors[$i][1]
        $a += 1
    next
    $sort_colors = $tmp_array
endfunc

; set this sort flag, and clear all other sort flags..
; this ensures you get your chosen sort on the first keypress
func cpc_SetSortFlag($flag)
    for $i = 1 to $sort_flags[0]
        if $i <> $flag then
            $sort_flags[$i] = false
        else
            $sort_flags[$i] = true
        endif
    next
endfunc



; The sorting routines..
;
; Basically, insertion sort algos with a colorful twist
; (the color fun happens in corz_colors.au3)
;
; I originally had a QuickSort algo here, but insertion sorting
; a) is just as fast, and b) gives better results for colors.
; ShellSort also proves to be no better in this application.
;
; sort by Hue/Sat/Lum..
;
func cpc_ColorSortHSL(ByRef $array$idx)
    for $i = 1 to $array[0][0]
        $store = $array[$i][0]
        $store2 = $array[$i][1]
        $hsl_idx = RGBToHSL($array[$i][0], $idx)
        $j = $i
        while $j > 1 and RGBToHSL($array[$j-1][0], $idx) > $hsl_idx
            $array[$j][0] = $array[$j-1][0]
            $array[$j][1] = $array[$j-1][1]
            $j -= 1
        wend
        $array[$j][0] = $store
        $array[$j][1] = $store2
    next
endfunc

; sort by RGB values..
; I often wonder why you don't see this more in color utilities.
;
func cpc_ColorSortRGB(ByRef $array$idx)
    for $i = 1 to $array[0][0]
        $store = $array[$i][0]
        $store2 = $array[$i][1]
        $hsl_idx = ConvertColorValue($array[$i][0], "i", 0, $idx)
        $j = $i
        while $j > 1 and ConvertColorValue($array[$j-1][0], "i", 0, $idx) > $hsl_idx
            $array[$j][0] = $array[$j-1][0]
            $array[$j][1] = $array[$j-1][1]
            $j -= 1
        wend
        $array[$j][0] = $store
        $array[$j][1] = $store2
    next
endfunc

; and a bubble sort for the names..
;
func cpc_ColorSortName(ByRef $bs_array)
    for $i = uBound($bs_array)-1 to 1 step -1
        for $j = 2 to $i
            if $bs_array[$j-1][1] > $bs_array[$j][1] then
                $temp = $bs_array[$j-1][0]
                $temp2 = $bs_array[$j-1][1]
                $bs_array[$j-1][0] = $bs_array[$j][0]
                $bs_array[$j-1][1] = $bs_array[$j][1]
                $bs_array[$j][0] = $temp
                $bs_array[$j][1] = $temp2
            endif
        next
    next
endfunc


func cpc_DialogOpen()
    cpc_UnSetHotKeys()
    GUISetState(@SW_DISABLE, $gui_color)
    if $cpc_stand_alone then
        AutoItSetOption ("TrayIconHide" , 1)
        if $cpc_on_top = $GUI_CHECKED then WinSetOnTop($gui_color"", 0)
    endif
endfunc
func cpc_DialogClose()
    if $cpc_stand_alone then
        if $cpc_on_top = $GUI_CHECKED then WinSetOnTop($gui_color"", 1)
        AutoItSetOption("TrayIconHide" , 0)
    endif
    GUISetState(@SW_ENABLE, $gui_color)
    WinActivate($gui_color; handy for when embedded in other apps
    cpc_SetHotKeys()
endfunc


func cpc_SaveColorPrefs()
    IniWrite($cpc_ini_path$cpc_my_name"my_color"$cpc_my_color)
    IniWrite($cpc_ini_path$cpc_my_name"my_group"$cpc_my_group)
endfunc


func cpc_LoadMag()
    local $tmp_blocks = IniRead($cpc_ini_path$cpc_my_name"mag_save""")
    if $tmp_blocks = "" then
        cpc_UpdateMag(true) ; (first run)
        return
    endif
    $mag_save_blocks = StringSplit($tmp_blocks"|")
    if $mag_save_blocks[0] = 1 then return
    for $i = 1 to 100
        GUICtrlSetBkColor($mag_block[$i-1], $mag_save_blocks[$i])
    next
endfunc

func cpc_SaveMag()
    local $mag_save = ""
    for $i = 1 to 100
        $mag_save &= $mag_save_blocks[$i] & "|"
    next
    $mag_save = StringTrimRight($mag_save, 1)
    IniWrite($cpc_ini_path$cpc_my_name"mag_save",  $mag_save)
    IniWrite($cpc_ini_path$cpc_my_name"last_mag"$cpc_last_mag; secondary mag backup system
endfunc


; backup group deletions in case they change their mind..
;
func cpc_StoreBackup($inifile_path)
    FileCopy($inifile_path, @TempDir & "\" & Basename($inifile_path) & ".backup.ini", 1)
endfunc

; use a standard ini import, in case they are tardy in recovery; no new colors get lost
;
func cpc_RecoverBackup($inifile_path)
    FileCopy($inifile_path, @TempDir & "\" & Basename($inifile_path) & ".backupTMP", 1)
    cpc_ImportIniColors(@TempDir & "\" & Basename($inifile_path) & ".backup.ini")
    FileMove(@TempDir & "\" & Basename($inifile_path) & ".backupTMP", @TempDir & "\" & Basename($inifile_path) & ".backup.ini", 1)
endfunc

; cpc will not, in fact, call this function.. ;o)
func cpc_RemoveBackup($inifile_path)
    FileDelete(@TempDir & "\" & Basename($inifile_path) & ".backup.ini")
endfunc



func cpc_OpenDataFolder()
    ShellExecute ("Explorer.exe"$cpc_data_parent)
endfunc


func cpc_DoAbout()
    GUISetCursor()
    cpc_DialogOpen()
    $last_mode = AutoItSetOption("GUIOnEventMode", 0) ; you surely wouln't    remove my credit!
    $gui_about = GUICreate(" about corz " & $cpc_my_name & "..", 225, 100, -1, -1, _
                                        $WS_CAPTION, BitOr($WS_EX_TOPMOST$WS_EX_TOOLWINDOW))
    GUICtrlCreateLabel(" " & $cpc_my_name & " v" & $cpc_my_version & @CRLF & " by cor", 60, 8)
    GUICtrlCreateIcon("shell32.dll", 274, 10, 10)

    GUICtrlCreateLabel(" do you want to visit the " & @CRLF & " color pickin chooser web page? ", 60, 38)

    $gui_about_NO = GUICtrlCreateButton("No, not right now", 10, 73, 85, 22)
    $gui_about_OK = GUICtrlCreateButton("Yes, let's do it!", 133, 73, 85, 22)
    GUICtrlSetState($gui_about_OK$GUI_FOCUS)

    GUISetState()
    while 1
        $msg = GUIGetMsg()
        switch $msg
            case $GUI_EVENT_CLOSE$gui_about_NO
                GUIDelete($gui_about)
                exitloop

            case $gui_about_OK
                VisitURL('http://corz.org/windows/software/color-pickin-chooser/')
                GUIDelete($gui_about)
                exitloop
        endswitch
    wend
    AutoItSetOption("GUIOnEventMode"$last_mode)
    cpc_DialogClose()
endfunc

; left-click system tray action..
;
func cpc_ToggleWindow()
    $winstate = WinGetState($gui_color)
    if BitAnd($winstate, 2) then ; hide the window..
        if $cpc_on_top = $GUI_CHECKED then WinSetOnTop($gui_color"", 0)
        GUISetCursor()
        ToolTip ("")
        cpc_GetXYPrefs() ; still looking for the "MOVE" event    (if primaryup is available, it's handy for that)
        cpc_UnSetHotKeys()
        corz_GUIAnimateClose($gui_color$cpc_gui_fx)
    else ; show the window..
        corz_GUIAnimateOpen($gui_color$cpc_gui_fx)
        cpc_UpdateImageContextMenu()
        cpc_SetHotKeys()
        if $cpc_on_top = $GUI_CHECKED then WinSetOnTop($gui_color"", 1)
    endif
endfunc


func cpc_SetHotKeys()
    HotKeySet("^{F1}""cpc_ToggleWindow")

    HotKeySet("{DEL}""cpc_HotKeyDeleteColor")
    HotKeySet("{ESC}""cpc_ExitDoQuit")
    HotKeySet("{ENTER}""cpc_HotKeyAddChosenColor")
    HotKeySet("{F1}""cpc_HotKeyShowTips")
    HotKeySet("{F2}""cpc_HotKeyAddChosenColor")
    HotKeySet("{F3}""cpc_HotAutoKeyCopyHex")
    HotKeySet("{F4}""cpc_HotKeyCopyHex")
    HotKeySet("{F5}""cpc_HotKeyToggleLiveLum")
    HotKeySet("{F6}""cpc_HotKeyToggleLiveMag")
    HotKeySet("{F7}""cpc_HotKeyToggleLiveHex")
    HotKeySet("{F8}""cpc_MenuUpdateImageContextMenu")
    HotKeySet("{F9}""cpc_HotKeySystemPicker")
    HotKeySet("{F10}""cpc_OpenDataFolder")
    HotKeySet("^{NUMPAD0}""cpc_MenuSortColorsName")
    HotKeySet("^{NUMPAD1}""cpc_MenuSortColorsRed")
    HotKeySet("^{NUMPAD2}""cpc_MenuSortColorsGreen")
    HotKeySet("^{NUMPAD3}""cpc_MenuSortColorsBlue")
    HotKeySet("^{NUMPAD4}""cpc_MenuSortColorsHue")
    HotKeySet("^{NUMPAD5}""cpc_MenuSortColorsSat")
    HotKeySet("^{NUMPAD6}""cpc_MenuSortColorsLum")
    HotKeySet("!c""cpc_MenuGroupComments")
endfunc

func cpc_UnSetHotKeys()
    HotKeySet("{DEL}")
    HotKeySet("{ESC}")
    HotKeySet("{ENTER}")
    HotKeySet("{F1}")
    HotKeySet("{F2}")
    HotKeySet("{F3}")
    HotKeySet("{F4}")
    HotKeySet("{F5}")
    HotKeySet("{F6}")
    HotKeySet("{F7}")
    HotKeySet("{F8}")
    HotKeySet("{F9}")
    HotKeySet("{F10}")
    HotKeySet("^{NUMPAD0}")
    HotKeySet("^{NUMPAD1}")
    HotKeySet("^{NUMPAD2}")
    HotKeySet("^{NUMPAD3}")
    HotKeySet("^{NUMPAD4}")
    HotKeySet("^{NUMPAD5}")
    HotKeySet("^{NUMPAD6}")
    HotKeySet("!c")
endfunc


func cpc_GetXYPrefs($check_only=false) ; also called during window toggle, and before tips
    $size_array = WinGetPos($gui_color)
    if IsArray($size_array) then
        $cpc_x = $size_array[0]
        $cpc_y = $size_array[1]
    else
        $cpc_x = -1
        $cpc_y = -1
    endif
    if not $check_only then
        IniWrite($cpc_ini_path$cpc_my_name"x"$cpc_x)
        IniWrite($cpc_ini_path$cpc_my_name"y"$cpc_y)
    endif
endfunc



func cpc_KillWindow()
    cpc_UnSetHotKeys() ; I'm trying to track something down *sigh*
    GUISetCursor()
    ToolTip ("")
    if not $cpc_killed then corz_GUIAnimateClose($gui_color$cpc_gui_fx)
    GUIDelete($gui_color)
    GUIDelete($dummy_container)
endfunc


func cpc_Done()
    if $done_quits = $GUI_CHECKED or not $cpc_stand_alone then
        cpc_DoneDoQuit()
        return
    else
        cpc_ToggleWindow()
    endif
endfunc

func cpc_DoneDoQuit()
    cpc_UnSetHotKeys()
    cpc_GetXYPrefs()
    cpc_SaveColorPrefs()
    cpc_SaveMag()
    $do_quit = true
endfunc


; bye!
func cpc_ExitDoQuit()
    $cpc_killed = true
    cpc_DoneDoQuit()
endfunc


func cpc_HotKeySystemPicker()
    cpc_SystemPicker()
endfunc

func cpc_SystemPicker()
    cpc_UnSetHotKeys()
    $some_color = cpc__ChooseColor(2, "0x" & $cpc_my_color, 2, $gui_color)
    if not @error then
        $cpc_live_color = StringTrimLeft($some_color, 2)
        cpc_SetColor()
    endif
    cpc_SetHotKeys()
endfunc



; From the UDFs (Misc.au3)..

; Call the System Picker..
;
; Author: Gary Frost (custompcs at charter dot net)
;
Func cpc__ChooseColor($i_ReturnType = 0, $i_colorref = 0, $i_refType = 0, $h_wnd_owner = 0)
    Local $custcolors = "int[16]"
    Local $struct = "dword;int;int;int;ptr;dword;int;ptr;ptr"
    Local $p = DllStructCreate($struct)
    If @error Then
        SetError(-1)
        Return -1
    EndIf
    Local $cc = DllStructCreate($custcolors)
    If @error Then
        SetError(-2)
        Return -1
    EndIf
    If ($i_refType == 1) Then
        $i_colorref = Int($i_colorref)
    ElseIf ($i_refType == 2) Then
        $i_colorref = Hex(String($i_colorref), 6)
        $i_colorref = '0x' & StringMid($i_colorref, 5, 2) & StringMid($i_colorref, 3, 2) & StringMid($i_colorref, 1, 2)
    EndIf
    DllStructSetData($p, 1, DllStructGetSize($p))
    DllStructSetData($p, 2, $h_wnd_owner)
    DllStructSetData($p, 4, $i_colorref)
    DllStructSetData($p, 5, DllStructGetPtr($cc))
    DllStructSetData($p, 6, BitOR($CC_ANYCOLOR$CC_FULLOPEN$CC_RGBINIT))
    Local $ret = DllCall("comdlg32.dll""long""ChooseColor""ptr", DllStructGetPtr($p))
    If ($ret[0] == 0) Then
        SetError(-3)
        Return -1
    EndIf
    Local $color_picked = DllStructGetData($p, 4)
    If ($i_ReturnType == 1) Then ; return Hex BGR Color
        Return '0x' & Hex(String($color_picked), 6)
    ElseIf ($i_ReturnType == 2) Then ; return Hex RGB Color
        $color_picked = Hex(String($color_picked), 6)
        Return '0x' & StringMid($color_picked, 5, 2) & StringMid($color_picked, 3, 2) & StringMid($color_picked, 1, 2)
    ElseIf ($i_ReturnType == 0) Then
        Return $color_picked
    Else
        SetError(-4)
        Return -1
    EndIf
EndFunc

#cs
    changes        [since release]

    1.8.1

    *    maintenance release - non-code changes only.

    1.8

    *    fixed picker image install bug, no  really.
    *    last if the include paths is now relative I upgraded to the latest AutoIt
        Wrapper, and the extra icons worked! Ensure you are using at least v1.9.3
        of AutoIt wrapper. YOu should be able to compile the source pack now with
        zero editing.

    1.7.9

    *    bugfix to the cpc_ButtCopyColor()function
    *    fixed incorrect ini path entry

    1.7.8
    *    made include paths relative
    *    notes updates

    1.7.7
    *    documentation updates and typo fixes
    *    cleaned up a couple of sections

    1.7.6
    *    added page URL to about box (and made the page!)



#ce


; compiler directives..
;
#Region
; AutoIt3Wrapper settings..
#AutoIt3Wrapper_Icon = img\chooser.ico
#AutoIt3Wrapper_Res_Icon_Add = img\icons\grad.ico
#AutoIt3Wrapper_Res_Icon_Add = img\icons\mag.ico
#AutoIt3Wrapper_Res_Icon_Add = img\icons\hex.ico
; free-form resource fields (max 15)..
#AutoIt3Wrapper_Res_Field = Author|(or
#AutoIt3Wrapper_Res_Field = Compiled|%date% - %time%
#AutoIt3Wrapper_Res_Field = URL|http://corz.org/windows/software/color-pickin-chooser/
; application's resource info..
#AutoIt3Wrapper_Res_Comment = a color chooser
#AutoIt3Wrapper_Res_Description = corz color pickin chooser
#AutoIt3Wrapper_Res_Fileversion = 1.8.1
#EndRegion

Welcome to corz.org!

I'm always messing around with the back-end.. See a bug? Wait a minute and try again. Still see a bug? Mail Me!