Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recycler view #153

Open
wants to merge 78 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
831def7
Basic touch event system
XITRIX Jan 31, 2021
cdfe9dc
Added Switch implementation
XITRIX Jan 31, 2021
72b07de
Implemented gesture recognizion system
XITRIX Feb 1, 2021
3cd8f27
Added scroll with PanGestureRecognizer
XITRIX Feb 3, 2021
a43aa87
Merge branch 'yoga' into Touch-control
XITRIX Feb 3, 2021
c66fe06
Naming fixes
XITRIX Feb 3, 2021
5d1d99d
Merge branch 'yoga' into Touch-control
XITRIX Feb 3, 2021
ff04633
Merge branch 'yoga' into Touch-control
XITRIX Feb 10, 2021
2b0b125
Merge remote-tracking branch 'Natinusala/yoga' into Touch-control
XITRIX Feb 11, 2021
35277b2
Improvements in recognition states and interruption
XITRIX Feb 12, 2021
67a9501
Some review changes and focus hiding an touch
XITRIX Feb 13, 2021
380415b
Replaced double with float
XITRIX Feb 13, 2021
2cc081d
Improved touch interactions
XITRIX Feb 13, 2021
1f0b0e9
Meson fix
XITRIX Feb 13, 2021
e06f7ef
Improved touch mode disabling
XITRIX Feb 13, 2021
009e9ad
made focusTouchMode private set
XITRIX Feb 14, 2021
a5342fb
Added scroll acceleration
XITRIX Feb 14, 2021
1314ea4
Added animation time crop on top and bottom boundaries
XITRIX Feb 14, 2021
f35f81a
Added touch focus sound
XITRIX Feb 16, 2021
b924c51
Added touch sounds
XITRIX Feb 16, 2021
f853c27
Fix view shadow on focus in touch mode.
XITRIX Feb 20, 2021
73a51dc
Merge remote-tracking branch 'Natinusala/yoga' into Touch-control
XITRIX Feb 20, 2021
24d247f
Merge remote-tracking branch 'Natinusala/yoga' into Touch-control
XITRIX Feb 20, 2021
8030aef
Moved first responder from public header
XITRIX Feb 20, 2021
0eb4c6d
Updated license
XITRIX Feb 20, 2021
7303792
Merge remote-tracking branch 'Natinusala/yoga' into Touch-control
XITRIX Feb 22, 2021
0ab5950
Replaced focusTouchMode by InputType enum
XITRIX Feb 23, 2021
49987c8
Added comments
XITRIX Feb 23, 2021
79f891d
Review changes
XITRIX Feb 23, 2021
f1f28c3
clang formatter used
XITRIX Feb 23, 2021
57c43ba
Added shouldPlayDefaultSound attribute
XITRIX Feb 25, 2021
961e3cf
Review changes
XITRIX Mar 2, 2021
6a5ff7c
Added structs for gesture callbacks
XITRIX Mar 6, 2021
e3a65bb
Merge branch 'yoga' into Touch-control
XITRIX Mar 9, 2021
a774569
Merge remote-tracking branch 'origin/main' into Touch-control
XITRIX Mar 12, 2021
154a13c
Touch improvements
XITRIX Mar 12, 2021
951effb
Format script run
XITRIX Mar 13, 2021
53c0c14
END phase position fixed
XITRIX Mar 13, 2021
55c3665
Disabled animation on scrollFrame scrolling
XITRIX Mar 13, 2021
8722f51
Added bounce effect to scroll on edges
XITRIX Mar 15, 2021
ea63223
Moved metrics to core/geometry
XITRIX Mar 15, 2021
0e2ea97
Added comments
XITRIX Mar 17, 2021
29e6b39
WIP: recycler_frame
XITRIX Mar 18, 2021
a885e3b
Format fix
XITRIX Mar 18, 2021
db3c4b7
Complete RecyclerFrame - needs refactoring
XITRIX Mar 18, 2021
10cfcec
Simplify scrolling limits
XITRIX Mar 19, 2021
a104078
Merge branch 'Touch-control' into Recycler-view
XITRIX Mar 19, 2021
0b6d650
Improved algorithm
XITRIX Mar 20, 2021
7b88f65
Switch fix
XITRIX Mar 20, 2021
8e47b53
Added padding to recycler frame
XITRIX Mar 20, 2021
fc4baf3
Added navigation inside recycler frame
XITRIX Mar 20, 2021
bf2f59f
Added cell selection data source event
XITRIX Mar 20, 2021
8029f94
Fix cells destroying
XITRIX Mar 21, 2021
8bb51a9
PR review fixes
XITRIX Mar 23, 2021
8d3ab5e
Stop scrolling on tap
XITRIX Mar 23, 2021
2b3b7bf
Merge remote-tracking branch 'origin/main' into Touch-control
XITRIX Mar 23, 2021
a2f3899
Changed sound processing
XITRIX Mar 24, 2021
f63d92c
Changed function to Event in tap recognizer
XITRIX Mar 24, 2021
d5035fe
Gesture documentation update
XITRIX Mar 24, 2021
30814fd
Merge branch 'Touch-control' into Recycler-view
XITRIX Mar 25, 2021
6946d86
Merge fix
XITRIX Mar 25, 2021
cdd150e
Mouse scrolling
XITRIX Mar 28, 2021
859990c
Merge branch 'main' into Touch-control
XITRIX Mar 28, 2021
938a284
Merge branch 'Touch-control' into Recycler-view
XITRIX Mar 28, 2021
c8597c4
Fix blink on mouse scroll
XITRIX Mar 28, 2021
cfe9fe0
Merge branch 'Touch-control' into Recycler-view
XITRIX Mar 28, 2021
cd02506
Changed behavior of scrolling in ScrollingFrame
XITRIX Mar 29, 2021
4f3c590
Added sections
XITRIX Mar 29, 2021
e580b9a
Format --fix
XITRIX Mar 29, 2021
9eea766
Fix scroll failed state chech
XITRIX Mar 29, 2021
520a862
Merge branch 'Touch-control' into Recycler-view
XITRIX Mar 29, 2021
56f3757
Fix controller navigation in scroll frame
XITRIX Apr 1, 2021
cab3ac6
Review fixes
XITRIX Apr 4, 2021
8f6c68e
Merge branch 'Touch-control' into Recycler-view
XITRIX Apr 4, 2021
0e50819
Added section headers
XITRIX Apr 4, 2021
1d39f59
Merge remote-tracking branch 'origin/main' into Touch-control
XITRIX Apr 6, 2021
696fc0b
Merge branch 'Touch-control' into Recycler-view
XITRIX Apr 6, 2021
94a85e7
fixed view's freeing
XITRIX May 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions demo/captioned_image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ CaptionedImage::CaptionedImage()
this->forwardXMLAttribute("imageHeight", this->image, "height");

