mirror of
https://github.com/DarkMatterCore/nxdumptool.git
synced 2024-11-08 11:51:48 +00:00
159 lines
5.3 KiB
C++
159 lines
5.3 KiB
C++
/*
|
|
* layered_error_frame.cpp
|
|
*
|
|
* Copyright (c) 2020-2024, DarkMatterCore <pabloacurielz@gmail.com>.
|
|
*
|
|
* This file is part of nxdumptool (https://github.com/DarkMatterCore/nxdumptool).
|
|
*
|
|
* nxdumptool is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* nxdumptool is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <layered_error_frame.hpp>
|
|
|
|
namespace nxdt::views
|
|
{
|
|
LayeredErrorFrame::LayeredErrorFrame(std::string msg) : brls::LayerView()
|
|
{
|
|
/* Error frame. */
|
|
this->error_frame = new ErrorFrame(msg);
|
|
this->addLayer(this->error_frame);
|
|
|
|
/* List. */
|
|
this->list = new brls::List();
|
|
this->addLayer(this->list);
|
|
}
|
|
|
|
void LayeredErrorFrame::SetParentSidebarItem(brls::SidebarItem *sidebar_item)
|
|
{
|
|
if (sidebar_item) this->sidebar_item = sidebar_item;
|
|
}
|
|
|
|
bool LayeredErrorFrame::IsListItemFocused(void)
|
|
{
|
|
brls::View *cur_view = brls::Application::getCurrentFocus();
|
|
size_t cur_list_count = this->list->getViewsCount();
|
|
|
|
if (cur_list_count)
|
|
{
|
|
while(cur_view)
|
|
{
|
|
if (cur_view == this->list) return true;
|
|
cur_view = cur_view->getParent();
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
int LayeredErrorFrame::GetFocusStackViewIndex(void)
|
|
{
|
|
size_t cur_list_count = this->list->getViewsCount();
|
|
std::vector<brls::View*> *focus_stack = brls::Application::getFocusStack();
|
|
|
|
if (cur_list_count && focus_stack)
|
|
{
|
|
size_t focus_stack_size = focus_stack->size();
|
|
|
|
for(size_t i = 0; i < focus_stack_size; i++)
|
|
{
|
|
for(size_t j = 0; j < cur_list_count; j++)
|
|
{
|
|
if (this->list->getChild(j) == focus_stack->at(i)) return static_cast<int>(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
bool LayeredErrorFrame::UpdateFocusStackViewAtIndex(int index, brls::View *view)
|
|
{
|
|
std::vector<brls::View*> *focus_stack = brls::Application::getFocusStack();
|
|
if (!focus_stack || index < 0 || !view) return false;
|
|
|
|
size_t focus_stack_size = focus_stack->size();
|
|
if (index >= static_cast<int>(focus_stack_size)) return false;
|
|
|
|
focus_stack->at(index) = view;
|
|
LOG_MSG_DEBUG("Focus stack updated.");
|
|
|
|
return true;
|
|
}
|
|
|
|
brls::View *LayeredErrorFrame::GetListFirstFocusableChild(void)
|
|
{
|
|
size_t cur_list_count = this->list->getViewsCount();
|
|
if (!cur_list_count) return nullptr;
|
|
|
|
for(size_t i = 0; i < cur_list_count; i++)
|
|
{
|
|
brls::View *cur_child = this->list->getChild(i);
|
|
if (cur_child && !cur_child->isHidden() && cur_child->getDefaultFocus() != nullptr) return cur_child;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void LayeredErrorFrame::SwitchLayerView(bool use_error_frame, bool update_focused_view, bool update_focus_stack)
|
|
{
|
|
int cur_index = this->getLayerIndex();
|
|
int new_index = (use_error_frame ? 0 : 1);
|
|
|
|
size_t cur_list_count = this->list->getViewsCount();
|
|
brls::View *first_child = nullptr;
|
|
|
|
int focus_stack_index = this->GetFocusStackViewIndex();
|
|
bool focus_stack_updated = false;
|
|
|
|
if (cur_list_count)
|
|
{
|
|
/* Get pointer to the first focusable/unhidden list item. */
|
|
/* Fallback to the sidebar item if there's none. */
|
|
first_child = this->GetListFirstFocusableChild();
|
|
if (!first_child) first_child = this->sidebar_item;
|
|
|
|
/* Update focus stack information, if needed. */
|
|
if (update_focus_stack && focus_stack_index > -1) focus_stack_updated = this->UpdateFocusStackViewAtIndex(focus_stack_index, use_error_frame ? this->sidebar_item : first_child);
|
|
}
|
|
|
|
if (!focus_stack_updated)
|
|
{
|
|
/* Check if the user is currently focusing a list item. */
|
|
if (!update_focused_view) update_focused_view = this->IsListItemFocused();
|
|
|
|
if (update_focused_view)
|
|
{
|
|
/* Update focused view. */
|
|
if (use_error_frame || !cur_list_count)
|
|
{
|
|
/* Move focus to the sidebar item. */
|
|
brls::Application::giveFocus(this->sidebar_item);
|
|
} else {
|
|
/* Move focus to the first list item. */
|
|
brls::Application::giveFocus(first_child);
|
|
|
|
/* Make sure to call willAppear() on our list to update the scrolling accordingly. */
|
|
this->list->willAppear(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Change layer view only if the new index is different. */
|
|
if (cur_index != new_index)
|
|
{
|
|
this->changeLayer(new_index);
|
|
this->invalidate(true);
|
|
}
|
|
}
|
|
}
|