[FarGroup/FarManager] master: Color dialog improvements (0b0d518b5)

0 views
Skip to first unread message

farg...@farmanager.com

unread,
Feb 24, 2026, 7:00:58 PM (2 days ago) Feb 24
to farco...@googlegroups.com
Repository : https://github.com/FarGroup/FarManager
On branch : master
Link : https://github.com/FarGroup/FarManager/commit/0b0d518b5c3d2ada47df17a8dc40627b1594de1c

>---------------------------------------------------------------

commit 0b0d518b5c3d2ada47df17a8dc40627b1594de1c
Author: Alex Alabuzhev <alab...@gmail.com>
Date: Tue Feb 24 23:46:55 2026 +0000

Color dialog improvements


>---------------------------------------------------------------

0b0d518b5c3d2ada47df17a8dc40627b1594de1c
far/changelog | 5 ++++
far/color_picker_256.cpp | 30 +++++++++++++++++++++--
far/color_picker_common.hpp | 10 ++------
far/color_picker_rgb.cpp | 58 ++++++++++++++++++++++++++++++++++++++++-----
far/vbuild.m4 | 2 +-
5 files changed, 88 insertions(+), 17 deletions(-)

diff --git a/far/changelog b/far/changelog
index 8a96c343f..738c2fe5d 100644
--- a/far/changelog
+++ b/far/changelog
@@ -1,3 +1,8 @@
+--------------------------------------------------------------------------------
+drkns 2026-02-24 23:46:38+00:00 - build 6648
+
+1. Color dialog improvements.
+
--------------------------------------------------------------------------------
drkns 2026-02-23 18:17:42+00:00 - build 6647

diff --git a/far/color_picker_256.cpp b/far/color_picker_256.cpp
index 97519f448..96f163655 100644
--- a/far/color_picker_256.cpp
+++ b/far/color_picker_256.cpp
@@ -234,6 +234,8 @@ struct color_256_state

uint8_t CurColor{};

+ uint8_t rgb::* ZAxis{ &rgb::r };
+
cube_data<cube> Cube;

static auto channel_value(uint8_t const Channel)
@@ -316,6 +318,14 @@ intptr_t color_256_state::GetColorDlgProc(Dialog* Dlg, intptr_t Msg, intptr_t Pa
return true;
}

+ case cd_text_slice:
+ {
+ rgb RGB = {};
+ std::invoke(ZAxis, RGB) = cube_size - 1;
+ Colors.Colors[0] = Console256ColorToFarColor({ static_cast<uint8_t>(colors::invert(RGB, true)), RGB });
+ return true;
+ }
+
case cd_text_r:
case cd_text_g:
case cd_text_b:
@@ -390,7 +400,18 @@ intptr_t color_256_state::GetColorDlgProc(Dialog* Dlg, intptr_t Msg, intptr_t Pa
}
}

- Dlg->SendMessage(DM_SETTEXTPTR, cd_text_slice, UNSAFE_CSTR(Cube.slice_str()));
+ SCOPED_ACTION(Dialog::suppress_redraw)(Dlg);
+
+ rgb const CubeA = cube_color(Cube.Cube[0][0][0]), CubeB = cube_color(Cube.Cube[1][0][0]);
+ ZAxis = CubeA.r != CubeB.r? &rgb::r : CubeA.g != CubeB.g? &rgb::g : &rgb::b;
+
+ const auto IsInverted = std::invoke(ZAxis, CubeA) > std::invoke(ZAxis, CubeB);
+ const auto Slice = IsInverted? cube_size - 1 - Cube.Slice : Cube.Slice;
+
+ Dlg->SendMessage(DM_SETTEXTPTR, cd_text_slice, UNSAFE_CSTR(channel_value(Slice)));
+
+ Dlg->SendMessage(DM_ENABLE, cd_button_minus, ToPtr(Slice != (IsInverted? cube_size - 1 : 0)));
+ Dlg->SendMessage(DM_ENABLE, cd_button_plus, ToPtr(Slice != (IsInverted? 0 : cube_size - 1)));

Dlg->SendMessage(DM_REDRAW, 0, {});
}
@@ -491,7 +512,12 @@ bool pick_color_256(uint8_t& Color)
ColorDlg[ControlId].Flags |= DIF_FOCUS;
}

- ColorDlg[cd_text_slice].strData = ColorState.Cube.slice_str();
+ ColorDlg[cd_text_slice].strData = ColorState.channel_value(ColorState.Cube.Slice);
+
+ if (!ColorState.Cube.Slice)
+ ColorDlg[cd_button_minus].Flags |= DIF_DISABLE;
+ else if (ColorState.Cube.Slice == cube_size - 1)
+ ColorDlg[cd_button_plus].Flags |= DIF_DISABLE;