this->forwardXMLAttribute("caption", this->label, "text");

this->addGestureRecognizer(new brls::TapGestureRecognizer(this, brls::TapGestureConfig(false, brls::SOUND_NONE, brls::SOUND_NONE, brls::SOUND_NONE)));
}

void CaptionedImage::onChildFocusGained(brls::View* directChild, brls::View* focusedView)
Expand Down
49 changes: 49 additions & 0 deletions demo/recycling_list_tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,59 @@

#include "recycling_list_tab.hpp"

RecyclerCell::RecyclerCell()
{
this->inflateFromXMLRes("xml/cells/cell.xml");
}

RecyclerCell* RecyclerCell::create()
{
return new RecyclerCell();
}

// DATA SOURCE

int DataSource::numberOfSections(brls::RecyclerFrame* recycler)
{
return 3;
}

int DataSource::numberOfRows(brls::RecyclerFrame* recycler, int section)
{
return 10;
}

std::string DataSource::titleForHeader(brls::RecyclerFrame* recycler, int section)
{
if (section == 0)
return "";
return "Section #" + std::to_string(section+1);
}

brls::RecyclerCell* DataSource::cellForRow(brls::RecyclerFrame* recycler, brls::IndexPath indexPath)
{
RecyclerCell* item = (RecyclerCell*)recycler->dequeueReusableCell("Cell");
item->label->setText("Item Section: " + std::to_string(indexPath.section) + ", Row: " + std::to_string(indexPath.row));
if (indexPath.row == 7)
item->label->setText("Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.");
return item;
}

void DataSource::didSelectRowAt(brls::RecyclerFrame* recycler, brls::IndexPath index)
{
brls::Logger::info("Item Index(" + std::to_string(index.section) + ":" + std::to_string(index.row) + ") selected.");
}

// RECYCLER VIEW

RecyclingListTab::RecyclingListTab()
{
// Inflate the tab from the XML file
this->inflateFromXMLRes("xml/tabs/recycling_list.xml");

recycler->registerCell("Header", []() { return RecyclerHeader::create(); });
recycler->registerCell("Cell", []() { return RecyclerCell::create(); });
recycler->setDataSource(new DataSource());
}

