Feature/scroll indication (#3)

Add scroll arrows when there are more items in the list than the list can show at a time.

These arrows can be shown in the main menu (although there aren't enough items in there to have them shown) or in the various DistributionEventPokemonListScene menus.

I also did provisions to support the same for the ScrollWidget in the about screen. Although I haven't implemented that (yet?)
This commit is contained in:
Philippe Symons
2024-08-22 21:45:31 +02:00
committed by GitHub
parent bc7733cc36
commit 90bb9ccceb
14 changed files with 361 additions and 54 deletions

View File

@@ -3,13 +3,13 @@
#include <libdragon.h>
enum class UINavigationKey
enum class UINavigationDirection
{
NONE,
UP,
RIGHT,
DOWN,
LEFT
LEFT,
MAX
};
enum class NavigationInputSourceType
@@ -24,6 +24,6 @@ enum class NavigationInputSourceType
* This function determines whether the joypad_inputs_t has analog or dpad positions/presses that could be considered for UI navigation.
* If so, it will return the most prominent direction.
*/
const UINavigationKey determineUINavigationKey(joypad_inputs_t inputs, NavigationInputSourceType sourceType);
const UINavigationDirection determineUINavigationDirection(joypad_inputs_t inputs, NavigationInputSourceType sourceType);
#endif

View File

@@ -3,11 +3,13 @@
#include "scenes/SceneWithDialogWidget.h"
#include "widget/VerticalList.h"
#include "widget/ImageWidget.h"
#include "widget/DialogWidget.h"
#include "widget/CursorWidget.h"
#include "widget/MenuItemWidget.h"
#include "widget/ListItemFiller.h"
#include "widget/IFocusListener.h"
#include "widget/IScrollWindowListener.h"
typedef struct MenuSceneContext
{
@@ -20,7 +22,7 @@ typedef struct MenuSceneContext
* @brief A scene showing a menu
*
*/
class MenuScene : public SceneWithDialogWidget, public IFocusListener
class MenuScene : public SceneWithDialogWidget, public IFocusListener, public IScrollWindowListener
{
public:
MenuScene(SceneDependencies& deps, void* context);
@@ -36,6 +38,7 @@ public:
virtual void onDialogDone();
void focusChanged(const FocusChangeStatus& status) override;
void onScrollWindowChanged(const ScrollWindowUpdate& update) override;
SceneDependencies& getDependencies();
@@ -47,7 +50,11 @@ protected:
MenuSceneContext* context_;
sprite_t* menu9SliceSprite_;
sprite_t* cursorSprite_;
sprite_t* uiArrowUpSprite_;
sprite_t* uiArrowDownSprite_;
VerticalList menuList_;
ImageWidget scrollArrowUp_;
ImageWidget scrollArrowDown_;
CursorWidget cursorWidget_;
ListItemFiller<VerticalList, MenuItemData, MenuItemWidget, MenuItemStyle> menuListFiller_;
WidgetFocusChainSegment listFocusChainSegment_;

View File

@@ -0,0 +1,54 @@
#ifndef ISCROLLWINDOWLISTENER_H
#define ISCROLLWINDOWLISTENER_H
#include "core/common.h"
#include "core/DragonUtils.h"
/**
* This struct contains the various things to know about the scroll window
* when it has been changed.
*/
typedef struct ScrollWindowUpdate
{
/**
* The coords and size of the scroll window relative to the widget
* that implements the scrolling
*/
Rectangle scrollWindowRectangle;
/**
* The total size of the panel containing all of the widgets in the scrolling widget.
* this includes the parts that aren't visible (because they're not in the scroll window)
*/
Dimensions totalSize;
} ScrollWindowUpdate;
bool canScrollTo(const ScrollWindowUpdate& info, UINavigationDirection direction);
/**
* This class allows you to react to changes to the scroll window of a widget.
* This is useful for showing UI indications like scrollbars or "more" arrows
*/
class IScrollWindowListener
{
public:
virtual ~IScrollWindowListener();
virtual void onScrollWindowChanged(const ScrollWindowUpdate& update) = 0;
protected:
private:
};
/**
* Test implementation that will just print the scroll window update
*/
class TestScrollWindowListener : public IScrollWindowListener
{
public:
virtual ~TestScrollWindowListener();
void onScrollWindowChanged(const ScrollWindowUpdate& update) override;
protected:
private:
};
#endif

View File

@@ -5,11 +5,13 @@
#include "animations/IAnimation.h"
#include <vector>
typedef std::vector<IWidget*> WidgetList;
class IScrollWindowListener;
class ScrollWidget;
class AnimationManager;
typedef std::vector<IWidget*> WidgetList;
typedef std::vector<IScrollWindowListener*> ScrollWindowListenerList;
typedef struct ScrollWidgetStyle
{
// it defines the amount of pixels we should scroll when the analog stick or dpad is used.
@@ -84,16 +86,8 @@ public:
*/
void setWindowStart(const Point& windowStart);
/**
* @brief Indicates the percentage at which the current window position is at horizontally
* in relation to the entire window
*/
float getWindowProgressX() const;
/**
* @brief Indicates the percentage at which the current window position is at vertically
* in relation to the entire window
*/
float getWindowProgressY() const;
void registerScrollWindowListener(IScrollWindowListener* listener);
void unregisterScrollWindowListener(IScrollWindowListener* listener);
protected:
private:
/**
@@ -107,8 +101,11 @@ private:
*/
void recalculateWindowSize();
void notifyScrollWindowListeners();
MoveScrollWidgetWindowAnimation windowAnimation_;
WidgetList widgets_;
ScrollWindowListenerList scrollWindowListeners_;
ScrollWidgetStyle style_;
AnimationManager& animManager_;
Rectangle bounds_;

View File

@@ -11,13 +11,14 @@ class RDPQGraphics;
class IWidget;
class VerticalList;
class AnimationManager;
struct FocusChangeStatus;
class IFocusListener;
class IScrollWindowListener;
typedef std::vector<IWidget*> IWidgetList;
typedef std::vector<Rectangle> WidgetBoundsList;
struct FocusChangeStatus;
class IFocusListener;
typedef std::vector<IFocusListener*> FocusListenerList;
typedef std::vector<IScrollWindowListener*> ScrollWindowListenerList;
/**
* @brief This Animation implementation is used internal in VerticalList
@@ -138,6 +139,7 @@ public:
bool focusPrevious();
void addWidget(IWidget* widget);
void removeWidget(IWidget* widget);
void clearWidgets();
VerticalListStyle& getStyle();
@@ -160,6 +162,10 @@ public:
void registerFocusListener(IFocusListener* listener);
void unregisterFocusListener(IFocusListener* listener);
void registerScrollWindowListener(IScrollWindowListener* listener);
void unregisterScrollWindowListener(IScrollWindowListener* listener);
void notifyScrollWindowListeners();
protected:
private:
void rebuildLayout();
@@ -176,6 +182,7 @@ private:
IWidgetList widgetList_;
WidgetBoundsList widgetBoundsList_;
FocusListenerList focusListeners_;
ScrollWindowListenerList scrollWindowListeners_;
VerticalListStyle listStyle_;
Rectangle bounds_;
uint32_t windowMinY_;