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

Touch control #77

Open
wants to merge 55 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 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
10cfcec
Simplify scrolling limits
XITRIX Mar 19, 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
cdd150e
Mouse scrolling
XITRIX Mar 28, 2021
859990c
Merge branch 'main' into Touch-control
XITRIX Mar 28, 2021
c8597c4
Fix blink on mouse scroll
XITRIX Mar 28, 2021
9eea766
Fix scroll failed state chech
XITRIX Mar 29, 2021
cab3ac6
Review fixes
XITRIX Apr 4, 2021
1d39f59
Merge remote-tracking branch 'origin/main' into Touch-control
XITRIX Apr 6, 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
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
9 changes: 8 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,7 +43,7 @@
#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>
Expand All @@ -51,3 +53,8 @@
#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
1 change: 1 addition & 0 deletions 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
110 changes: 110 additions & 0 deletions library/include/borealis/core/geometry.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
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();
};

} // namespace brls
94 changes: 94 additions & 0 deletions library/include/borealis/core/gesture.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
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 <borealis/core/audio.hpp>
#include <borealis/core/input.hpp>
#include <functional>

namespace brls
{

class View;

// Represents current gesture state
enum class GestureState
{
INTERRUPTED, // Gesture has been interupted, no callbacks will come
UNSURE, // Gesture started recognition and not sure if it should interupt other recognizers
START, // Gesture sure that it match to conditions and will interupt other recognizers
STAY, // Gesture in process, user still hold finger on screen
END, // User released their finger from screen, final frame of gesture
FAILED, // Gesture failed conditions
};

/*
* Superclass for all recognizers
*
* To create a new type of gesture recognizer, you should implement
* recognitionLoop method.
*
* It should contain logic with changing gesture's state.
* Recognizers' first state is UNSURE, in that state calling stack cannot tell
* which gesture user tries to apply. I.E. user puts and holds finger on the screen, so it can't be
* told whether it's going to be a tap or a swipe
*
* If gesture has been recognized, change its state to START, but ONLY for the first frame,
* on the next frame it should be changed to STAY and remain the same until the end, then it
* should change state to END.
*
* When any recognizer changes its state to START, it sends an interrupt event to every recognizer in the stack,
* so don't forget to handle that case.
*
* If gesture does not apply to recognizer's pattern, change its state to FAILED.
* It could also be used as a placerholder when recognizer is not in use.
*
* Use touch argument to get current state of touch.
*
* View argument contains the view to which this recognizer is attached.
*
* Use soundToPlay pointer to set sound which will be played in current frame.
* Leave it empty or use SOUND_NONE to not play any sound.
*/
class GestureRecognizer
XITRIX marked this conversation as resolved.
Show resolved Hide resolved
{
public:
virtual ~GestureRecognizer() { }

// Main recognition loop, for internal usage only, should not be called anywhere, but Application
XITRIX marked this conversation as resolved.
Show resolved Hide resolved
virtual GestureState recognitionLoop(TouchState touch, View* view, Sound* soundToPlay);

// Interrupt this recognizer
// If onlyIfUnsureState == true recognizer will be interupted
// only if current state is UNSURE
void interrupt(bool onlyIfUnsureState);

// If false, this recognizer will be skipped
bool isEnabled() const { return this->enabled; }

// If false, this recognizer will be skipped
void setEnabled(bool enabled) { this->enabled = enabled; }

// Get the current state of recognizer
GestureState getState() const { return state; }

protected:
GestureState state = GestureState::FAILED;
bool enabled = true;
};

} // namespace brls
Loading