brls::View* RecyclingListTab::create()
Expand Down
31 changes: 31 additions & 0 deletions demo/recycling_list_tab.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,41 @@

#include <borealis.hpp>

class RecyclerHeader
: public brls::RecyclerHeader
{
};

class RecyclerCell
: public brls::RecyclerCell
{
public:
RecyclerCell();

BRLS_BIND(brls::Rectangle, accent, "brls/sidebar/item_accent");
BRLS_BIND(brls::Label, label, "brls/sidebar/item_label");

static RecyclerCell* create();
};

class DataSource
: public brls::RecyclerDataSource
{
public:
int numberOfSections(brls::RecyclerFrame* recycler) override;
int numberOfRows(brls::RecyclerFrame* recycler, int section) override;
brls::RecyclerCell* cellForRow(brls::RecyclerFrame* recycler, brls::IndexPath index) override;
void didSelectRowAt(brls::RecyclerFrame* recycler, brls::IndexPath indexPath) override;
std::string titleForHeader(brls::RecyclerFrame* recycler, int section) override;
};

class RecyclingListTab : public brls::Box
{
public:
RecyclingListTab();

static brls::View* create();

private:
BRLS_BIND(brls::RecyclerFrame, recycler, "recycler");
};
1 change: 1 addition & 0 deletions library/borealis.mk
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ include $(TOPDIR)/$(current_dir)/lib/extern/switch-libpulsar/deps.mk

SOURCES := $(SOURCES) \
$(current_dir)/lib/core \
$(current_dir)/lib/core/touch \
$(current_dir)/lib/views \
$(current_dir)/lib/platforms/switch \
$(current_dir)/lib/extern/glad \
Expand Down
10 changes: 9 additions & 1 deletion library/include/borealis.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include <borealis/core/event.hpp>
#include <borealis/core/font.hpp>
#include <borealis/core/frame_context.hpp>
#include <borealis/core/geometry.hpp>
#include <borealis/core/gesture.hpp>
#include <borealis/core/i18n.hpp>
#include <borealis/core/input.hpp>
#include <borealis/core/logger.hpp>
Expand All @@ -41,13 +43,19 @@
#include <borealis/core/video.hpp>
#include <borealis/core/view.hpp>

//Views
// Views
#include <borealis/views/applet_frame.hpp>
#include <borealis/views/button.hpp>
#include <borealis/views/header.hpp>
#include <borealis/views/image.hpp>
#include <borealis/views/label.hpp>
#include <borealis/views/rectangle.hpp>
#include <borealis/views/recycler.hpp>
#include <borealis/views/scrolling_frame.hpp>
#include <borealis/views/sidebar.hpp>
#include <borealis/views/tab_frame.hpp>

// Gestures
#include <borealis/core/touch/pan_gesture.hpp>
#include <borealis/core/touch/scroll_gesture.hpp>
#include <borealis/core/touch/tap_gesture.hpp>
21 changes: 21 additions & 0 deletions library/include/borealis/core/application.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
Copyright 2019-2021 natinusala
Copyright 2019 p-sam
Copyright 2021 XITRIX

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -36,6 +37,13 @@
namespace brls
{

// Input types for entire app
enum class InputType
{
GAMEPAD, // Gamepad or keyboard
TOUCH, // Touch screen
};

typedef std::function<View*(void)> XMLViewCreator;

class Application
Expand Down Expand Up @@ -190,6 +198,14 @@ class Application
*/
static std::string getLocale();

/**
* Returns the current input type.
*/
inline static InputType getInputType()
{
return inputType;
}

private:
inline static bool inited = false;
inline static bool quitRequested = false;
Expand All @@ -207,6 +223,11 @@ class Application

inline static View* currentFocus;

// Return true if input type was changed
static bool setInputType(InputType type);

inline static InputType inputType = InputType::GAMEPAD;

inline static unsigned blockInputsTokens = 0; // any value > 0 means inputs are blocked

inline static std::string commonFooter = "";
Expand Down
6 changes: 4 additions & 2 deletions library/include/borealis/core/audio.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ enum Sound
SOUND_CLICK_ERROR, // played when the user clicks a disabled button / a view focused with no click action
SOUND_HONK, // honk
SOUND_CLICK_SIDEBAR, // played when a sidebar item is clicked
SOUND_TOUCH_UNFOCUS, // played when touch focus has been interrupted
SOUND_TOUCH, // played when touch doesn't require it's own click sound

_SOUND_MAX, // not an actual sound, just used to count of many sounds there are
};
Expand Down Expand Up @@ -57,7 +59,7 @@ class AudioPlayer
*
* Returns a boolean indicating if the sound has been played or not.
*/
virtual bool play(enum Sound sound) = 0;
virtual bool play(enum Sound sound, float pitch = 1) = 0;
};