const auto Dlg = Dialog::create(ColorDlg, std::bind_front(&color_256_state::GetColorDlgProc, &ColorState));

diff --git a/far/color_picker_common.hpp b/far/color_picker_common.hpp
index 3103a3899..e591eaf5e 100644
--- a/far/color_picker_common.hpp
+++ b/far/color_picker_common.hpp
@@ -58,7 +58,6 @@ namespace color_picker_common
using row = std::array<cell, Size>;
using plane = std::array<row, Size>;
using cube = std::array<plane, Size>;
-
};

enum class axis
@@ -191,11 +190,6 @@ namespace color_picker_common
{
cube Cube;
uint8_t Slice{}, Index{};
-
- auto slice_str() const
- {
- return far::format(L"{:X}"sv, Slice);
- }
};

template<typename cube_data, typename dialog_items>
@@ -380,12 +374,12 @@ namespace color_picker_common
{ DI_BUTTON, {{x+3, y+2}, {0, y+2}}, DIF_NOBRACKETS, L"[▼]"sv, }, \
{ DI_BUTTON, {{x+3, y+1}, {0, y+1}}, DIF_NOBRACKETS, L"[⌂]"sv, }, \
{ DI_BUTTON, {{x+0, y+4}, {0, y+4}}, DIF_NOBRACKETS, L"[-]"sv, }, \
- { DI_TEXT, {{x+4, y+4}, {0, y+4}}, }, \
+ { DI_TEXT, {{x+3, y+4}, {0, y+4}}, }, \
{ DI_BUTTON, {{x+6, y+4}, {0, y+4}}, DIF_NOBRACKETS, L"[+]"sv, }


#define SCROLL_CONTROL(x, y) \
- { DI_TEXT, {{x, y+0}, {0, y+0}}, DIF_NONE, L" 0"sv, }, \
+ { DI_TEXT, {{x, y+0}, {0, y+0}}, }, \
{ DI_BUTTON, {{x, y+1}, {0, y+1}}, DIF_NOBRACKETS, L"[▲]"sv, }, \
{ DI_BUTTON, {{x, y+2}, {0, y+2}}, DIF_NOBRACKETS, L"[▼]"sv, }

diff --git a/far/color_picker_rgb.cpp b/far/color_picker_rgb.cpp
index 8506efe92..78415eb6e 100644
--- a/far/color_picker_rgb.cpp
+++ b/far/color_picker_rgb.cpp
@@ -129,7 +129,7 @@ enum color_rgb_dialog_items
cd_cube_last = cd_cube_first + 255,

cd_custom_first,
- cd_custom_last = cd_custom_first + 16 - 1,
+ cd_custom_last = cd_custom_first + cube_size - 1,

cd_button_up,
cd_button_left,
@@ -176,6 +176,9 @@ struct color_rgb_state

COLORREF CurColor{};

+ uint8_t rgb::* ZAxis{ &rgb::r };
+ uint8_t rgb::* OuterZAxis{ &rgb::r };
+
cube_data<cube> Cube, OuterCube;

bool IsZoomed{};
@@ -207,7 +210,7 @@ struct color_rgb_state
static rgb cube_rgb(cube const& Cube, uint8_t const x, uint8_t const y, uint8_t const z, bool const IsZoomed)
{
const auto CellIndex = Cube[z][y][x];
- const auto Multiplier = IsZoomed? 1 : 16;
+ const auto Multiplier = IsZoomed? 1 : cube_size;

return
{
@@ -296,6 +299,18 @@ static void init_cube(color_rgb_state& ColorState)
}
}

