summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKunal <shindek@google.com>2020-05-04 20:25:33 -0700
committerKunal <shindek@google.com>2020-05-07 17:07:57 -0700
commit7ed1bd4ef7cb18503e4e3a77992b0bcf24038054 (patch)
tree69764844ef2be0549727228625dc053859c57d6c
parent6efb1eb02a048ca6964abcfd876d2ada35aa80a4 (diff)
downloadteeui-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.h5
-rw-r--r--libteeui/example/phys_button_example.cpp2
-rw-r--r--libteeui/example/touch_button_example.cpp47
-rw-r--r--libteeui/include/teeui/example/example.h8
-rw-r--r--libteeui/include/teeui/label.h6
-rw-r--r--libteeui/include/teeui/utils.h14
-rw-r--r--libteeui/src/label.cpp10
-rw-r--r--libteeui_jni/include/com_android_framebufferizer_NativeRenderer.h8
-rw-r--r--libteeui_jni/libteeui_jni.cpp13
-rw-r--r--tools/framebufferizer/src/com/android/framebufferizer/NativeRenderer.java1
-rw-r--r--tools/framebufferizer/src/com/android/framebufferizer/utils/FrameBufferBuffer.java60
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();
}