diff options
author | Kunal <shindek@google.com> | 2020-05-04 20:25:33 -0700 |
---|---|---|
committer | Kunal <shindek@google.com> | 2020-05-07 17:07:57 -0700 |
commit | 7ed1bd4ef7cb18503e4e3a77992b0bcf24038054 (patch) | |
tree | 69764844ef2be0549727228625dc053859c57d6c | |
parent | 6efb1eb02a048ca6964abcfd876d2ada35aa80a4 (diff) | |
download | teeui-7ed1bd4ef7cb18503e4e3a77992b0bcf24038054.tar.gz |
Implementation of hit detection for teeui based layout.
Teeui layout elements need to be hit sensitive, and each element has
the hit function that can be called with touch event.Callback function
are configurable on an instantiated layout elements.
Bug: 149791997
Test: make -j TeeuiFramebufferizer &&
LD_LIBRARY_PATH=./out/host/linux-x86/lib64 TeeuiFramebufferizer
Change-Id: Idb10efa427bafa885f154dfd944b7a4c44789125
-rw-r--r-- | libteeui/example/example_utils.h | 5 | ||||
-rw-r--r-- | libteeui/example/phys_button_example.cpp | 2 | ||||
-rw-r--r-- | libteeui/example/touch_button_example.cpp | 47 | ||||
-rw-r--r-- | libteeui/include/teeui/example/example.h | 8 | ||||
-rw-r--r-- | libteeui/include/teeui/label.h | 6 | ||||
-rw-r--r-- | libteeui/include/teeui/utils.h | 14 | ||||
-rw-r--r-- | libteeui/src/label.cpp | 10 | ||||
-rw-r--r-- | libteeui_jni/include/com_android_framebufferizer_NativeRenderer.h | 8 | ||||
-rw-r--r-- | libteeui_jni/libteeui_jni.cpp | 13 | ||||
-rw-r--r-- | tools/framebufferizer/src/com/android/framebufferizer/NativeRenderer.java | 1 | ||||
-rw-r--r-- | tools/framebufferizer/src/com/android/framebufferizer/utils/FrameBufferBuffer.java | 60 |
11 files changed, 159 insertions, 15 deletions
diff --git a/libteeui/example/example_utils.h b/libteeui/example/example_utils.h index 3a4f841..568542d 100644 --- a/libteeui/example/example_utils.h +++ b/libteeui/example/example_utils.h @@ -60,6 +60,11 @@ Error drawElements(std::tuple<Elements...>& layout, const PixelDrawer& drawPixel return (std::get<Elements>(layout).draw(drawPixel) || ...); } +template <typename... Elements> +Error handleAllEvent(std::tuple<Elements...>& layout, const Event& event) { + return (std::get<Elements>(layout).hit(event) || ...); +} + void translate(LabelImpl* label); template <typename T, typename Layout> void translateLabel(Layout* layout) { diff --git a/libteeui/example/phys_button_example.cpp b/libteeui/example/phys_button_example.cpp index 5f6365e..e490925 100644 --- a/libteeui/example/phys_button_example.cpp +++ b/libteeui/example/phys_button_example.cpp @@ -55,7 +55,7 @@ class GUIStatePhysButtons : public ITeeuiExample { } uint32_t setDeviceInfo(DeviceInfo device_info, bool magnified, bool inverted = false) override; - void onEvent(uint32_t, uint32_t, uint32_t) override {} + EventResult onEvent(uint32_t, uint32_t, uint32_t) override { return EventResult::NONE; } uint32_t renderUIIntoBuffer(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t lineStride, uint32_t* buffer, diff --git a/libteeui/example/touch_button_example.cpp b/libteeui/example/touch_button_example.cpp index ab2ff4e..c909dbb 100644 --- a/libteeui/example/touch_button_example.cpp +++ b/libteeui/example/touch_button_example.cpp @@ -34,12 +34,36 @@ template <typename Layout> static void translateLabels(Layout* layout) { } class GUIStateTouch : public ITeeuiExample { + private: + bool okTapped_ = false; + bool cancelTapped_ = false; + EventResult eventResult_ = EventResult::NONE; + public: bool inverted_; std::string confirmationMessage_; layout_t<ConfUILayout> layoutInstance_ = {}; - GUIStateTouch() : inverted_(false), layoutInstance_{} {} + GUIStateTouch() : okTapped_(false), cancelTapped_(false), inverted_(false), layoutInstance_{} {} + + bool isOkTapped() const { return okTapped_; } + bool isCancelTapped() const { return cancelTapped_; } + + Error tapOk(Event e) { + if (e.event_ == EventType::KeyUp) { + okTapped_ = true; + eventResult_ = EventResult::CONFIRM; + } + return Error::OK; + } + + Error tapCancel(Event e) { + if (e.event_ == EventType::KeyUp) { + cancelTapped_ = true; + eventResult_ = EventResult::CANCEL; + } + return Error::OK; + } void selectLanguage(const char* language_id) override { teeui::localization::selectLangId(language_id); @@ -54,7 +78,7 @@ class GUIStateTouch : public ITeeuiExample { uint32_t setDeviceInfo(DeviceInfo device_info, bool magnified, bool inverted = false) override; - void onEvent(uint32_t, uint32_t, uint32_t) override {} + EventResult onEvent(uint32_t x, uint32_t y, uint32_t) override; uint32_t renderUIIntoBuffer(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t lineStride, uint32_t* buffer, @@ -65,6 +89,13 @@ std::unique_ptr<ITeeuiExample> createTeeuiExample() { return std::make_unique<GUIStateTouch>(); } +EventResult GUIStateTouch::onEvent(uint32_t x, uint32_t y, uint32_t) { + eventResult_ = EventResult::NONE; + Event event{x, y, EventType::KeyUp}; + handleAllEvent(layoutInstance_, event); + return eventResult_; +} + static context<ConfUIParameters> setLayoutParams(DeviceInfo& deviceInfo, bool magnified, bool inverted) { context<ConfUIParameters> ctx(deviceInfo.mm2px_, deviceInfo.dp2px_); @@ -95,6 +126,16 @@ uint32_t GUIStateTouch::setDeviceInfo(DeviceInfo device_info, bool magnified, bo layoutInstance_ = instantiateLayout(ConfUILayout(), setLayoutParams(device_info, magnified, inverted)); inverted_ = inverted; + std::get<LabelOK>(layoutInstance_) + .setCB(makeCallback<Error, Event>( + [](Event e, void* p) -> Error { return reinterpret_cast<GUIStateTouch*>(p)->tapOk(e); }, + this)); + std::get<LabelCancel>(layoutInstance_) + .setCB(makeCallback<Error, Event>( + [](Event e, void* p) -> Error { + return reinterpret_cast<GUIStateTouch*>(p)->tapCancel(e); + }, + this)); return 0; } @@ -142,4 +183,4 @@ uint32_t GUIStateTouch::renderUIIntoBuffer(uint32_t x, uint32_t y, uint32_t w, u } // namespace touch_button } // namespace example -} // namespace teeui
\ No newline at end of file +} // namespace teeui diff --git a/libteeui/include/teeui/example/example.h b/libteeui/include/teeui/example/example.h index 6144306..ef94651 100644 --- a/libteeui/include/teeui/example/example.h +++ b/libteeui/include/teeui/example/example.h @@ -34,6 +34,12 @@ struct DeviceInfo { double volUpButtonBottomMm_; }; +enum class EventResult : uint32_t { + NONE, + CONFIRM, + CANCEL, +}; + class ITeeuiExample { public: virtual void selectLanguage(const char*) = 0; @@ -41,7 +47,7 @@ class ITeeuiExample { virtual uint32_t setDeviceInfo(DeviceInfo, bool, bool) = 0; virtual uint32_t renderUIIntoBuffer(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t*, size_t) = 0; - virtual void onEvent(uint32_t x, uint32_t y, uint32_t) = 0; + virtual EventResult onEvent(uint32_t x, uint32_t y, uint32_t) = 0; virtual ~ITeeuiExample() {} }; diff --git a/libteeui/include/teeui/label.h b/libteeui/include/teeui/label.h index b3b9114..845922a 100644 --- a/libteeui/include/teeui/label.h +++ b/libteeui/include/teeui/label.h @@ -83,6 +83,9 @@ class LabelImpl { uint64_t textId() const { return textId_; } Error draw(const PixelDrawer& drawPixel, const Box<pxs>& bounds, LineInfo* lineInfo); + void setCB(CallbackEvent cbEvent) { cbEvent_ = std::move(cbEvent); } + optional<CallbackEvent> getCB() { return cbEvent_; } + Error hit(const Event& event, const Box<pxs>& bounds); private: pxs fontSize_; @@ -93,6 +96,7 @@ class LabelImpl { Color textColor_; FontBuffer font_; uint64_t textId_; + optional<CallbackEvent> cbEvent_; }; /** @@ -124,6 +128,8 @@ template <typename Derived> class Label : public LayoutElement<Derived>, public LabelImpl::LineInfo lineInfo = {Derived::label_number_of_lines, lines}; return LabelImpl::draw(drawPixel, this->bounds_, &lineInfo); } + + Error hit(const Event& event) { return LabelImpl::hit(event, this->bounds_); } }; } // namespace teeui diff --git a/libteeui/include/teeui/utils.h b/libteeui/include/teeui/utils.h index 33da519..985761a 100644 --- a/libteeui/include/teeui/utils.h +++ b/libteeui/include/teeui/utils.h @@ -859,6 +859,18 @@ template <typename Coord> std::ostream& operator<<(std::ostream& out, const Box< } #endif +enum class EventType : uint8_t { + KeyDown, + KeyUp, + KeyMoved, +}; + +struct Event { + uint32_t x_; + uint32_t y_; + EventType event_; +}; + template <typename Fn> struct Callback; template <typename Ret, typename... Args> struct Callback<Ret(Args...)> { @@ -883,6 +895,7 @@ template <typename Fn, typename Ret, typename... Args> struct CallbackHelper { } }; +using CallbackEvent = Callback<Error(Event)>; using PixelDrawer = Callback<Error(uint32_t, uint32_t, Color)>; template <typename Fn> @@ -901,6 +914,7 @@ template <typename Derived> struct LayoutElement { context = Derived::dim_h} {} Error draw(const PixelDrawer&) { return Error::OK; } + Error hit(const Event&) { return Error::OK; } }; template <typename... Elements, typename Context> diff --git a/libteeui/src/label.cpp b/libteeui/src/label.cpp index 8267bf2..34d8eb0 100644 --- a/libteeui/src/label.cpp +++ b/libteeui/src/label.cpp @@ -136,4 +136,14 @@ Error LabelImpl::draw(const PixelDrawer& drawPixel, const Box<pxs>& bounds, Line return Error::OK; } +Error LabelImpl::hit(const Event& event, const Box<pxs>& bounds) { + using intpxs = Coordinate<px, int64_t>; + if (bounds.contains(Point<intpxs>(event.x_, event.y_))) { + optional<CallbackEvent> callback = getCB(); + if (callback) { + return callback.value()(event); + } + } + return Error::OK; +} } // namespace teeui diff --git a/libteeui_jni/include/com_android_framebufferizer_NativeRenderer.h b/libteeui_jni/include/com_android_framebufferizer_NativeRenderer.h index 61466fc..a24b826 100644 --- a/libteeui_jni/include/com_android_framebufferizer_NativeRenderer.h +++ b/libteeui_jni/include/com_android_framebufferizer_NativeRenderer.h @@ -47,6 +47,14 @@ Java_com_android_framebufferizer_NativeRenderer_getLanguageIdList(JNIEnv*, jclas JNIEXPORT void JNICALL Java_com_android_framebufferizer_NativeRenderer_setConfimationMessage(JNIEnv*, jclass, jstring); +/* + * Class: com_android_framebufferizer_NativeRenderer + * Method: onEvent + * Signature: (III)I + */ +JNIEXPORT jint JNICALL Java_com_android_framebufferizer_NativeRenderer_onEvent(JNIEnv*, jclass, + jint, jint, jint); + #ifdef __cplusplus } #endif diff --git a/libteeui_jni/libteeui_jni.cpp b/libteeui_jni/libteeui_jni.cpp index 90be314..7f6e6fd 100644 --- a/libteeui_jni/libteeui_jni.cpp +++ b/libteeui_jni/libteeui_jni.cpp @@ -214,3 +214,16 @@ Java_com_android_framebufferizer_NativeRenderer_setConfimationMessage( JString confirmationMessage(env, jConfirmationMessage); if (sCurrentExample) sCurrentExample->setConfirmationMessage(confirmationMessage.begin()); } + +/* + * Class: com_android_framebufferizer_NativeRenderer + * Method: onEvent + * Signature: (III)I + */ +extern "C" JNIEXPORT jint JNICALL Java_com_android_framebufferizer_NativeRenderer_onEvent( + JNIEnv*, jclass, jint x, jint y, jint event) { + if (sCurrentExample) { + return (jint)sCurrentExample->onEvent((uint32_t)x, (uint32_t)y, (uint32_t)event); + } + return 0; +}
\ No newline at end of file diff --git a/tools/framebufferizer/src/com/android/framebufferizer/NativeRenderer.java b/tools/framebufferizer/src/com/android/framebufferizer/NativeRenderer.java index e0eeaa1..4a82bee 100644 --- a/tools/framebufferizer/src/com/android/framebufferizer/NativeRenderer.java +++ b/tools/framebufferizer/src/com/android/framebufferizer/NativeRenderer.java @@ -28,4 +28,5 @@ public class NativeRenderer { public static native void setLanguage(String language_id); public static native String[] getLanguageIdList(); public static native void setConfimationMessage(String confimationMessage); + public static native int onEvent(int x, int y, int event); } diff --git a/tools/framebufferizer/src/com/android/framebufferizer/utils/FrameBufferBuffer.java b/tools/framebufferizer/src/com/android/framebufferizer/utils/FrameBufferBuffer.java index 31b68ef..18991eb 100644 --- a/tools/framebufferizer/src/com/android/framebufferizer/utils/FrameBufferBuffer.java +++ b/tools/framebufferizer/src/com/android/framebufferizer/utils/FrameBufferBuffer.java @@ -17,11 +17,6 @@ package com.android.framebufferizer.utils; import com.android.framebufferizer.NativeRenderer; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.ComponentEvent; -import java.awt.event.ComponentListener; -import java.awt.event.MouseEvent; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; @@ -37,7 +32,8 @@ import javax.swing.*; import java.awt.*; import java.awt.event.*; -public class FrameBufferBuffer extends JPanel implements ComponentListener, MouseMotionListener { +public class FrameBufferBuffer extends JPanel implements ComponentListener, MouseMotionListener, + MouseListener { public class MagnifiedView extends JPanel implements ComponentListener { private BufferedImage mImage; @@ -88,6 +84,19 @@ public class FrameBufferBuffer extends JPanel implements ComponentListener, Mous } + public static enum EVENT_RESULT{ + NONE(0), CONFIRM(1) ,CANCEL(2); + private int id; + + EVENT_RESULT(int id){ + this.id = id; + } + + public int getValue(){ + return id; + } + } + public class ConfigSelector extends JPanel implements ActionListener { private final String languages[]; @@ -219,6 +228,7 @@ public class FrameBufferBuffer extends JPanel implements ComponentListener, Mous private MagnifiedView mMagnifiedView; private ConfigSelector mConfigSelector; private JFrame mFrame; + private double mScale; public MagnifiedView getMagnifiedView() { if (mMagnifiedView == null) { @@ -235,6 +245,36 @@ public class FrameBufferBuffer extends JPanel implements ComponentListener, Mous } @Override + public void mouseReleased(MouseEvent e) { + if (e.MOUSE_RELEASED == MouseEvent.MOUSE_RELEASED) { + double x = e.getPoint().x / mScale; + double y = e.getPoint().y / mScale; + int value = NativeRenderer.onEvent((int)x, (int)y, MouseEvent.MOUSE_RELEASED); + if(value == EVENT_RESULT.CONFIRM.getValue()){ + JOptionPane.showMessageDialog((Component) e.getSource(), "Confirm clicked."); + } else if (value == EVENT_RESULT.CANCEL.getValue()){ + JOptionPane.showMessageDialog((Component) e.getSource(), "Cancel clicked."); + } + } + } + + @Override + public void mouseClicked(MouseEvent e){ + } + + @Override + public void mousePressed(MouseEvent e){ + } + + @Override + public void mouseEntered(MouseEvent e){ + } + + @Override + public void mouseExited(MouseEvent e){ + } + + @Override public void mouseDragged(MouseEvent e) { } @@ -310,6 +350,7 @@ public class FrameBufferBuffer extends JPanel implements ComponentListener, Mous renderNativeBuffer(); addComponentListener(this); addMouseMotionListener(this); + addMouseListener(this); } @Override @@ -380,16 +421,15 @@ public class FrameBufferBuffer extends JPanel implements ComponentListener, Mous mImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB_PRE); Graphics2D gc = mImage.createGraphics(); - double scale = 0.0; if (w / (double) h > getWidth() / (double) getHeight()) { - scale = (double) getWidth() / (double) w; + mScale = (double) getWidth() / (double) w; } else { - scale = (double) getHeight() / (double) h; + mScale = (double) getHeight() / (double) h; } gc.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); gc.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); gc.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); - gc.drawRenderedImage(image, AffineTransform.getScaleInstance(scale, scale)); + gc.drawRenderedImage(image, AffineTransform.getScaleInstance(mScale, mScale)); } repaint(); } |