Skip to content

Commit

Permalink
WIP: Works?
Browse files Browse the repository at this point in the history
  • Loading branch information
MKadaner committed Jan 16, 2024
1 parent 8839de5 commit c0b83fb
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 55 deletions.
168 changes: 113 additions & 55 deletions far/vmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,19 @@ namespace
bool were_right_items() { return MinRightOffset != NonValue; }
};

int adjust_en_bloc_shift(const int Shift, const int EnBlocHScrollDiscriminator, const int TextAreaWidth)
{
assert(TextAreaWidth > 0);

if (EnBlocHScrollDiscriminator <= 0)
return Shift <= 0 ? 0 : Shift - EnBlocHScrollDiscriminator;

if (EnBlocHScrollDiscriminator >= TextAreaWidth)
return Shift >= 0 ? 0 : Shift - (EnBlocHScrollDiscriminator - TextAreaWidth);

return Shift;
}

// Indices in the color array
enum class color_indices
{
Expand Down Expand Up @@ -2124,7 +2137,7 @@ int VMenu::VisualPosToReal(int VPos) const
*/


bool VMenu::SetAllItemsSmartHPos(int NewHPos)
bool VMenu::SetAllItemsSmartHPos(const int NewHPos)
{
const auto TextAreaWidth{ CalculateTextAreaWidth() };
if (TextAreaWidth <= 0) return false;
Expand All @@ -2148,57 +2161,48 @@ bool VMenu::SetAllItemsSmartHPos(int NewHPos)
return NeedRedraw;
}

bool VMenu::SetCurItemSmartHPos(int NewHPos)
{
return false;
}

bool VMenu::ShiftAllItemsHPos(int Shift)
bool VMenu::SetCurItemSmartHPos(const int NewHPos)
{
if (!Shift) return false;

const auto TextAreaWidth{ CalculateTextAreaWidth() };
if (TextAreaWidth <= 0) return false;

//return SetItemAbsoluteHPos(Item, Item.HPos + Shift, TextAreaWidth, Policy);

bool NeedRedraw{};
const auto Policy{ CheckFlags(VMENU_ENABLEALIGNANNOTATIONS) ? item_hscroll_policy::cling_to_edge : item_hscroll_policy::bound_stick_to_left };

if (EnBlocHScrollMode && EnBlocHScrollDiscriminator)
{
if (Shift > 0)
{
if (EnBlocHScrollDiscriminator.value() >= TextAreaWidth)
return false;
if (EnBlocHScrollDiscriminator.value() <= 0)
Shift -= EnBlocHScrollDiscriminator.value();
}
else
{
if (EnBlocHScrollDiscriminator.value() <= 0)
return false;
if (EnBlocHScrollDiscriminator.value() >= TextAreaWidth)
Shift -= EnBlocHScrollDiscriminator.value() - TextAreaWidth;
}
auto& Item{ Items[SelectPos] };
if (Item.Flags & LIF_SEPARATOR) return false;

if (!SetItemSmartHPos(Item, NewHPos, TextAreaWidth, Policy)) return false;

}
SetMenuFlags(VMENU_UPDATEREQUIRED);
return true;
}

//for (auto& Item : Items)
//{
// if (Item.Flags & LIF_SEPARATOR) continue;
bool VMenu::ShiftAllItemsHPos(const int Shift)
{
const auto TextAreaWidth{ CalculateTextAreaWidth() };
if (TextAreaWidth <= 0) return false;

// if (SetItemSmartHPos(Item, NewHPos, TextAreaWidth, Policy))
// NeedRedraw = true;
//}
const auto ShiftAllItemsHPosFunc{ EnBlocHScrollMode ? &VMenu::ShiftAllItemsHPosEnBlock : &VMenu::ShiftAllItemsHPosLimited };
if (!(this->*ShiftAllItemsHPosFunc)(Shift, TextAreaWidth)) return false;

if (NeedRedraw) SetMenuFlags(VMENU_UPDATEREQUIRED);
return NeedRedraw;
SetMenuFlags(VMENU_UPDATEREQUIRED);
return true;
}

bool VMenu::ShiftCurItemHPos(int Shift)
bool VMenu::ShiftCurItemHPos(const int Shift)
{
return false;
const auto TextAreaWidth{ CalculateTextAreaWidth() };
if (TextAreaWidth <= 0) return false;

const auto Policy{ CheckFlags(VMENU_ENABLEALIGNANNOTATIONS) ? item_hscroll_policy::cling_to_edge : item_hscroll_policy::bound_stick_to_left };

auto& Item{ Items[SelectPos] };
if (Item.Flags & LIF_SEPARATOR) return false;

if (!SetItemAbsoluteHPos(Item, Item.HPos + Shift, TextAreaWidth, Policy)) return false;

SetMenuFlags(VMENU_UPDATEREQUIRED);
return true;
}

bool VMenu::AlignAnnotations()
Expand Down Expand Up @@ -2234,29 +2238,57 @@ bool VMenu::AlignAnnotations()
return NeedRedraw;
}

