Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
MKadaner committed Jan 13, 2024
1 parent 7d1f71c commit 8839de5
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 29 deletions.
99 changes: 72 additions & 27 deletions far/vmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ namespace
}
}

struct list_hpos_classifier
struct list_hpos_discriminator
{
void accumulate(const int HPos, const int Length)
{
Expand Down Expand Up @@ -2126,7 +2126,26 @@ int VMenu::VisualPosToReal(int VPos) const

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

EnBlocHScrollMode = false;
EnBlocHScrollDiscriminator = std::nullopt;

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 (SetItemSmartHPos(Item, NewHPos, TextAreaWidth, Policy))
NeedRedraw = true;
}

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

bool VMenu::SetCurItemSmartHPos(int NewHPos)
Expand All @@ -2136,7 +2155,45 @@ bool VMenu::SetCurItemSmartHPos(int NewHPos)

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

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

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

bool NeedRedraw{};

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;
}


}

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

// if (SetItemSmartHPos(Item, NewHPos, TextAreaWidth, Policy))
// NeedRedraw = true;
//}

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

bool VMenu::ShiftCurItemHPos(int Shift)
Expand All @@ -2150,13 +2207,8 @@ bool VMenu::AlignAnnotations()
if (TextAreaWidth <= 0 || TextAreaWidth + 2 <= 0) return false;
const auto AlignPos{ (TextAreaWidth + 2) / 4 };

// TBD: Should be enum: EnBlocOff, EnBlocOn, EnBlocOfflimitLeft, EnBlocOfflimit
EnBlocHScrollMode = true;
EnBlocHScrollOffLimit = 0;

bool NeedRedraw{};
int MaxLeftOffLimit{}; // <= 1; 1 means no items are off the text area LEFT edge
int MinRightOffLimit{}; // >= (-1); (-1) means no items are off the text area RIGHT edge
list_hpos_discriminator Discriminator;

for (auto& Item : Items)
{
Expand All @@ -2167,15 +2219,17 @@ bool VMenu::AlignAnnotations()

const auto NewHPos{ Item.Annotations.empty() ? 0 : AlignPos - Item.Annotations.front().first };

MaxLeftOffLimit = std::max(MaxLeftOffLimit, std::max(0, NewHPos + ItemLength));
MinRightOffLimit = std::min(MinRightOffLimit, std::max(0, NewHPos - TextAreaWidth));
Discriminator.accumulate(NewHPos, ItemLength);

if (Item.HPos == NewHPos) continue;

Item.HPos = NewHPos;
NeedRedraw = true;
}

EnBlocHScrollMode = true;
EnBlocHScrollDiscriminator = Discriminator.classify();

if (NeedRedraw) SetMenuFlags(VMENU_UPDATEREQUIRED);
return NeedRedraw;
}
Expand All @@ -2202,6 +2256,7 @@ bool VMenu::AlignAnnotations()

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

const auto HPosLimits{ item_hpos_limits(Policy, ItemLength, static_cast<int>(m_MaxItemLength), TextAreaWidth) };
Expand All @@ -2211,7 +2266,6 @@ bool VMenu::SetItemAbsoluteHPos(MenuItemEx& Item, const int NewHPos, const int I
return false;

Item.HPos = ClampedHPos;
VMFlags.Set(VMENU_UPDATEREQUIRED);
return true;
}

Expand All @@ -2232,17 +2286,6 @@ bool VMenu::ShiftItemHPos(MenuItemEx& Item, const int Shift, const int TextAreaW
return SetItemAbsoluteHPos(Item, Item.HPos + Shift, TextAreaWidth, Policy);
}

bool VMenu::SetAllItemsSmartHPos(const int NewHPos, const item_hscroll_policy Policy)
{
const auto TextAreaWidth{ CalculateTextAreaWidth() };

return std::accumulate(Items.begin(), Items.end(), false, [&](const bool NeedRedraw, MenuItemEx& Item)
{
return SetItemSmartHPos(Item, NewHPos, TextAreaWidth, Policy)
|| NeedRedraw;
});
}

bool VMenu::ShiftAllItemsHPos(const int Shift, const item_hscroll_policy Policy)
{
const auto TextAreaWidth{ CalculateTextAreaWidth() };
Expand Down Expand Up @@ -3477,8 +3520,10 @@ TEST_CASE("list.hpos.classifier")
{ { { 1, 1 } }, 1 },
{ { { 1, 3 } }, 1 },
{ { { 3, 1 } }, 3 },
{ { { -5, 2 }, { -5, 4 } }, -1 },
{ { { -5, 2 }, { -7, 6 } }, -1 },
{ { { 1, 3 }, { 3, 5 } }, 1 },
{ { { -5, 2 }, { 3, 5 } }, std::nullopt },
{ { { 1, 3 }, { -5, 4 } }, std::nullopt },
{ { { -5, 2 }, { -5, 4 }, { 3, 5 } }, std::nullopt },
{ { { 1, 3 }, { 3, 5 }, { -5, 4 } }, std::nullopt },
{ { { -5, 2 }, { 3, 5 }, { -5, 4 } }, std::nullopt },
Expand All @@ -3495,14 +3540,14 @@ TEST_CASE("list.hpos.classifier")

for (const auto& TestDataPoint : TestDataPoints)
{
list_hpos_classifier Classifier;
list_hpos_discriminator Discriminator;

for (const auto& Item : TestDataPoint.Items)
{
Classifier.accumulate(Item.first, Item.second);
Discriminator.accumulate(Item.first, Item.second);
}

REQUIRE(TestDataPoint.Expected == Classifier.classify());
REQUIRE(TestDataPoint.Expected == Discriminator.classify());
}
}

Expand Down
3 changes: 1 addition & 2 deletions far/vmenu.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,6 @@ class VMenu final: public Modal
[[nodiscard]] bool SetItemSmartHPos(MenuItemEx& Item, int NewHPos, int TextAreaWidth, item_hscroll_policy Policy);
// Shifts item's HPos; if Shift is positive, the item visually moves right
[[nodiscard]] bool ShiftItemHPos(MenuItemEx& Item, int Shift, int TextAreaWidth, item_hscroll_policy Policy);
[[nodiscard]] bool SetAllItemsSmartHPos(int NewHPos, item_hscroll_policy Policy);
[[nodiscard]] bool ShiftAllItemsHPos(int Shift, item_hscroll_policy Policy);

void UpdateMaxLengthFromTitles();
Expand Down Expand Up @@ -350,7 +349,7 @@ class VMenu final: public Modal
vmenu_colors_t Colors{};
bool bRightBtnPressed{};
bool EnBlocHScrollMode{};
int EnBlocHScrollOffLimit{};
std::optional<int> EnBlocHScrollDiscriminator{};
UUID MenuId;
};

Expand Down

0 comments on commit 8839de5

Please sign in to comment.