summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gui/devices/1080x1920/res/ui.xml43
-rw-r--r--gui/devices/1920x1200/res/ui.xml35
-rw-r--r--gui/devices/320x320/res/ui.xml35
-rw-r--r--gui/devices/480x800/res/ui.xml43
-rw-r--r--gui/devices/800x480/res/ui.xml35
-rw-r--r--gui/devices/landscape/res/landscape.xml6
-rw-r--r--gui/devices/portrait/res/portrait.xml10
-rw-r--r--gui/devices/watch/res/watch.xml6
-rw-r--r--gui/objects.hpp11
-rw-r--r--gui/patternpassword.cpp212
-rwxr-xr-xgui/theme/common/landscape.xml39
-rwxr-xr-xgui/theme/common/languages/en.xml1
-rwxr-xr-xgui/theme/common/portrait.xml37
-rwxr-xr-xgui/theme/common/watch.xml76
-rw-r--r--gui/theme/landscape_hdpi/ui.xml2
-rw-r--r--gui/theme/landscape_mdpi/ui.xml4
-rw-r--r--gui/theme/portrait_hdpi/ui.xml4
-rw-r--r--gui/theme/portrait_mdpi/ui.xml4
-rw-r--r--gui/theme/watch_mdpi/images/grid_less.pngbin0 -> 426 bytes
-rw-r--r--gui/theme/watch_mdpi/images/grid_more.pngbin0 -> 581 bytes
-rw-r--r--gui/theme/watch_mdpi/ui.xml6
21 files changed, 548 insertions, 61 deletions
diff --git a/gui/devices/1080x1920/res/ui.xml b/gui/devices/1080x1920/res/ui.xml
index 0ac3e43b4..d49157720 100644
--- a/gui/devices/1080x1920/res/ui.xml
+++ b/gui/devices/1080x1920/res/ui.xml
@@ -200,14 +200,19 @@
<variable name="slidervalue_padding" value="30" />
<variable name="slidervalue_sliderw" value="15" />
<variable name="slidervalue_sliderh" value="90" />
- <variable name="pattern_x" value="216" />
+ <variable name="pattern_button3_x" value="275" />
+ <variable name="pattern_button4_x" value="409" />
+ <variable name="pattern_button5_x" value="543" />
+ <variable name="pattern_button6_x" value="677" />
+ <variable name="pattern_x" value="92" />
<variable name="pattern_y" value="508" />
- <variable name="pattern_width" value="648" />
+ <variable name="pattern_width" value="896" />
<variable name="pattern_dot_color" value="#33B5E5" />
<variable name="pattern_dot_color_active" value="#FFFFFF" />
<variable name="pattern_dot_radius" value="23" />
<variable name="pattern_line_color" value="#33B5E5" />
<variable name="pattern_line_width" value="18" />
+ <variable name="pattern_cancel_y" value="1440" />
</variables>
<mousecursor>
@@ -318,6 +323,40 @@
</object>
</template>
+ <template name="pattern_options">
+ <object type="button">
+ <placement x="%pattern_button3_x%" y="%row2_text_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>3x3</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=3</action>
+ </object>
+
+ <object type="button">
+ <placement x="%pattern_button4_x%" y="%row2_text_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>4x4</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=4</action>
+ </object>
+
+ <object type="button">
+ <placement x="%pattern_button5_x%" y="%row2_text_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>5x5</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=5</action>
+ </object>
+
+ <object type="button">
+ <placement x="%pattern_button6_x%" y="%row2_text_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>6x6</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=6</action>
+ </object>
+ </template>
+
<template name="sort_options">
<object type="text" color="%text_color%">
<font resource="font" />
diff --git a/gui/devices/1920x1200/res/ui.xml b/gui/devices/1920x1200/res/ui.xml
index 8171cf596..160ddf64c 100644
--- a/gui/devices/1920x1200/res/ui.xml
+++ b/gui/devices/1920x1200/res/ui.xml
@@ -221,6 +221,7 @@
<variable name="pattern_dot_radius" value="23" />
<variable name="pattern_line_color" value="#33B5E5" />
<variable name="pattern_line_width" value="18" />
+ <variable name="pattern_button_y" value="190" />
</variables>
<mousecursor>
@@ -329,6 +330,40 @@
</object>
</template>
+ <template name="pattern_options">
+ <object type="button">
+ <placement x="%col1_medium_x%" y="%pattern_button_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>3x3</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=3</action>
+ </object>
+
+ <object type="button">
+ <placement x="%col2_medium_x%" y="%pattern_button_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>4x4</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=4</action>
+ </object>
+
+ <object type="button">
+ <placement x="%col3_medium_x%" y="%pattern_button_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>5x5</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=5</action>
+ </object>
+
+ <object type="button">
+ <placement x="%col4_medium_x%" y="%pattern_button_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>6x6</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=6</action>
+ </object>
+ </template>
+
<template name="sort_options">
<object type="text" color="%text_color%">
<font resource="font" />
diff --git a/gui/devices/320x320/res/ui.xml b/gui/devices/320x320/res/ui.xml
index afe2509db..345a81c6a 100644
--- a/gui/devices/320x320/res/ui.xml
+++ b/gui/devices/320x320/res/ui.xml
@@ -211,6 +211,7 @@
<variable name="pattern_dot_radius" value="7" />
<variable name="pattern_line_color" value="#33B5E5" />
<variable name="pattern_line_width" value="4" />
+ <variable name="pattern_button_y" value="33" />
</variables>
<templates>
@@ -323,6 +324,40 @@
</object>
</template>
+ <template name="pattern_options">
+ <object type="button">
+ <placement x="%col1_medium_x%" y="%pattern_button_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>3x3</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=3</action>
+ </object>
+
+ <object type="button">
+ <placement x="%col2_medium_x%" y="%pattern_button_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>4x4</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=4</action>
+ </object>
+
+ <object type="button">
+ <placement x="%col3_medium_x%" y="%pattern_button_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>5x5</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=5</action>
+ </object>
+
+ <object type="button">
+ <placement x="%col4_medium_x%" y="%pattern_button_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>6x6</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=6</action>
+ </object>
+ </template>
+
<template name="sort_options">
<object type="text" color="%text_color%">
<font resource="mediumfont" />
diff --git a/gui/devices/480x800/res/ui.xml b/gui/devices/480x800/res/ui.xml
index c406e66ef..ec9df7ed8 100644
--- a/gui/devices/480x800/res/ui.xml
+++ b/gui/devices/480x800/res/ui.xml
@@ -195,14 +195,19 @@
<variable name="slidervalue_padding" value="13" />
<variable name="slidervalue_sliderw" value="7" />
<variable name="slidervalue_sliderh" value="40" />
- <variable name="pattern_x" value="90" />
+ <variable name="pattern_button3_x" value="117" />
+ <variable name="pattern_button4_x" value="180" />
+ <variable name="pattern_button5_x" value="243" />
+ <variable name="pattern_button6_x" value="306" />
+ <variable name="pattern_x" value="41" />
<variable name="pattern_y" value="250" />
- <variable name="pattern_width" value="300" />
+ <variable name="pattern_width" value="398" />
<variable name="pattern_dot_color" value="#33B5E5" />
<variable name="pattern_dot_color_active" value="#FFFFFF" />
<variable name="pattern_dot_radius" value="12" />
<variable name="pattern_line_color" value="#33B5E5" />
<variable name="pattern_line_width" value="9" />
+ <variable name="pattern_cancel_y" value="672" />
</variables>
<mousecursor>
@@ -319,6 +324,40 @@
</object>
</template>
+ <template name="pattern_options">
+ <object type="button">
+ <placement x="%pattern_button3_x%" y="%row2_text_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>3x3</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=3</action>
+ </object>
+
+ <object type="button">
+ <placement x="%pattern_button4_x%" y="%row2_text_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>4x4</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=4</action>
+ </object>
+
+ <object type="button">
+ <placement x="%pattern_button5_x%" y="%row2_text_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>5x5</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=5</action>
+ </object>
+
+ <object type="button">
+ <placement x="%pattern_button6_x%" y="%row2_text_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>6x6</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=6</action>
+ </object>
+ </template>
+
<template name="sort_options">
<object type="text" color="%text_color%">
<font resource="font" />
diff --git a/gui/devices/800x480/res/ui.xml b/gui/devices/800x480/res/ui.xml
index a9bf904bb..a561a3cc4 100644
--- a/gui/devices/800x480/res/ui.xml
+++ b/gui/devices/800x480/res/ui.xml
@@ -222,6 +222,7 @@
<variable name="pattern_dot_radius" value="10" />
<variable name="pattern_line_color" value="#33B5E5" />
<variable name="pattern_line_width" value="7" />
+ <variable name="pattern_button_y" value="94" />
</variables>
<mousecursor>
@@ -332,6 +333,40 @@
</object>
</template>
+ <template name="pattern_options">
+ <object type="button">
+ <placement x="%col1_medium_x%" y="%pattern_button_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>3x3</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=3</action>
+ </object>
+
+ <object type="button">
+ <placement x="%col2_medium_x%" y="%pattern_button_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>4x4</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=4</action>
+ </object>
+
+ <object type="button">
+ <placement x="%col3_medium_x%" y="%pattern_button_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>5x5</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=5</action>
+ </object>
+
+ <object type="button">
+ <placement x="%col4_medium_x%" y="%pattern_button_y%" />
+ <font resource="font" color="%button_text_color%" />
+ <text>6x6</text>
+ <image resource="sort_button" />
+ <action function="set">tw_gui_pattern_grid_size=6</action>
+ </object>
+ </template>
+
<template name="sort_options">
<object type="text" color="%text_color%">
<font resource="font" />
diff --git a/gui/devices/landscape/res/landscape.xml b/gui/devices/landscape/res/landscape.xml
index ec6f88ebd..b0f6b160b 100644
--- a/gui/devices/landscape/res/landscape.xml
+++ b/gui/devices/landscape/res/landscape.xml
@@ -63,6 +63,10 @@
<sort name="tw_gui_sort_order" />
</style>
+ <style name="patternpassword">
+ <size name="tw_gui_pattern_grid_size" default="3" />
+ </style>
+
<style name="partitionlist">
<style name="scrolllist" />
<icon selected="checkbox_true" unselected="checkbox_false" />
@@ -3359,6 +3363,8 @@
<text>Pattern Failed, Please Try Again</text>
</object>
+ <object type="template" name="pattern_options" />
+
<object type="patternpassword">
<placement x="%pattern_x%" y="%pattern_y%" w="%pattern_width%" h="%pattern_width%" />
<dot color="%pattern_dot_color%" activecolor="%pattern_dot_color_active%" radius="%pattern_dot_radius%" />
diff --git a/gui/devices/portrait/res/portrait.xml b/gui/devices/portrait/res/portrait.xml
index 9c230675f..b7e79e9e9 100644
--- a/gui/devices/portrait/res/portrait.xml
+++ b/gui/devices/portrait/res/portrait.xml
@@ -58,6 +58,10 @@
<sort name="tw_gui_sort_order" />
</style>
+ <style name="patternpassword">
+ <size name="tw_gui_pattern_grid_size" default="3" />
+ </style>
+
<style name="partitionlist">
<style name="scrolllist" />
<icon selected="checkbox_true" unselected="checkbox_false" />
@@ -3382,10 +3386,12 @@
<object type="text">
<condition var1="tw_password_fail" var2="1" />
<font resource="font" color="%text_fail_color%"/>
- <placement x="%center_x%" y="%row2_text_y%" placement="5" />
+ <placement x="%center_x%" y="%row1_text_y%" placement="5" />
<text>Pattern Failed, Please Try Again</text>
</object>
+ <object type="template" name="pattern_options" />
+
<object type="patternpassword">
<placement x="%pattern_x%" y="%pattern_y%" w="%pattern_width%" h="%pattern_width%" />
<dot color="%pattern_dot_color%" activecolor="%pattern_dot_color_active%" radius="%pattern_dot_radius%" />
@@ -3395,7 +3401,7 @@
</object>
<object type="button">
- <placement x="%col_center_x%" y="%row4_y%" />
+ <placement x="%col_center_x%" y="%pattern_cancel_y%" />
<text>Cancel</text>
<actions>
<action function="set">tw_page_done=1</action>
diff --git a/gui/devices/watch/res/watch.xml b/gui/devices/watch/res/watch.xml
index 3adf1643b..2dc291224 100644
--- a/gui/devices/watch/res/watch.xml
+++ b/gui/devices/watch/res/watch.xml
@@ -58,6 +58,10 @@
<sort name="tw_gui_sort_order" />
</style>
+ <style name="patternpassword">
+ <size name="tw_gui_pattern_grid_size" default="3" />
+ </style>
+
<style name="partitionlist">
<style name="scrolllist" />
<icon selected="checkbox_true" unselected="checkbox_false" />
@@ -3379,6 +3383,8 @@
<text>Pattern Failed, Please Try Again</text>
</object>
+ <object type="template" name="pattern_options" />
+
<object type="patternpassword">
<placement x="%pattern_x%" y="%pattern_y%" w="%pattern_width%" h="%pattern_width%" />
<dot color="%pattern_dot_color%" activecolor="%pattern_dot_color_active%" radius="%pattern_dot_radius%" />
diff --git a/gui/objects.hpp b/gui/objects.hpp
index ebf08a8db..4e7ea29f4 100644
--- a/gui/objects.hpp
+++ b/gui/objects.hpp
@@ -1134,6 +1134,7 @@ public:
virtual int Render(void);
virtual int Update(void);
virtual int NotifyTouch(TOUCH_STATE state, int x, int y);
+ virtual int NotifyVarChange(const std::string& varName, const std::string& value);
virtual int SetRenderPos(int x, int y, int w = 0, int h = 0);
protected:
@@ -1141,9 +1142,10 @@ protected:
void ResetActiveDots();
void ConnectDot(int dot_idx);
void ConnectIntermediateDots(int dot_idx);
+ void Resize(size_t size);
int InDot(int x, int y);
bool DotUsed(int dot_idx);
- static bool IsInRect(int x, int y, int rx, int ry, int rw, int rh);
+ std::string GeneratePassphrase();
void PatternDrawn();
struct Dot {
@@ -1152,8 +1154,11 @@ protected:
bool active;
};
- Dot mDots[9];
- int mConnectedDots[9];
+ std::string mSizeVar;
+ size_t mGridSize;
+
+ Dot* mDots;
+ int* mConnectedDots;
size_t mConnectedDotsLen;
int mCurLineX;
int mCurLineY;
diff --git a/gui/patternpassword.cpp b/gui/patternpassword.cpp
index ed152851f..a6ab83128 100644
--- a/gui/patternpassword.cpp
+++ b/gui/patternpassword.cpp
@@ -9,6 +9,7 @@
#include <stdlib.h>
#include <string>
+#include <sstream>
extern "C" {
#include "../twcommon.h"
@@ -24,6 +25,11 @@ GUIPatternPassword::GUIPatternPassword(xml_node<>* node)
xml_attribute<>* attr;
xml_node<>* child;
+ // 3x3 is the default.
+ mGridSize = 3;
+ mDots = new Dot[mGridSize * mGridSize];
+ mConnectedDots = new int[mGridSize * mGridSize];
+
ResetActiveDots();
mTrackingTouch = false;
mNeedRender = true;
@@ -69,6 +75,14 @@ GUIPatternPassword::GUIPatternPassword(xml_node<>* node)
if(child)
mPassVar = LoadAttrString(child, "name", "");
+ child = FindNode(node, "size");
+ if(child) {
+ mSizeVar = LoadAttrString(child, "name", "");
+
+ // Use the configured default, if set.
+ size_t size = LoadAttrInt(child, "default", mGridSize);
+ Resize(size);
+ }
if(!mDotImage || !mDotImage->GetResource() || !mActiveDotImage || !mActiveDotImage->GetResource())
{
@@ -87,6 +101,9 @@ GUIPatternPassword::~GUIPatternPassword()
delete mActiveDotImage;
delete mAction;
+ delete[] mDots;
+ delete[] mConnectedDots;
+
if(mDotCircle)
gr_free_surface(mDotCircle);
@@ -98,7 +115,7 @@ void GUIPatternPassword::ResetActiveDots()
{
mConnectedDotsLen = 0;
mCurLineX = mCurLineY = -1;
- for(int i = 0; i < 9; ++i)
+ for(size_t i = 0; i < mGridSize * mGridSize; ++i)
mDots[i].active = false;
}
@@ -122,17 +139,28 @@ int GUIPatternPassword::SetRenderPos(int x, int y, int w, int h)
void GUIPatternPassword::CalculateDotPositions(void)
{
- const int step_x = (mRenderW - mDotRadius*2) / 2;
- const int step_y = (mRenderH - mDotRadius*2) / 2;
+ const int num_gaps = mGridSize - 1;
+ const int step_x = (mRenderW - mDotRadius*2) / num_gaps;
+ const int step_y = (mRenderH - mDotRadius*2) / num_gaps;
int x = mRenderX;
int y = mRenderY;
- for(int r = 0; r < 3; ++r)
+ /* Order is important for keyphrase generation:
+ *
+ * 0 1 2 3 ... n-1
+ * n n+1 n+2 n+3 ... 2n-1
+ * 2n 2n+1 2n+2 2n+3 ... 3n-1
+ * 3n 3n+1 3n+2 3n+3 ... 4n-1
+ * : : : :
+ * n*n-1
+ */
+
+ for(size_t r = 0; r < mGridSize; ++r)
{
- for(int c = 0; c < 3; ++c)
+ for(size_t c = 0; c < mGridSize; ++c)
{
- mDots[3*r+c].x = x;
- mDots[3*r+c].y = y;
+ mDots[mGridSize*r + c].x = x;
+ mDots[mGridSize*r + c].y = y;
x += step_x;
}
x = mRenderX;
@@ -157,7 +185,7 @@ int GUIPatternPassword::Render(void)
gr_line(dc.x + mDotRadius, dc.y + mDotRadius, mCurLineX, mCurLineY, mLineWidth);
}
- for(int i = 0; i < 9; ++i) {
+ for(size_t i = 0; i < mGridSize * mGridSize; ++i) {
if(mDotCircle) {
gr_blit(mDotCircle, 0, 0, gr_get_width(mDotCircle), gr_get_height(mDotCircle), mDots[i].x, mDots[i].y);
if(mDots[i].active) {
@@ -185,15 +213,39 @@ int GUIPatternPassword::Update(void)
return res;
}
-bool GUIPatternPassword::IsInRect(int x, int y, int rx, int ry, int rw, int rh)
+void GUIPatternPassword::Resize(size_t n) {
+ if(mGridSize == n)
+ return;
+
+ delete[] mDots;
+ delete[] mConnectedDots;
+
+ mGridSize = n;
+ mDots = new Dot[n*n];
+ mConnectedDots = new int[n*n];
+
+ ResetActiveDots();
+ CalculateDotPositions();
+ mTrackingTouch = false;
+ mNeedRender = true;
+}
+
+static int pow(int x, int i)
+{
+ while(i-- > 1)
+ x *= x;
+ return x;
+}
+
+static bool IsInCircle(int x, int y, int ox, int oy, int r)
{
- return x >= rx && y >= ry && x <= rx+rw && y <= ry+rh;
+ return pow(x - ox, 2) + pow(y - oy, 2) <= pow(r, 2);
}
int GUIPatternPassword::InDot(int x, int y)
{
- for(int i = 0; i < 9; ++i) {
- if(IsInRect(x, y, mDots[i].x - mDotRadius*1.5, mDots[i].y - mDotRadius*1.5, mDotRadius*6, mDotRadius*6))
+ for(size_t i = 0; i < mGridSize * mGridSize; ++i) {
+ if(IsInCircle(x, y, mDots[i].x + mDotRadius, mDots[i].y + mDotRadius, mDotRadius*3))
return i;
}
return -1;
@@ -210,7 +262,7 @@ bool GUIPatternPassword::DotUsed(int dot_idx)
void GUIPatternPassword::ConnectDot(int dot_idx)
{
- if(mConnectedDotsLen >= 9)
+ if(mConnectedDotsLen >= mGridSize * mGridSize)
{
LOGERR("mConnectedDots in GUIPatternPassword has overflown!\n");
return;
@@ -220,30 +272,66 @@ void GUIPatternPassword::ConnectDot(int dot_idx)
mDots[dot_idx].active = true;
}
-void GUIPatternPassword::ConnectIntermediateDots(int dot_idx)
+void GUIPatternPassword::ConnectIntermediateDots(int next_dot_idx)
{
if(mConnectedDotsLen == 0)
return;
- const int last_dot = mConnectedDots[mConnectedDotsLen-1];
- int mid = -1;
-
- // The line is vertical and has crossed a point in the middle
- if(dot_idx%3 == last_dot%3 && abs(dot_idx - last_dot) > 3) {
- mid = 3 + dot_idx%3;
- // the line is horizontal and has crossed a point in the middle
- } else if(dot_idx/3 == last_dot/3 && abs(dot_idx - last_dot) > 1) {
- mid = (dot_idx/3)*3 + 1;
- // the line is diagonal and has crossed the middle point
- } else if((dot_idx == 0 && last_dot == 8) || (dot_idx == 8 && last_dot == 0) ||
- (dot_idx == 2 && last_dot == 6) || (dot_idx == 6 && last_dot == 2)) {
- mid = 4;
- } else {
+ const int prev_dot_idx = mConnectedDots[mConnectedDotsLen-1];
+
+ int px = prev_dot_idx % mGridSize;
+ int py = prev_dot_idx / mGridSize;
+
+ int nx = next_dot_idx % mGridSize;
+ int ny = next_dot_idx / mGridSize;
+
+ /*
+ * We connect all dots that are in a straight line between the previous dot
+ * and the next one. This is simple for 3x3, but is more complicated for
+ * larger grids.
+ *
+ * Weirdly, Android doesn't do the logical thing when it comes to connecting
+ * dots between two points. Rather than simply adding all points that lie
+ * on the line between the start and end points, it instead only connects
+ * dots that are adjacent in only three directions -- horizontal, vertical
+ * and diagonal (45°).
+ *
+ * So we can just iterate over the correct axes, taking care to ensure that
+ * the order in which the intermediate points are added to the pattern is
+ * correct.
+ */
+
+ int x = px;
+ int y = py;
+
+ int Dx = (nx > px) ? 1 : -1;
+ int Dy = (ny > py) ? 1 : -1;
+
+ // Vertical lines.
+ if(px == nx)
+ Dx = 0;
+
+ // Horizontal lines.
+ else if(py == ny)
+ Dy = 0;
+
+ // Diagonal lines (|∆x| = |∆y|).
+ else if(abs(px - nx) == abs(py - ny))
+ ;
+
+ // No valid intermediate dots.
+ else
return;
- }
- if(!DotUsed(mid))
- ConnectDot(mid);
+ // Iterate along axis, adding dots in the correct order.
+ while((Dy == 0 || y != ny - Dy) && (Dx == 0 || x != nx - Dx)) {
+ x += Dx;
+ y += Dy;
+
+ int idx = mGridSize * y + x;
+ if(!DotUsed(idx))
+ ConnectDot(idx);
+ }
}
int GUIPatternPassword::NotifyTouch(TOUCH_STATE state, int x, int y)
@@ -303,15 +391,65 @@ int GUIPatternPassword::NotifyTouch(TOUCH_STATE state, int x, int y)
return 0;
}
+int GUIPatternPassword::NotifyVarChange(const std::string& varName, const std::string& value)
+{
+ if(!isConditionTrue())
+ return 0;
+
+ if(varName == mSizeVar) {
+ Resize(atoi(value.c_str()));
+ mUpdate = true;
+ }
+ return 0;
+}
+
+std::string GUIPatternPassword::GeneratePassphrase()
+{
+ char pattern[mConnectedDotsLen];
+ for(size_t i = 0; i < mConnectedDotsLen; i++) {
+ pattern[i] = (char) mConnectedDots[i];
+ }
+
+ std::stringstream pass;
+
+ for(size_t i = 0; i < mConnectedDotsLen; i++) {
+ int digit = pattern[i] & 0xff;
+
+ /*
+ * Okay, rant time.
+ * It turns out that Android and CyanogenMod have *two* separate methods
+ * for generating passphrases from patterns. This is a legacy issue, as
+ * Android only supports 3x3 grids, and so we need to support both.
+ * Luckily, CyanogenMod is in the same boat as us and needs to support
+ * Android's 3x3 encryption style.
+ *
+ * In order to generate a 3x3 passphrase, add 1 to each dot index
+ * and concatenate the string representation of the integers. No
+ * padding should be added.
+ *
+ * For *all* other NxN passphrases (until a 16x16 grid comes along),
+ * they are generated by taking "%.2x" for each dot index and
+ * concatenating the results (without adding 1).
+ */
+
+ if(mGridSize == 3)
+ // Android (legacy) 3x3 grids.
+ pass << digit + 1;
+ else {
+ // Other NxN grids.
+ char buffer[3];
+ snprintf(buffer, 3, "%.2x", digit);
+ pass << std::string(buffer);
+ }
+ }
+
+ return pass.str();
+}
+
void GUIPatternPassword::PatternDrawn()
{
if(!mPassVar.empty() && mConnectedDotsLen > 0)
- {
- std::string pass;
- for(size_t i = 0; i < mConnectedDotsLen; ++i)
- pass += '1' + mConnectedDots[i];
- DataManager::SetValue(mPassVar, pass);
- }
+ DataManager::SetValue(mPassVar, GeneratePassphrase());
if(mAction)
mAction->doActions();
diff --git a/gui/theme/common/landscape.xml b/gui/theme/common/landscape.xml
index 938c8548d..35986dddc 100755
--- a/gui/theme/common/landscape.xml
+++ b/gui/theme/common/landscape.xml
@@ -176,6 +176,10 @@
<colors line="%fileselector_linecolor%"/>
<dimensions lineh="%slidervalue_lineh%" linepadding="%slidervalue_padding%" sliderw="%slidervalue_sliderw%" sliderh="%slidervalue_sliderh%"/>
</style>
+
+ <style name="patternpassword">
+ <size name="tw_gui_pattern_grid_size" default="3"/>
+ </style>
</styles>
<pages>
@@ -3911,19 +3915,48 @@
</text>
<text style="text_m_accent">
- <placement x="%center_x%" y="%row2_y%" placement="5"/>
+ <placement x="%col2_x_left%" y="%row2_y%" placement="5"/>
<text>{@decrypt_data_enter_pattern=Enter Pattern.}</text>
</text>
+ <text style="text_m_fail">
+ <condition var1="tw_password_fail" var2="1"/>
+ <placement x="%col2_x_left%" y="%row3_y%" placement="5"/>
+ <text>{@decryt_data_failed_pattern=Pattern failed, please try again!}</text>
+ </text>
+
<patternpassword>
- <placement x="%pattern_x%" y="%row4_y%" w="%pattern_size%" h="%pattern_size%"/>
- <size name="tw_pattern_grid_size" default="3"/>
+ <placement x="%pattern_x%" y="%row4a_y%" w="%pattern_size%" h="%pattern_size%"/>
<dot color="%fileselector_linecolor%" activecolor="%accent_color%" radius="%pattern_dot_dia%"/>
<line color="%fileselector_linecolor%" width="%pattern_line_w%"/>
<data name="tw_crypto_password"/>
<action function="page">trydecrypt</action>
</patternpassword>
+ <button style="main_button_half_width_low">
+ <placement x="%col_button_right%" y="%row1a_y%"/>
+ <text>3x3</text>
+ <action function="set">tw_gui_pattern_grid_size=3</action>
+ </button>
+
+ <button style="main_button_half_width_low">
+ <placement x="%col_button_right%" y="%row4a_y%"/>
+ <text>4x4</text>
+ <action function="set">tw_gui_pattern_grid_size=4</action>
+ </button>
+
+ <button style="main_button_half_width_low">
+ <placement x="%col_button_right%" y="%row7a_y%"/>
+ <text>5x5</text>
+ <action function="set">tw_gui_pattern_grid_size=5</action>
+ </button>
+
+ <button style="main_button_half_width_low">
+ <placement x="%col_button_right%" y="%row10a_y%"/>
+ <text>6x6</text>
+ <action function="set">tw_gui_pattern_grid_size=6</action>
+ </button>
+
<button style="main_button_half_width">
<placement x="%col2_x_right%" y="%row15a_y%"/>
<text>{@cancel_btn=Cancel}</text>
diff --git a/gui/theme/common/languages/en.xml b/gui/theme/common/languages/en.xml
index 2847d2253..e417ace54 100755
--- a/gui/theme/common/languages/en.xml
+++ b/gui/theme/common/languages/en.xml
@@ -435,6 +435,7 @@
<string name="decrypt_data_hdr">Decrypt Data</string>
<string name="decrypt_data_enter_pass"></string>
<string name="decryt_data_failed">Password failed, please try again!</string>
+ <string name="decryt_data_failed_pattern">Pattern failed, please try again!</string>
<string name="decrypt_data_enter_pattern">Enter Pattern.</string>
<string name="decrypt_data_trying">Trying Decryption</string>
<string name="term_hdr">Terminal Command</string>
diff --git a/gui/theme/common/portrait.xml b/gui/theme/common/portrait.xml
index 2cd49e4c6..2d399babe 100755
--- a/gui/theme/common/portrait.xml
+++ b/gui/theme/common/portrait.xml
@@ -141,6 +141,10 @@
<colors line="%fileselector_linecolor%"/>
<dimensions lineh="%slidervalue_lineh%" linepadding="%slidervalue_padding%" sliderw="%slidervalue_sliderw%" sliderh="%slidervalue_sliderh%"/>
</style>
+
+ <style name="patternpassword">
+ <size name="tw_gui_pattern_grid_size" default="3"/>
+ </style>
</styles>
<pages>
@@ -3986,15 +3990,44 @@
<text>{@decrypt_data_enter_pattern=Enter Pattern.}</text>
</text>
+ <text style="text_m_fail">
+ <condition var1="tw_password_fail" var2="1"/>
+ <placement x="%center_x%" y="%row3_y%" placement="5"/>
+ <text>{@decryt_data_failed_pattern=Pattern failed, please try again!}</text>
+ </text>
+
<patternpassword>
- <placement x="%pattern_x%" y="%row6_y%" w="%pattern_size%" h="%pattern_size%"/>
- <size name="tw_pattern_grid_size" default="3"/>
+ <placement x="%pattern_x%" y="%row5_y%" w="%pattern_size%" h="%pattern_size%"/>
<dot color="%fileselector_linecolor%" activecolor="%accent_color%" radius="%pattern_dot_dia%"/>
<line color="%fileselector_linecolor%" width="%pattern_line_w%"/>
<data name="tw_crypto_password"/>
<action function="page">trydecrypt</action>
</patternpassword>
+ <button style="button_quarter_width">
+ <placement x="%indent%" y="%row19a_y%"/>
+ <text>3x3</text>
+ <action function="set">tw_gui_pattern_grid_size=3</action>
+ </button>
+
+ <button style="button_quarter_width">
+ <placement x="%btn4_col2_x%" y="%row19a_y%"/>
+ <text>4x4</text>
+ <action function="set">tw_gui_pattern_grid_size=4</action>
+ </button>
+
+ <button style="button_quarter_width">
+ <placement x="%btn4_col3_x%" y="%row19a_y%"/>
+ <text>5x5</text>
+ <action function="set">tw_gui_pattern_grid_size=5</action>
+ </button>
+
+ <button style="button_quarter_width">
+ <placement x="%btn4_col4_x%" y="%row19a_y%"/>
+ <text>6x6</text>
+ <action function="set">tw_gui_pattern_grid_size=6</action>
+ </button>
+
<button style="main_button_half_height">
<placement x="%indent%" y="%row21a_y%"/>
<text>{@cancel_btn=Cancel}</text>
diff --git a/gui/theme/common/watch.xml b/gui/theme/common/watch.xml
index 2ed266aad..382b2e186 100755
--- a/gui/theme/common/watch.xml
+++ b/gui/theme/common/watch.xml
@@ -68,6 +68,10 @@
<image resource="tab_3"/>
</style>
+ <style name="button_navbar">
+ <font resource="font_m" color="%text_button_color%"/>
+ </style>
+
<style name="console">
<color foreground="%text_color%" background="%background_color%" scroll="%background_color%"/>
<font resource="fixed"/>
@@ -167,6 +171,10 @@
<colors line="%fileselector_linecolor%"/>
<dimensions lineh="%slidervalue_lineh%" linepadding="%slidervalue_padding%" sliderw="%slidervalue_sliderw%" sliderh="%slidervalue_sliderh%"/>
</style>
+
+ <style name="patternpassword">
+ <size name="tw_gui_pattern_grid_size" default="3"/>
+ </style>
</styles>
<pages>
@@ -4780,16 +4788,27 @@
<template name="statusbar"/>
+ <action>
+ <action function="set">tw_gui_pattern_grid_size=3</action>
+ </action>
+
<text style="text_m">
<placement x="%col1_x_left%" y="%row1_header_y%"/>
<text>{@mount_hdr=Mount} &gt; {@decrypt_data_hdr=Decrypt Data}</text>
</text>
<text style="text_m_accent">
+ <condition var1="tw_password_fail" op="!=" var2="1"/>
<placement x="%center_x%" y="%row5_y%" placement="5"/>
<text>{@decrypt_data_enter_pattern=Enter Pattern.}</text>
</text>
+ <text style="text_m_fail">
+ <condition var1="tw_password_fail" var2="1"/>
+ <placement x="%center_x%" y="%row5_y%" placement="5"/>
+ <text>{@decryt_data_failed_pattern=Pattern failed, please try again!}</text>
+ </text>
+
<text style="text_m">
<placement x="%center_x%" y="%row10_y%" placement="5"/>
<text>{@back_cancel=Press back to cancel.}</text>
@@ -4797,7 +4816,6 @@
<patternpassword>
<placement x="%pattern_x%" y="%row2_y%" w="%pattern_size%" h="%pattern_size%"/>
- <size name="tw_pattern_grid_size" default="3"/>
<dot color="%fileselector_linecolor%" activecolor="%accent_color%" radius="%pattern_dot_dia%"/>
<line color="%fileselector_linecolor%" width="%pattern_line_w%"/>
<data name="tw_crypto_password"/>
@@ -4817,6 +4835,62 @@
<action function="page">main</action>
</actions>
</button>
+
+ <button>
+ <condition var1="tw_gui_pattern_grid_size" var2="3"/>
+ <placement x="%center_x%" y="%navbar_btn_y%" placement="4"/>
+ <image resource="grid_less"/>
+ <action function="set">tw_gui_pattern_grid_size=3</action>
+ </button>
+
+ <button>
+ <condition var1="tw_gui_pattern_grid_size" var2="4"/>
+ <placement x="%center_x%" y="%navbar_btn_y%" placement="4"/>
+ <image resource="grid_less"/>
+ <action function="set">tw_gui_pattern_grid_size=3</action>
+ </button>
+
+ <button>
+ <condition var1="tw_gui_pattern_grid_size" var2="5"/>
+ <placement x="%center_x%" y="%navbar_btn_y%" placement="4"/>
+ <image resource="grid_less"/>
+ <action function="set">tw_gui_pattern_grid_size=4</action>
+ </button>
+
+ <button>
+ <condition var1="tw_gui_pattern_grid_size" var2="6"/>
+ <placement x="%center_x%" y="%navbar_btn_y%" placement="4"/>
+ <image resource="grid_less"/>
+ <action function="set">tw_gui_pattern_grid_size=5</action>
+ </button>
+
+ <button>
+ <condition var1="tw_gui_pattern_grid_size" var2="3"/>
+ <placement x="%console_button_x%" y="%navbar_btn_y%" placement="4"/>
+ <image resource="grid_more"/>
+ <action function="set">tw_gui_pattern_grid_size=4</action>
+ </button>
+
+ <button>
+ <condition var1="tw_gui_pattern_grid_size" var2="4"/>
+ <placement x="%console_button_x%" y="%navbar_btn_y%" placement="4"/>
+ <image resource="grid_more"/>
+ <action function="set">tw_gui_pattern_grid_size=5</action>
+ </button>
+
+ <button>
+ <condition var1="tw_gui_pattern_grid_size" var2="5"/>
+ <placement x="%console_button_x%" y="%navbar_btn_y%" placement="4"/>
+ <image resource="grid_more"/>
+ <action function="set">tw_gui_pattern_grid_size=6</action>
+ </button>
+
+ <button>
+ <condition var1="tw_gui_pattern_grid_size" var2="6"/>
+ <placement x="%console_button_x%" y="%navbar_btn_y%" placement="4"/>
+ <image resource="grid_more"/>
+ <action function="set">tw_gui_pattern_grid_size=6</action>
+ </button>
</page>
<page name="trydecrypt">
diff --git a/gui/theme/landscape_hdpi/ui.xml b/gui/theme/landscape_hdpi/ui.xml
index 824164137..e6a6b681c 100644
--- a/gui/theme/landscape_hdpi/ui.xml
+++ b/gui/theme/landscape_hdpi/ui.xml
@@ -206,7 +206,7 @@
<variable name="progress_x" value="552" />
<variable name="progress_text_x" value="96" />
<variable name="progress_text_y" value="900" />
- <variable name="pattern_x" value="636" />
+ <variable name="pattern_x" value="180" />
<variable name="pattern_dot_dia" value="32" />
<variable name="pattern_line_w" value="12" />
<variable name="pattern_size" value="648" />
diff --git a/gui/theme/landscape_mdpi/ui.xml b/gui/theme/landscape_mdpi/ui.xml
index 818c23d17..f4b34a79a 100644
--- a/gui/theme/landscape_mdpi/ui.xml
+++ b/gui/theme/landscape_mdpi/ui.xml
@@ -206,10 +206,10 @@
<variable name="progress_x" value="230" />
<variable name="progress_text_x" value="40" />
<variable name="progress_text_y" value="348" />
- <variable name="pattern_x" value="300" />
+ <variable name="pattern_x" value="84" />
<variable name="pattern_dot_dia" value="12" />
<variable name="pattern_line_w" value="4" />
- <variable name="pattern_size" value="200" />
+ <variable name="pattern_size" value="252" />
</variables>
<mousecursor>
diff --git a/gui/theme/portrait_hdpi/ui.xml b/gui/theme/portrait_hdpi/ui.xml
index 7708f926b..16937353f 100644
--- a/gui/theme/portrait_hdpi/ui.xml
+++ b/gui/theme/portrait_hdpi/ui.xml
@@ -198,10 +198,10 @@
<variable name="console_height" value="960" />
<variable name="console_terminal_height" value="576" />
<variable name="dialog_button_x" value="696" />
- <variable name="pattern_x" value="216" />
+ <variable name="pattern_x" value="126" />
<variable name="pattern_dot_dia" value="32" />
<variable name="pattern_line_w" value="12" />
- <variable name="pattern_size" value="648" />
+ <variable name="pattern_size" value="828" />
</variables>
<mousecursor>
diff --git a/gui/theme/portrait_mdpi/ui.xml b/gui/theme/portrait_mdpi/ui.xml
index 68fd32459..946132d2e 100644
--- a/gui/theme/portrait_mdpi/ui.xml
+++ b/gui/theme/portrait_mdpi/ui.xml
@@ -198,10 +198,10 @@
<variable name="console_height" value="390" />
<variable name="console_terminal_height" value="234" />
<variable name="dialog_button_x" value="310" />
- <variable name="pattern_x" value="88" />
+ <variable name="pattern_x" value="60" />
<variable name="pattern_dot_dia" value="12" />
<variable name="pattern_line_w" value="4" />
- <variable name="pattern_size" value="392" />
+ <variable name="pattern_size" value="360" />
</variables>
<mousecursor>
diff --git a/gui/theme/watch_mdpi/images/grid_less.png b/gui/theme/watch_mdpi/images/grid_less.png
new file mode 100644
index 000000000..7366c8ecf
--- /dev/null
+++ b/gui/theme/watch_mdpi/images/grid_less.png
Binary files differ
diff --git a/gui/theme/watch_mdpi/images/grid_more.png b/gui/theme/watch_mdpi/images/grid_more.png
new file mode 100644
index 000000000..cd51f7e2e
--- /dev/null
+++ b/gui/theme/watch_mdpi/images/grid_more.png
Binary files differ
diff --git a/gui/theme/watch_mdpi/ui.xml b/gui/theme/watch_mdpi/ui.xml
index 7c7715a2c..850a32f01 100644
--- a/gui/theme/watch_mdpi/ui.xml
+++ b/gui/theme/watch_mdpi/ui.xml
@@ -46,6 +46,8 @@
<resource name="home" type="image" filename="home" retainaspect="1" />
<resource name="back" type="image" filename="back" retainaspect="1" />
<resource name="console" type="image" filename="console" retainaspect="1" />
+ <resource name="grid_less" type="image" filename="grid_less" retainaspect="1" />
+ <resource name="grid_more" type="image" filename="grid_more" retainaspect="1" />
<resource name="checkbox_false" type="image" filename="checkbox_false" retainaspect="1" />
<resource name="checkbox_false_small" type="image" filename="checkbox_false_small" retainaspect="1" />
<resource name="checkbox_true" type="image" filename="checkbox_true" retainaspect="1" />
@@ -167,8 +169,8 @@
<variable name="console_terminal_height" value="64" />
<variable name="close_btn_x" value="280" />
<variable name="pattern_x" value="60" />
- <variable name="pattern_dot_dia" value="20" />
- <variable name="pattern_line_w" value="8" />
+ <variable name="pattern_dot_dia" value="12" />
+ <variable name="pattern_line_w" value="4" />
<variable name="pattern_size" value="200" />
</variables>