// TBD: Temp, not needed
//bool VMenu::SetItemAbsoluteHPos(MenuItemEx& Item, const int NewHPos)
//{
// if (ItemLength <= 0) return false;
//
// const auto HPosLimits{ item_hpos_limits(Policy, ItemLength, static_cast<int>(m_MaxItemLength), TextAreaWidth) };
// const auto ClampedHPos = std::clamp(NewHPos, HPosLimits.first, HPosLimits.second);
//
// if (Item.HPos == ClampedHPos)
// return false;
//
// Item.HPos = ClampedHPos;
// SetMenuFlags(VMENU_UPDATEREQUIRED);
// return true;
//}
bool VMenu::ShiftAllItemsHPosEnBlock(const int Shift, const int TextAreaWidth)
{
const auto AdjustedShift = EnBlocHScrollDiscriminator
? adjust_en_bloc_shift(Shift, EnBlocHScrollDiscriminator.value(), TextAreaWidth)
: Shift;
if (!AdjustedShift) return false;

bool NeedRedraw{};
list_hpos_discriminator Discriminator;

for (auto& Item : Items)
{
if (Item.Flags & LIF_SEPARATOR) continue;

const auto ItemLength{ static_cast<int>(CheckFlags(VMENU_SHOWAMPERSAND) ? visual_string_length(Item.Name) : HiStrlen(Item.Name)) };
if (ItemLength <= 0) continue;

const auto NewHPos{ Item.HPos + AdjustedShift };

Discriminator.accumulate(NewHPos, ItemLength);

if (Item.HPos == NewHPos) continue;

Item.HPos = NewHPos;
NeedRedraw = true;
}

EnBlocHScrollDiscriminator = Discriminator.classify();
return NeedRedraw;
}

bool VMenu::ShiftAllItemsHPosLimited(const int Shift, const int TextAreaWidth)
{
const auto Policy{ CheckFlags(VMENU_ENABLEALIGNANNOTATIONS) ? item_hscroll_policy::cling_to_edge : item_hscroll_policy::bound_stick_to_left };

bool NeedRedraw{};

for (auto& Item : Items)
{
if (Item.Flags & LIF_SEPARATOR) continue;

if (SetItemAbsoluteHPos(Item, Item.HPos + Shift, TextAreaWidth, Policy))
NeedRedraw = true;
}

return NeedRedraw;
}

bool VMenu::SetItemAbsoluteHPos(MenuItemEx& Item, const int NewHPos, const int ItemLength, const int TextAreaWidth, const item_hscroll_policy Policy)
{
// TBD: Not needed? (TextAreaWidth <= 0)
// TBD: (TextAreaWidth <= 0) not needed?
if (ItemLength <= 0 || TextAreaWidth <= 0) return false;

const auto HPosLimits{ item_hpos_limits(Policy, ItemLength, static_cast<int>(m_MaxItemLength), TextAreaWidth) };
Expand Down Expand Up @@ -3551,4 +3583,30 @@ TEST_CASE("list.hpos.classifier")
}
}

TEST_CASE("adjust.en.bloc.shift")
{
static constexpr int TextAreaWidth{ 10 };
static const struct test_data
{
int EnBlocHScrollDiscriminator;
std::initializer_list<std::pair<int, int>> ShiftAndExpectedList;
} TestDataPoints[] =
{
{ -5, { { 0, 0 }, { -7, 0 }, { -5, 0 }, { -1, 0 }, { 1, 6 }, { 3, 8 }, { 10, 15 }, { 15, 20 }, } },
{ 0, { { 0, 0 }, { -7, 0 }, { -5, 0 }, { -1, 0 }, { 1, 1 }, { 3, 3 }, { 10, 10 }, { 15, 15 }, } },
{ 1, { { 0, 0 }, { -7, -7 }, { -5, -5 }, { -1, -1 }, { 1, 1 }, { 3, 3 }, { 10, 10 }, { 15, 15 }, } },
{ 5, { { 0, 0 }, { -7, -7 }, { -5, -5 }, { -1, -1 }, { 1, 1 }, { 3, 3 }, { 10, 10 }, { 15, 15 }, } },
{ 10, { { 0, 0 }, { -7, -7 }, { -5, -5 }, { -1, -1 }, { 1, 0 }, { 3, 0 }, { 10, 0 }, { 15, 0 }, } },
{ 15, { { 0, 0 }, { -7, -12 }, { -5, -10 }, { -1, -6 }, { 1, 0 }, { 3, 0 }, { 10, 0 }, { 15, 0 }, } },
};

for (const auto& TestDataPoint : TestDataPoints)
{
for (const auto& ShiftAndExpected : TestDataPoint.ShiftAndExpectedList)
{
REQUIRE(ShiftAndExpected.second == adjust_en_bloc_shift(ShiftAndExpected.first, TestDataPoint.EnBlocHScrollDiscriminator, TextAreaWidth));
}
}
}

#endif
3 changes: 3 additions & 0 deletions far/vmenu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,9 @@ class VMenu final: public Modal
[[nodiscard]] bool ShiftCurItemHPos(int Shift);
[[nodiscard]] bool AlignAnnotations();

[[nodiscard]] bool ShiftAllItemsHPosEnBlock(int Shift, int TextAreaWidth);
[[nodiscard]] bool ShiftAllItemsHPosLimited(int Shift, int TextAreaWidth);



[[nodiscard]] bool SetItemAbsoluteHPos(MenuItemEx& Item, int NewHPos, int ItemLength, int TextAreaWidth, item_hscroll_policy Policy);
Expand Down

0 comments on commit c0b83fb

Please sign in to comment.