+static auto get_z_axis(cube_data<cube> const& Data, bool const IsZoomed)
+{
+ const auto
+ CubeA = cube_rgb(Data.Cube, 0, 0, 0, IsZoomed),
+ CubeB = cube_rgb(Data.Cube, 0, 0, 1, IsZoomed);
+
+ const auto ZAxis = CubeA.r != CubeB.r? &rgb::r : CubeA.g != CubeB.g? &rgb::g : &rgb::b;
+ const auto IsInverted = std::invoke(ZAxis, CubeA) > std::invoke(ZAxis, CubeB);
+
+ return std::pair{ ZAxis, IsInverted };
+}
+
static void zoom(Dialog* const Dlg, color_rgb_state& ColorState)
{
const auto ZoomingIn = !ColorState.IsZoomed;
@@ -304,7 +319,9 @@ static void zoom(Dialog* const Dlg, color_rgb_state& ColorState)
{
ColorState.OuterCube = ColorState.Cube;

- ColorState.Cube.Slice = 0;
+ const auto [ZAxis, IsInverted] = get_z_axis(ColorState.OuterCube, false);
+
+ ColorState.Cube.Slice = IsInverted? cube_size - 1 : 0;
ColorState.Cube.Index = 0;

ColorState.Overlay.set();
@@ -432,6 +449,14 @@ intptr_t color_rgb_state::GetColorDlgProc(Dialog* Dlg, intptr_t Msg, intptr_t Pa
return true;
}

+ case cd_text_slice:
+ {
+ rgb RGB = {};
+ std::invoke(ZAxis, RGB) = 0xFF;
+ Colors.Colors[0] = TrueColorToFarColor(colors::to_color(RGB));
+ return true;
+ }
+
case cd_text_r:
case cd_text_g:
case cd_text_b:
@@ -478,6 +503,7 @@ intptr_t color_rgb_state::GetColorDlgProc(Dialog* Dlg, intptr_t Msg, intptr_t Pa
switch (Button)
{
case cd_button_home:
+ IsZoomed = false;
init_cube(*this);
Cube.Slice = 0;
Dlg->SendMessage(DM_ONCUBECHANGE, 0, {});
@@ -551,7 +577,22 @@ intptr_t color_rgb_state::GetColorDlgProc(Dialog* Dlg, intptr_t Msg, intptr_t Pa
}
}

- Dlg->SendMessage(DM_SETTEXTPTR, cd_text_slice, UNSAFE_CSTR(Cube.slice_str()));
+ SCOPED_ACTION(Dialog::suppress_redraw)(Dlg);
+
+ bool IsOuterInverted, IsInverted;
+ std::tie(OuterZAxis, IsOuterInverted) = get_z_axis(Cube, false);
+ std::tie(ZAxis, IsInverted) = get_z_axis(Cube, IsZoomed);
+
+ const auto OuterMultiplier = cube_size;
+ const auto OuterValue = IsZoomed? (IsOuterInverted? cube_size - 1 - OuterCube.Slice : OuterCube.Slice) * OuterMultiplier : 0;
+ const auto Multiplier = IsZoomed? 1 : OuterMultiplier;
+ const auto Slice = IsInverted? cube_size - 1 - Cube.Slice : Cube.Slice;
+ const auto Value = Slice * Multiplier;
+
+ Dlg->SendMessage(DM_SETTEXTPTR, cd_text_slice, UNSAFE_CSTR(channel_value(OuterValue + Value)));
+
+ Dlg->SendMessage(DM_ENABLE, cd_button_minus, ToPtr(Slice != (IsInverted? cube_size - 1 : 0)));
+ Dlg->SendMessage(DM_ENABLE, cd_button_plus, ToPtr(Slice != (IsInverted? 0 : cube_size - 1)));

Dlg->SendMessage(DM_REDRAW, 0, {});
}
@@ -648,7 +689,7 @@ static bool pick_color_rgb_tui(COLORREF& Color, [[maybe_unused]] std::array<COLO

PAD_CONTROL(PadX, PadY),

- { DI_BUTTON, {{PadX+3, PadY+6}, {0, PadY+6}}, DIF_NOBRACKETS, L"[ ]"sv, },
+ { DI_BUTTON, {{PadX+3, PadY+6}, {0, PadY+6}}, DIF_NOBRACKETS, L"[↔]"sv, },

RGB_CONTROL(RGBX, RGBY),

@@ -687,7 +728,12 @@ static bool pick_color_rgb_tui(COLORREF& Color, [[maybe_unused]] std::array<COLO
if (ColorState.CurColor == colors::to_color(cube_rgb(ColorState, ColorState.Cube.Index)))
ColorDlg[ControlId].Selected = BSTATE_CHECKED;

- ColorDlg[cd_text_slice].strData = ColorState.Cube.slice_str();
+ ColorDlg[cd_text_slice].strData = ColorState.channel_value(ColorState.Cube.Slice * cube_size);
+
+ if (!ColorState.Cube.Slice)
+ ColorDlg[cd_button_minus].Flags |= DIF_DISABLE;
+ else if (ColorState.Cube.Slice == cube_size - 1)
+ ColorDlg[cd_button_plus].Flags |= DIF_DISABLE;
}

const auto Dlg = Dialog::create(ColorDlg, std::bind_front(&color_rgb_state::GetColorDlgProc, &ColorState));
diff --git a/far/vbuild.m4 b/far/vbuild.m4
index 1ef1be1cd..e0cf2b11a 100644
--- a/far/vbuild.m4
+++ b/far/vbuild.m4
@@ -1 +1 @@
-6647
+6648


Reply all
Reply to author
Forward
0 new messages