Add support for actions triggered by key combination

Change-Id: I9dfa7de40229f00412d63fc9c1eb3a809a6eb2e6
Signed-off-by: Vojtech Bocek <vbocek@gmail.com>
This commit is contained in:
Vojtech Bocek
2014-04-16 17:51:17 +02:00
committed by Gerrit Code Review
parent 9c102b536d
commit 0b7fe504dc
9 changed files with 145 additions and 48 deletions
+43 -11
View File
@@ -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
View File
@@ -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;
+22 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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,
+20
View File
@@ -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
+1
View File
@@ -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);