mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-01-02 10:58:45 -05:00
* Added new widget SongsListViewItem implementing ListViewWithLabels that can be added as SettingsListItem. * Changed horizontal list in pre-wakeup to vertical using that new widget.
224 lines
8.4 KiB
C++
224 lines
8.4 KiB
C++
// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#include "ListViewWithArrows.hpp"
|
|
#include "TextFixedSize.hpp"
|
|
#include "ImageBox.hpp"
|
|
#include <InputEvent.hpp>
|
|
|
|
namespace gui
|
|
{
|
|
ListViewWithArrows::ListViewWithArrows(Item *parent,
|
|
unsigned int x,
|
|
unsigned int y,
|
|
unsigned int w,
|
|
unsigned int h,
|
|
std::shared_ptr<ListItemProvider> prov)
|
|
: Rect{parent, x, y, w, h}, ListViewEngine(std::move(prov))
|
|
{
|
|
this->setEdges(RectangleEdge::None);
|
|
createLayout();
|
|
|
|
body->borderCallback = [this](const InputEvent &inputEvent) -> bool {
|
|
if (!inputEvent.isShortRelease()) {
|
|
return false;
|
|
}
|
|
if (inputEvent.is(KeyCode::KEY_UP) && pageLoaded) {
|
|
return this->requestPreviousPage();
|
|
}
|
|
else if (inputEvent.is(KeyCode::KEY_DOWN) && pageLoaded) {
|
|
return this->requestNextPage();
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
inputCallback = [&](Item &item, const InputEvent &event) { return body->onInput(event); };
|
|
|
|
focusChangedCallback = [this]([[maybe_unused]] Item &item) -> bool {
|
|
if (focus) {
|
|
setFocus();
|
|
}
|
|
else {
|
|
setFocusItem(nullptr);
|
|
}
|
|
return true;
|
|
};
|
|
|
|
body->dimensionChangedCallback = [&](gui::Item &, const BoundingBox &newDim) -> bool {
|
|
if (listOverlay->lastBox->visible && direction == listview::Direction::Top) {
|
|
if (startIndex > 1 && listOverlay->firstBox->visible) {
|
|
startIndex += 1;
|
|
}
|
|
|
|
if (startIndex == 1 && !listOverlay->firstBox->visible) {
|
|
startIndex = 0;
|
|
}
|
|
}
|
|
|
|
currentPageSize = body->getVisibleChildrenCount();
|
|
return true;
|
|
};
|
|
|
|
applyScrollCallbacks();
|
|
|
|
type = gui::ItemType::LIST;
|
|
}
|
|
|
|
void ListViewWithArrows::createLayout()
|
|
{
|
|
widgetBody = new VBox(this, 0, 0, widgetArea.w, widgetArea.h);
|
|
widgetBody->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
|
|
widgetBody->setEdges(RectangleEdge::None);
|
|
|
|
listOverlay = new VThreeBox<VBox, VBox, VBox>(widgetBody, 0, 0, 0, 0);
|
|
listOverlay->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
|
|
listOverlay->setEdges(RectangleEdge::None);
|
|
|
|
listOverlay->firstBox = new VBox(listOverlay);
|
|
listOverlay->firstBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
|
|
listOverlay->firstBox->setEdges(RectangleEdge::None);
|
|
listOverlay->firstBox->setVisible(false);
|
|
|
|
arrowTop = new ImageBox(listOverlay->firstBox, new Image("bell_arrow_top_W_M"));
|
|
arrowTop->setMinimumSizeToFitImage();
|
|
|
|
listOverlay->centerBox = new VBox(listOverlay);
|
|
listOverlay->centerBox->setAlignment(Alignment(gui::Alignment::Horizontal::Center));
|
|
listOverlay->centerBox->setEdges(RectangleEdge::None);
|
|
|
|
body = new VBox(listOverlay->centerBox);
|
|
body->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
|
|
body->setEdges(RectangleEdge::None);
|
|
|
|
listOverlay->lastBox = new VBox(listOverlay);
|
|
listOverlay->lastBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
|
|
listOverlay->lastBox->setEdges(RectangleEdge::None);
|
|
listOverlay->lastBox->setVisible(false);
|
|
|
|
arrowDown = new ImageBox(listOverlay->lastBox, new Image("bell_arrow_down_W_M"));
|
|
arrowDown->setMinimumSizeToFitImage();
|
|
}
|
|
|
|
void ListViewWithArrows::applySizeRestrictions(unsigned int w,
|
|
unsigned int h,
|
|
unsigned int outerLayoutsH,
|
|
int outerLayoutsMargin)
|
|
{
|
|
listOverlay->setMinimumSize(w, h);
|
|
body->setMaximumSize(w, h);
|
|
|
|
listOverlay->firstBox->setMinimumSize(w, outerLayoutsH);
|
|
listOverlay->centerBox->setMaximumSize(w, h);
|
|
listOverlay->centerBox->setMargins(Margins(0, outerLayoutsMargin, 0, outerLayoutsMargin));
|
|
listOverlay->lastBox->setMinimumSize(w, outerLayoutsH);
|
|
|
|
widgetBody->resizeItems();
|
|
}
|
|
|
|
void ListViewWithArrows::setListTitle(const std::string &title)
|
|
{
|
|
titleBody = new TextFixedSize(listOverlay->firstBox);
|
|
titleBody->drawUnderline(false);
|
|
titleBody->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
|
|
titleBody->setFont(style::window::font::large);
|
|
titleBody->setMinimumSize(listOverlay->firstBox->widgetMinimumArea.w,
|
|
listOverlay->firstBox->widgetMinimumArea.h);
|
|
titleBody->setEdges(RectangleEdge::None);
|
|
titleBody->setEditMode(EditMode::Browse);
|
|
titleBody->setText(title);
|
|
|
|
body->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
|
|
listOverlay->firstBox->setVisible(true);
|
|
|
|
listOverlay->resizeItems();
|
|
// Second resize is needed as we need to first apply max size for center box and next extra margins.
|
|
listOverlay->resizeItems();
|
|
|
|
arrowTop->setVisible(false);
|
|
titleBody->setVisible(true);
|
|
listOverlay->firstBox->resizeItems();
|
|
}
|
|
|
|
void ListViewWithArrows::setListTitleFont(const UTF8 &fontName)
|
|
{
|
|
titleBody->setFont(fontName);
|
|
}
|
|
|
|
void ListViewWithArrows::applyScrollCallbacks()
|
|
{
|
|
updateScrollCallback = [this](ListViewScrollUpdateData data) {
|
|
auto elementsOnPage = listOverlay->centerBox->widgetArea.h / data.elementMinimalSpaceRequired;
|
|
|
|
if (boundaries == Boundaries::Continuous) {
|
|
if (elementsOnPage == data.elementsCount) {
|
|
listOverlay->firstBox->setVisible(true);
|
|
listOverlay->lastBox->setVisible(false);
|
|
}
|
|
else if (elementsOnPage < data.elementsCount) {
|
|
listOverlay->firstBox->setVisible(true);
|
|
listOverlay->lastBox->setVisible(true);
|
|
}
|
|
else {
|
|
listOverlay->firstBox->setVisible(false);
|
|
listOverlay->lastBox->setVisible(false);
|
|
}
|
|
}
|
|
else if (boundaries == Boundaries::Fixed) {
|
|
if (elementsOnPage + data.startIndex < data.elementsCount) {
|
|
listOverlay->lastBox->setVisible(true);
|
|
}
|
|
else {
|
|
listOverlay->lastBox->setVisible(false);
|
|
}
|
|
|
|
if (data.startIndex == 0 && titleBody) {
|
|
titleBody->setVisible(true);
|
|
arrowTop->setVisible(false);
|
|
listOverlay->firstBox->setVisible(true);
|
|
}
|
|
else if (data.startIndex > 1) {
|
|
if (titleBody) {
|
|
titleBody->setVisible(false);
|
|
}
|
|
arrowTop->setVisible(true);
|
|
listOverlay->firstBox->setVisible(true);
|
|
}
|
|
else {
|
|
listOverlay->firstBox->setVisible(false);
|
|
}
|
|
}
|
|
|
|
listOverlay->resizeItems();
|
|
// Second resize is needed as we need to first apply max size for center box and next extra margins.
|
|
listOverlay->resizeItems();
|
|
};
|
|
}
|
|
|
|
void ListViewWithArrows::setFocus()
|
|
{
|
|
if (!focus) {
|
|
return;
|
|
}
|
|
setFocusItem(body);
|
|
|
|
ListViewEngine::setFocus();
|
|
}
|
|
|
|
void ListViewWithArrows::setAlignment(const Alignment &value)
|
|
{
|
|
if (body->getAlignment() != value) {
|
|
body->setAlignment(value);
|
|
}
|
|
}
|
|
|
|
bool ListViewWithArrows::onDimensionChanged(const BoundingBox &oldDim, const BoundingBox &newDim)
|
|
{
|
|
Rect::onDimensionChanged(oldDim, newDim);
|
|
body->setSize(body->getWidth(), newDim.h);
|
|
|
|
return true;
|
|
}
|
|
} /* namespace gui */
|