Add support for actions triggered by key combination
Change-Id: I9dfa7de40229f00412d63fc9c1eb3a809a6eb2e6 Signed-off-by: Vojtech Bocek <vbocek@gmail.com>
This commit is contained in:
committed by
Gerrit Code Review
parent
9c102b536d
commit
0b7fe504dc
+43
-11
@@ -73,8 +73,6 @@ GUIAction::GUIAction(xml_node<>* node)
|
||||
xml_node<>* actions;
|
||||
xml_attribute<>* attr;
|
||||
|
||||
mKey = 0;
|
||||
|
||||
if (!node) return;
|
||||
|
||||
// First, get the action
|
||||
@@ -105,9 +103,12 @@ GUIAction::GUIAction(xml_node<>* node)
|
||||
attr = child->first_attribute("key");
|
||||
if (attr)
|
||||
{
|
||||
std::string key = attr->value();
|
||||
|
||||
mKey = getKeyByName(key);
|
||||
std::vector<std::string> keys = TWFunc::Split_String(attr->value(), "+");
|
||||
for(size_t i = 0; i < keys.size(); ++i)
|
||||
{
|
||||
const int key = getKeyByName(keys[i]);
|
||||
mKeys[key] = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -135,12 +136,41 @@ int GUIAction::NotifyTouch(TOUCH_STATE state, int x, int y)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GUIAction::NotifyKey(int key)
|
||||
int GUIAction::NotifyKey(int key, bool down)
|
||||
{
|
||||
if (!mKey || key != mKey)
|
||||
return 1;
|
||||
if (mKeys.empty())
|
||||
return 0;
|
||||
|
||||
std::map<int, bool>::iterator itr = mKeys.find(key);
|
||||
if(itr == mKeys.end())
|
||||
return 0;
|
||||
|
||||
bool prevState = itr->second;
|
||||
itr->second = down;
|
||||
|
||||
// If there is only one key for this action, wait for key up so it
|
||||
// doesn't trigger with multi-key actions.
|
||||
// Else, check if all buttons are pressed, then consume their release events
|
||||
// so they don't trigger one-button actions and reset mKeys pressed status
|
||||
if(mKeys.size() == 1) {
|
||||
if(!down && prevState)
|
||||
doActions();
|
||||
} else if(down) {
|
||||
for(itr = mKeys.begin(); itr != mKeys.end(); ++itr) {
|
||||
if(!itr->second)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Passed, all req buttons are pressed, reset them and consume release events
|
||||
HardwareKeyboard *kb = PageManager::GetHardwareKeyboard();
|
||||
for(itr = mKeys.begin(); itr != mKeys.end(); ++itr) {
|
||||
kb->ConsumeKeyRelease(itr->first);
|
||||
itr->second = false;
|
||||
}
|
||||
|
||||
doActions();
|
||||
}
|
||||
|
||||
doActions();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -148,7 +178,7 @@ int GUIAction::NotifyVarChange(const std::string& varName, const std::string& va
|
||||
{
|
||||
GUIObject::NotifyVarChange(varName, value);
|
||||
|
||||
if (varName.empty() && !isConditionValid() && !mKey && !mActionW)
|
||||
if (varName.empty() && !isConditionValid() && mKeys.empty() && !mActionW)
|
||||
doActions();
|
||||
else if((varName.empty() || IsConditionVariable(varName)) && isConditionValid() && isConditionTrue())
|
||||
doActions();
|
||||
@@ -380,7 +410,9 @@ int GUIAction::doAction(Action action, int isThreaded /* = 0 */)
|
||||
|
||||
if (function == "key")
|
||||
{
|
||||
PageManager::NotifyKey(getKeyByName(arg));
|
||||
const int key = getKeyByName(arg);
|
||||
PageManager::NotifyKey(key, true);
|
||||
PageManager::NotifyKey(key, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+14
-17
@@ -187,8 +187,8 @@ static void * input_thread(void *cookie)
|
||||
static int x = 0, y = 0;
|
||||
static int lshift = 0, rshift = 0;
|
||||
static struct timeval touchStart;
|
||||
HardwareKeyboard kb;
|
||||
string seconds;
|
||||
HardwareKeyboard *kb = PageManager::GetHardwareKeyboard();
|
||||
MouseCursor *cursor = PageManager::GetMouseCursor();
|
||||
|
||||
#ifndef TW_NO_SCREEN_TIMEOUT
|
||||
@@ -249,7 +249,7 @@ static void * input_thread(void *cookie)
|
||||
#endif
|
||||
gettimeofday(&touchStart, NULL);
|
||||
key_repeat = 2;
|
||||
kb.KeyRepeat();
|
||||
kb->KeyRepeat();
|
||||
#ifndef TW_NO_SCREEN_TIMEOUT
|
||||
blankTimer.resetTimerAndUnblank();
|
||||
#endif
|
||||
@@ -261,7 +261,7 @@ static void * input_thread(void *cookie)
|
||||
LOGERR("KEY_REPEAT: %d,%d\n", x, y);
|
||||
#endif
|
||||
gettimeofday(&touchStart, NULL);
|
||||
kb.KeyRepeat();
|
||||
kb->KeyRepeat();
|
||||
#ifndef TW_NO_SCREEN_TIMEOUT
|
||||
blankTimer.resetTimerAndUnblank();
|
||||
#endif
|
||||
@@ -356,6 +356,9 @@ static void * input_thread(void *cookie)
|
||||
{
|
||||
cursor->GetPos(x, y);
|
||||
|
||||
#ifdef _EVENT_LOGGING
|
||||
LOGERR("TOUCH_RELEASE: %d,%d\n", x, y);
|
||||
#endif
|
||||
PageManager::NotifyTouch(TOUCH_RELEASE, x, y);
|
||||
|
||||
touch_and_hold = 0;
|
||||
@@ -371,15 +374,13 @@ static void * input_thread(void *cookie)
|
||||
else if(ev.code == BTN_SIDE)
|
||||
{
|
||||
if(ev.value == 1)
|
||||
kb.KeyDown(KEY_BACK);
|
||||
kb->KeyDown(KEY_BACK);
|
||||
else
|
||||
kb.KeyUp(KEY_BACK);
|
||||
}
|
||||
else if (ev.value != 0)
|
||||
{
|
||||
kb->KeyUp(KEY_BACK);
|
||||
} else if (ev.value != 0) {
|
||||
// This is a key press
|
||||
if (kb.KeyDown(ev.code))
|
||||
{
|
||||
if (kb->KeyDown(ev.code)) {
|
||||
// Key repeat is enabled for this key
|
||||
key_repeat = 1;
|
||||
touch_and_hold = 0;
|
||||
touch_repeat = 0;
|
||||
@@ -388,9 +389,7 @@ static void * input_thread(void *cookie)
|
||||
#ifndef TW_NO_SCREEN_TIMEOUT
|
||||
blankTimer.resetTimerAndUnblank();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
key_repeat = 0;
|
||||
touch_and_hold = 0;
|
||||
touch_repeat = 0;
|
||||
@@ -399,11 +398,9 @@ static void * input_thread(void *cookie)
|
||||
blankTimer.resetTimerAndUnblank();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// This is a key release
|
||||
kb.KeyUp(ev.code);
|
||||
kb->KeyUp(ev.code);
|
||||
key_repeat = 0;
|
||||
touch_and_hold = 0;
|
||||
touch_repeat = 0;
|
||||
|
||||
@@ -38,15 +38,22 @@ HardwareKeyboard::~HardwareKeyboard()
|
||||
|
||||
int HardwareKeyboard::KeyDown(int key_code)
|
||||
{
|
||||
mPressedKeys.insert(key_code);
|
||||
PageManager::NotifyKey(key_code, true);
|
||||
#ifdef _EVENT_LOGGING
|
||||
LOGERR("HardwareKeyboard::KeyDown %i\n", key_code);
|
||||
#endif
|
||||
PageManager::NotifyKey(key_code);
|
||||
return 0; // 0 = no key repeat anything else turns on key repeat
|
||||
}
|
||||
|
||||
int HardwareKeyboard::KeyUp(int key_code)
|
||||
{
|
||||
std::set<int>::iterator itr = mPressedKeys.find(key_code);
|
||||
if(itr != mPressedKeys.end())
|
||||
{
|
||||
mPressedKeys.erase(itr);
|
||||
PageManager::NotifyKey(key_code, false);
|
||||
}
|
||||
#ifdef _EVENT_LOGGING
|
||||
LOGERR("HardwareKeyboard::KeyUp %i\n", key_code);
|
||||
#endif
|
||||
@@ -55,8 +62,22 @@ int HardwareKeyboard::KeyUp(int key_code)
|
||||
|
||||
int HardwareKeyboard::KeyRepeat(void)
|
||||
{
|
||||
/*
|
||||
* Uncomment when key repeats are sent somewhere.
|
||||
* std::set<int>::iterator itr = mPressedKeys.find(key_code);
|
||||
* if(itr != mPressedKeys.end())
|
||||
* {
|
||||
* Send repeats somewhere, don't remove itr from mPressedKeys
|
||||
* }
|
||||
*/
|
||||
|
||||
#ifdef _EVENT_LOGGING
|
||||
LOGERR("HardwareKeyboard::KeyRepeat\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HardwareKeyboard::ConsumeKeyRelease(int key)
|
||||
{
|
||||
mPressedKeys.erase(key);
|
||||
}
|
||||
|
||||
+9
-3
@@ -25,6 +25,7 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <time.h>
|
||||
|
||||
extern "C" {
|
||||
@@ -101,7 +102,7 @@ public:
|
||||
|
||||
// NotifyKey - Notify of a key press
|
||||
// Return 0 on success (and consume key), >0 to pass key to next handler, and <0 on error
|
||||
virtual int NotifyKey(int key) { return 1; }
|
||||
virtual int NotifyKey(int key, bool down) { return 1; }
|
||||
|
||||
// GetRenderPos - Returns the current position of the object
|
||||
virtual int GetActionPos(int& x, int& y, int& w, int& h) { x = mActionX; y = mActionY; w = mActionW; h = mActionH; return 0; }
|
||||
@@ -269,7 +270,7 @@ public:
|
||||
|
||||
public:
|
||||
virtual int NotifyTouch(TOUCH_STATE state, int x, int y);
|
||||
virtual int NotifyKey(int key);
|
||||
virtual int NotifyKey(int key, bool down);
|
||||
virtual int NotifyVarChange(const std::string& varName, const std::string& value);
|
||||
virtual int doActions();
|
||||
|
||||
@@ -282,7 +283,7 @@ protected:
|
||||
};
|
||||
|
||||
std::vector<Action> mActions;
|
||||
int mKey;
|
||||
std::map<int, bool> mKeys;
|
||||
|
||||
protected:
|
||||
int getKeyByName(std::string key);
|
||||
@@ -927,6 +928,11 @@ public:
|
||||
virtual int KeyDown(int key_code);
|
||||
virtual int KeyUp(int key_code);
|
||||
virtual int KeyRepeat(void);
|
||||
|
||||
void ConsumeKeyRelease(int key);
|
||||
|
||||
private:
|
||||
std::set<int> mPressedKeys;
|
||||
};
|
||||
|
||||
class GUISliderValue: public GUIObject, public RenderObject, public ActionObject
|
||||
|
||||
+21
-12
@@ -55,6 +55,7 @@ std::map<std::string, PageSet*> PageManager::mPageSets;
|
||||
PageSet* PageManager::mCurrentSet;
|
||||
PageSet* PageManager::mBaseSet = NULL;
|
||||
MouseCursor *PageManager::mMouseCursor = NULL;
|
||||
HardwareKeyboard *PageManager::mHardwareKeyboard = NULL;
|
||||
|
||||
// Helper routine to convert a string to a color declaration
|
||||
int ConvertStrToColor(std::string str, COLOR* color)
|
||||
@@ -447,7 +448,7 @@ int Page::NotifyTouch(TOUCH_STATE state, int x, int y)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Page::NotifyKey(int key)
|
||||
int Page::NotifyKey(int key, bool down)
|
||||
{
|
||||
std::vector<ActionObject*>::reverse_iterator iter;
|
||||
|
||||
@@ -455,16 +456,17 @@ int Page::NotifyKey(int key)
|
||||
if (mActions.size() == 0)
|
||||
return 1;
|
||||
|
||||
int ret = 1;
|
||||
// We work backwards, from top-most element to bottom-most element
|
||||
for (iter = mActions.rbegin(); iter != mActions.rend(); iter++)
|
||||
{
|
||||
int ret = (*iter)->NotifyKey(key);
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
else if (ret < 0)
|
||||
LOGERR("An action handler has returned an error");
|
||||
ret = (*iter)->NotifyKey(key, down);
|
||||
if (ret < 0) {
|
||||
LOGERR("An action handler has returned an error\n");
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Page::NotifyKeyboard(int key)
|
||||
@@ -719,12 +721,12 @@ int PageSet::NotifyTouch(TOUCH_STATE state, int x, int y)
|
||||
return (mCurrentPage ? mCurrentPage->NotifyTouch(state, x, y) : -1);
|
||||
}
|
||||
|
||||
int PageSet::NotifyKey(int key)
|
||||
int PageSet::NotifyKey(int key, bool down)
|
||||
{
|
||||
if (mOverlayPage)
|
||||
return (mOverlayPage->NotifyKey(key));
|
||||
return (mOverlayPage->NotifyKey(key, down));
|
||||
|
||||
return (mCurrentPage ? mCurrentPage->NotifyKey(key) : -1);
|
||||
return (mCurrentPage ? mCurrentPage->NotifyKey(key, down) : -1);
|
||||
}
|
||||
|
||||
int PageSet::NotifyKeyboard(int key)
|
||||
@@ -964,6 +966,13 @@ int PageManager::Render(void)
|
||||
return res;
|
||||
}
|
||||
|
||||
HardwareKeyboard *PageManager::GetHardwareKeyboard()
|
||||
{
|
||||
if(!mHardwareKeyboard)
|
||||
mHardwareKeyboard = new HardwareKeyboard();
|
||||
return mHardwareKeyboard;
|
||||
}
|
||||
|
||||
MouseCursor *PageManager::GetMouseCursor()
|
||||
{
|
||||
if(!mMouseCursor)
|
||||
@@ -1002,9 +1011,9 @@ int PageManager::NotifyTouch(TOUCH_STATE state, int x, int y)
|
||||
return (mCurrentSet ? mCurrentSet->NotifyTouch(state, x, y) : -1);
|
||||
}
|
||||
|
||||
int PageManager::NotifyKey(int key)
|
||||
int PageManager::NotifyKey(int key, bool down)
|
||||
{
|
||||
return (mCurrentSet ? mCurrentSet->NotifyKey(key) : -1);
|
||||
return (mCurrentSet ? mCurrentSet->NotifyKey(key, down) : -1);
|
||||
}
|
||||
|
||||
int PageManager::NotifyKeyboard(int key)
|
||||
|
||||
+7
-3
@@ -30,6 +30,7 @@ class ActionObject;
|
||||
class InputObject;
|
||||
class MouseCursor;
|
||||
class GUIObject;
|
||||
class HardwareKeyboard;
|
||||
|
||||
class Page
|
||||
{
|
||||
@@ -43,7 +44,7 @@ public:
|
||||
virtual int Render(void);
|
||||
virtual int Update(void);
|
||||
virtual int NotifyTouch(TOUCH_STATE state, int x, int y);
|
||||
virtual int NotifyKey(int key);
|
||||
virtual int NotifyKey(int key, bool down);
|
||||
virtual int NotifyKeyboard(int key);
|
||||
virtual int SetKeyBoardFocus(int inFocus);
|
||||
virtual int NotifyVarChange(std::string varName, std::string value);
|
||||
@@ -84,7 +85,7 @@ public:
|
||||
int Render(void);
|
||||
int Update(void);
|
||||
int NotifyTouch(TOUCH_STATE state, int x, int y);
|
||||
int NotifyKey(int key);
|
||||
int NotifyKey(int key, bool down);
|
||||
int NotifyKeyboard(int key);
|
||||
int SetKeyBoardFocus(int inFocus);
|
||||
int NotifyVarChange(std::string varName, std::string value);
|
||||
@@ -127,7 +128,7 @@ public:
|
||||
static int Render(void);
|
||||
static int Update(void);
|
||||
static int NotifyTouch(TOUCH_STATE state, int x, int y);
|
||||
static int NotifyKey(int key);
|
||||
static int NotifyKey(int key, bool down);
|
||||
static int NotifyKeyboard(int key);
|
||||
static int SetKeyBoardFocus(int inFocus);
|
||||
static int NotifyVarChange(std::string varName, std::string value);
|
||||
@@ -135,6 +136,8 @@ public:
|
||||
static MouseCursor *GetMouseCursor();
|
||||
static void LoadCursorData(xml_node<>* node);
|
||||
|
||||
static HardwareKeyboard *GetHardwareKeyboard();
|
||||
|
||||
protected:
|
||||
static PageSet* FindPackage(std::string name);
|
||||
|
||||
@@ -143,6 +146,7 @@ protected:
|
||||
static PageSet* mCurrentSet;
|
||||
static PageSet* mBaseSet;
|
||||
static MouseCursor *mMouseCursor;
|
||||
static HardwareKeyboard *mHardwareKeyboard;
|
||||
};
|
||||
|
||||
#endif // _PAGES_HEADER_HPP
|
||||
|
||||
+8
-1
@@ -384,6 +384,7 @@ static int vk_modify(struct ev *e, struct input_event *ev)
|
||||
{
|
||||
static int downX = -1, downY = -1;
|
||||
static int discard = 0;
|
||||
static int last_virt_key = 0;
|
||||
static int lastWasSynReport = 0;
|
||||
static int touchReleaseOnNextSynReport = 0;
|
||||
static int use_tracking_id_negative_as_touch_release = 0; // On some devices, type: 3 code: 39 value: -1, aka EV_ABS ABS_MT_TRACKING_ID -1 indicates a true touch release
|
||||
@@ -593,7 +594,11 @@ static int vk_modify(struct ev *e, struct input_event *ev)
|
||||
if (discard)
|
||||
{
|
||||
discard = 0;
|
||||
return 1;
|
||||
|
||||
// Send the keyUp event
|
||||
ev->type = EV_KEY;
|
||||
ev->code = last_virt_key;
|
||||
ev->value = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -651,6 +656,8 @@ static int vk_modify(struct ev *e, struct input_event *ev)
|
||||
ev->code = e->vks[i].scancode;
|
||||
ev->value = 1;
|
||||
|
||||
last_virt_key = e->vks[i].scancode;
|
||||
|
||||
vibrate(VIBRATOR_TIME_MS);
|
||||
|
||||
// Mark that all further movement until lift is discard,
|
||||
|
||||
@@ -1142,4 +1142,24 @@ void TWFunc::Fixup_Time_On_Boot()
|
||||
#endif
|
||||
}
|
||||
|
||||
std::vector<std::string> TWFunc::Split_String(const std::string& str, const std::string& delimiter, bool removeEmpty)
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
size_t idx = 0, idx_last = 0;
|
||||
|
||||
while(idx < str.size())
|
||||
{
|
||||
idx = str.find_first_of(delimiter, idx_last);
|
||||
if(idx == std::string::npos)
|
||||
idx = str.size();
|
||||
|
||||
if(idx-idx_last != 0 || !removeEmpty)
|
||||
res.push_back(str.substr(idx_last, idx-idx_last));
|
||||
|
||||
idx_last = idx + delimiter.size();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif // ndef BUILD_TWRPTAR_MAIN
|
||||
|
||||
@@ -80,6 +80,7 @@ public:
|
||||
static string Get_Current_Date(void); // Returns the current date in ccyy-m-dd--hh-nn-ss format
|
||||
static void Auto_Generate_Backup_Name(); // Populates TW_BACKUP_NAME with a backup name based on current date and ro.build.display.id from /system/build.prop
|
||||
static void Fixup_Time_On_Boot(); // Fixes time on devices which need it
|
||||
static std::vector<std::string> Split_String(const std::string& str, const std::string& delimiter, bool removeEmpty = true); // Splits string by delimiter
|
||||
|
||||
private:
|
||||
static void Copy_Log(string Source, string Destination);
|
||||
|
||||
Reference in New Issue
Block a user