// An AudioPlayer that does nothing
Expand All @@ -69,7 +71,7 @@ class NullAudioPlayer : public AudioPlayer
return false;
}

bool play(enum Sound sound) override
bool play(enum Sound sound, float pitch) override
{
return false;
}
Expand Down
4 changes: 3 additions & 1 deletion library/include/borealis/core/box.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class Box : public View

void draw(NVGcontext* vg, float x, float y, float width, float height, Style style, FrameContext* ctx) override;
View* getDefaultFocus() override;
View* hitTest(Point point) override;
View* getNextFocus(FocusDirection direction, View* currentView) override;
void willAppear(bool resetState) override;
void willDisappear(bool resetState) override;
Expand Down Expand Up @@ -92,7 +93,7 @@ class Box : public View
/**
* Removes the given view from the Box. It will be freed.
*/
virtual void removeView(View* view);
virtual void removeView(View* view, bool free = true);

/**
* Sets the padding of the view, aka the internal space to give
Expand Down Expand Up @@ -157,6 +158,7 @@ class Box : public View
void setDirection(Direction direction);

void setAxis(Axis axis);
Axis getAxis() const;

std::vector<View*>& getChildren();

Expand Down
2 changes: 1 addition & 1 deletion library/include/borealis/core/font.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ typedef std::unordered_map<std::string, int> FontStash;
class FontLoader
{
public:
virtual ~FontLoader() {}
virtual ~FontLoader() { }
/**
* Called once on init to load every font in the font stash.
*
Expand Down
116 changes: 116 additions & 0 deletions library/include/borealis/core/geometry.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
Copyright 2021 XITRIX

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#pragma once

#include <string>

namespace brls
{

// A structure that contains a point in a two-dimensional coordinate system.
struct Point
{
float x; // The x-coordinate of the point.
float y; // The y-coordinate of the point.

// Creates a point with location (0,0).
Point();

// Creates a point with coordinates specified as float values.
Point(float x, float y);

Point operator+(const Point& a) const;
Point operator-(const Point& a) const;
Point operator/(const float& a) const;
Point operator*(const float& a) const;
bool operator==(const Point& other) const;
bool operator!=(const Point& other) const;
void operator+=(const Point& a);
void operator-=(const Point& a);
};

// A structure that contains width and height values.
struct Size
{
float width; // A width value.
float height; // A height value.

// Creates a size with zero width and height.
Size();

// Creates a size with dimensions specified as float values.
Size(float width, float height);

Size operator+(const Size& a) const;
Size operator-(const Size& a) const;
Size operator/(const float& a) const;
Size operator*(const float& a) const;
bool operator==(const Size& other) const;
};

// Rect
// A structure that contains the location and dimensions of a rectangle.
struct Rect
{
Point origin; // A point that specifies the coordinates of the rectangle’s origin.
Size size; // A size that specifies the height and width of the rectangle.

// Creates a rectangle with origin (0,0) and size (0,0).
Rect();

// Creates a rectangle with the specified origin and size.
Rect(Point origin, Size size);

// Creates a rectangle with coordinates and dimensions specified as float values.
Rect(float x, float y, float width, float height);

// Returns the width of a rectangle.
float getWidth() const;
// Returns the height of a rectangle.
float getHeight() const;

// Returns the smallest value for the x-coordinate of the rectangle.
float getMinX() const;
// Returns the smallest value for the y-coordinate of the rectangle.
float getMinY() const;

// Returns the x-coordinate that establishes the center of a rectangle.
float getMidX() const;
// Returns the y-coordinate that establishes the center of the rectangle.
float getMidY() const;

// Returns the largest value of the x-coordinate for the rectangle.
float getMaxX() const;
// Returns the largest value for the y-coordinate of the rectangle.
float getMaxY() const;

bool operator==(const Rect& other) const;

// Returns true if point is inside this Rect.
bool pointInside(Point point);

// Returns string with description of current Rect.
std::string describe();

// Returns true if two rects have shared area.
bool collideWith(const Rect& other) const;

// Returns Rect with offset by presented Point.
Rect offsetBy(const Point& origin) const;
};

} // namespace brls
Loading