diff options
Diffstat (limited to 'gui')
241 files changed, 28472 insertions, 0 deletions
diff --git a/gui/Android.mk b/gui/Android.mk new file mode 100644 index 000000000..1fef03d41 --- /dev/null +++ b/gui/Android.mk @@ -0,0 +1,181 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_CFLAGS := -fno-strict-aliasing + +LOCAL_SRC_FILES := \ + gui.cpp \ + resources.cpp \ + pages.cpp \ + text.cpp \ + image.cpp \ + action.cpp \ + console.cpp \ + fill.cpp \ + button.cpp \ + checkbox.cpp \ + fileselector.cpp \ + progressbar.cpp \ + animation.cpp \ + object.cpp \ + slider.cpp \ + slidervalue.cpp \ + listbox.cpp \ + keyboard.cpp \ + input.cpp \ + blanktimer.cpp \ + partitionlist.cpp \ + mousecursor.cpp \ + scrolllist.cpp \ + patternpassword.cpp + +ifneq ($(TWRP_CUSTOM_KEYBOARD),) + LOCAL_SRC_FILES += $(TWRP_CUSTOM_KEYBOARD) +else + LOCAL_SRC_FILES += hardwarekeyboard.cpp +endif + +LOCAL_SHARED_LIBRARIES += libminuitwrp libc libstdc++ libminzip libaosprecovery +LOCAL_MODULE := libguitwrp + +#TWRP_EVENT_LOGGING := true +ifeq ($(TWRP_EVENT_LOGGING), true) + LOCAL_CFLAGS += -D_EVENT_LOGGING +endif +ifneq ($(TW_USE_KEY_CODE_TOUCH_SYNC),) + LOCAL_CFLAGS += -DTW_USE_KEY_CODE_TOUCH_SYNC=$(TW_USE_KEY_CODE_TOUCH_SYNC) +endif + +ifneq ($(TW_NO_SCREEN_BLANK),) + LOCAL_CFLAGS += -DTW_NO_SCREEN_BLANK +endif +ifneq ($(TW_NO_SCREEN_TIMEOUT),) + LOCAL_CFLAGS += -DTW_NO_SCREEN_TIMEOUT +endif +ifeq ($(HAVE_SELINUX), true) + LOCAL_CFLAGS += -DHAVE_SELINUX +endif +ifeq ($(TW_OEM_BUILD), true) + LOCAL_CFLAGS += -DTW_OEM_BUILD +endif +ifeq ($(TW_DISABLE_TTF), true) + LOCAL_CFLAGS += -DTW_DISABLE_TTF +endif +ifneq ($(TW_X_OFFSET),) + LOCAL_CFLAGS += -DTW_X_OFFSET=$(TW_X_OFFSET) +endif +ifneq ($(TW_Y_OFFSET),) + LOCAL_CFLAGS += -DTW_Y_OFFSET=$(TW_Y_OFFSET) +endif +ifeq ($(TW_ROUND_SCREEN), true) + LOCAL_CFLAGS += -DTW_ROUND_SCREEN +endif + +LOCAL_C_INCLUDES += bionic external/stlport/stlport system/core/libpixelflinger/include +LOCAL_CFLAGS += -DTWRES=\"$(TWRES_PATH)\" + +include $(BUILD_STATIC_LIBRARY) + +# Transfer in the resources for the device +include $(CLEAR_VARS) +LOCAL_MODULE := twrp +LOCAL_MODULE_TAGS := eng +LOCAL_MODULE_CLASS := RECOVERY_EXECUTABLES +LOCAL_MODULE_PATH := $(TARGET_RECOVERY_ROOT_OUT)$(TWRES_PATH) +TWRP_RES := $(commands_recovery_local_path)/gui/devices/common/res/* +# enable this to use new themes: +#TWRP_NEW_THEME := true + +ifeq ($(TW_CUSTOM_THEME),) + ifeq ($(TW_THEME),) + # This converts the old DEVICE_RESOLUTION flag to the new TW_THEME flag + PORTRAIT_MDPI := 320x480 480x800 480x854 540x960 + PORTRAIT_HDPI := 720x1280 800x1280 1080x1920 1200x1920 1440x2560 1600x2560 + WATCH_MDPI := 240x240 280x280 320x320 + LANDSCAPE_MDPI := 800x480 1024x600 1024x768 + LANDSCAPE_HDPI := 1280x800 1920x1200 2560x1600 + ifneq ($(filter $(DEVICE_RESOLUTION), $(PORTRAIT_MDPI)),) + TW_THEME := portrait_mdpi + else ifneq ($(filter $(DEVICE_RESOLUTION), $(PORTRAIT_HDPI)),) + TW_THEME := portrait_hdpi + else ifneq ($(filter $(DEVICE_RESOLUTION), $(WATCH_MDPI)),) + TW_THEME := watch_mdpi + else ifneq ($(filter $(DEVICE_RESOLUTION), $(LANDSCAPE_MDPI)),) + TW_THEME := landscape_mdpi + else ifneq ($(filter $(DEVICE_RESOLUTION), $(LANDSCAPE_HDPI)),) + TW_THEME := landscape_hdpi + endif + endif +ifeq ($(TWRP_NEW_THEME),true) + TWRP_THEME_LOC := $(commands_recovery_local_path)/gui/theme/$(TW_THEME) + TWRP_RES := $(commands_recovery_local_path)/gui/theme/common/fonts + TWRP_RES += $(commands_recovery_local_path)/gui/theme/common/$(word 1,$(subst _, ,$(TW_THEME))).xml +# for future copying of used include xmls and fonts: +# UI_XML := $(TWRP_THEME_LOC)/ui.xml +# TWRP_INCLUDE_XMLS := $(shell xmllint --xpath '/recovery/include/xmlfile/@name' $(UI_XML)|sed -n 's/[^\"]*\"\([^\"]*\)\"[^\"]*/\1\n/gp'|sort|uniq) +# TWRP_FONTS_TTF := $(shell xmllint --xpath '/recovery/resources/font/@filename' $(UI_XML)|sed -n 's/[^\"]*\"\([^\"]*\)\"[^\"]*/\1\n/gp'|sort|uniq) +# TWRP_FONTS_DAT := $(shell xmllint --xpath '/recovery/resources/font/@fallback' $(UI_XML)|sed -n 's/[^\"]*\"\([^\"]*\)\"[^\"]*/\1.dat\n/gp'|sort|uniq) +ifeq ($(wildcard $(TWRP_THEME_LOC)/ui.xml),) + $(warning ****************************************************************************) + $(warning * TW_THEME is not valid: '$(TW_THEME)') + $(warning * Please choose an appropriate TW_THEME or create a new one for your device.) + $(warning * Available themes:) + $(warning * $(notdir $(wildcard $(commands_recovery_local_path)/gui/theme/*_*))) + $(warning ****************************************************************************) + $(error stopping) +endif +else + TWRP_RES += $(commands_recovery_local_path)/gui/devices/$(word 1,$(subst _, ,$(TW_THEME)))/res/* + ifeq ($(TW_THEME), portrait_mdpi) + TWRP_THEME_LOC := $(commands_recovery_local_path)/gui/devices/480x800/res + else ifeq ($(TW_THEME), portrait_hdpi) + TWRP_THEME_LOC := $(commands_recovery_local_path)/gui/devices/1080x1920/res + else ifeq ($(TW_THEME), watch_mdpi) + TWRP_THEME_LOC := $(commands_recovery_local_path)/gui/devices/320x320/res + else ifeq ($(TW_THEME), landscape_mdpi) + TWRP_THEME_LOC := $(commands_recovery_local_path)/gui/devices/800x480/res + else ifeq ($(TW_THEME), landscape_hdpi) + TWRP_THEME_LOC := $(commands_recovery_local_path)/gui/devices/1920x1200/res + else + $(warning ****************************************************************************) + $(warning * TW_THEME ($(TW_THEME)) is not valid.) + $(warning * Please choose an appropriate TW_THEME or create a new one for your device.) + $(warning * Valid options are portrait_mdpi portrait_hdpi watch_mdpi) + $(warning * landscape_mdpi landscape_hdpi) + $(warning ****************************************************************************) + $(error stopping) + endif +endif +else + TWRP_THEME_LOC := $(TW_CUSTOM_THEME) +endif + +ifeq ($(TW_DISABLE_TTF), true) + TWRP_REMOVE_FONT := rm -f $(TARGET_RECOVERY_ROOT_OUT)$(TWRES_PATH)fonts/*.ttf +else + TWRP_REMOVE_FONT := rm -f $(TARGET_RECOVERY_ROOT_OUT)$(TWRES_PATH)fonts/*.dat +endif + +TWRP_RES_GEN := $(intermediates)/twrp +ifneq ($(TW_USE_TOOLBOX), true) + TWRP_SH_TARGET := /sbin/busybox +else + TWRP_SH_TARGET := /sbin/mksh +endif + +$(TWRP_RES_GEN): + mkdir -p $(TARGET_RECOVERY_ROOT_OUT)$(TWRES_PATH) + cp -fr $(TWRP_RES) $(TARGET_RECOVERY_ROOT_OUT)$(TWRES_PATH) + cp -fr $(TWRP_THEME_LOC)/* $(TARGET_RECOVERY_ROOT_OUT)$(TWRES_PATH) + $(TWRP_REMOVE_FONT) + mkdir -p $(TARGET_RECOVERY_ROOT_OUT)/sbin/ +ifneq ($(TW_USE_TOOLBOX), true) + ln -sf $(TWRP_SH_TARGET) $(TARGET_RECOVERY_ROOT_OUT)/sbin/sh +endif + ln -sf /sbin/pigz $(TARGET_RECOVERY_ROOT_OUT)/sbin/gzip + ln -sf /sbin/unpigz $(TARGET_RECOVERY_ROOT_OUT)/sbin/gunzip + + +LOCAL_GENERATED_SOURCES := $(TWRP_RES_GEN) +LOCAL_SRC_FILES := twrp $(TWRP_RES_GEN) +include $(BUILD_PREBUILT) diff --git a/gui/action.cpp b/gui/action.cpp new file mode 100644 index 000000000..0f8c7eea6 --- /dev/null +++ b/gui/action.cpp @@ -0,0 +1,1826 @@ +/*update + Copyright 2013 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <linux/input.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/wait.h> +#include <dirent.h> +#include <pwd.h> + +#include <string> +#include <sstream> +#include "../partitions.hpp" +#include "../twrp-functions.hpp" +#include "../openrecoveryscript.hpp" + +#include "../adb_install.h" +#include "../fuse_sideload.h" +#include "blanktimer.hpp" +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +#include "../variables.h" +#include "../twinstall.h" +#include "cutils/properties.h" +#include "../adb_install.h" +#include "../set_metadata.h" +}; + +#include "rapidxml.hpp" +#include "objects.hpp" +#include "../tw_atomic.hpp" + +void curtainClose(void); + +GUIAction::mapFunc GUIAction::mf; +std::set<string> GUIAction::setActionsRunningInCallerThread; +static string zip_queue[10]; +static int zip_queue_index; +static pthread_t terminal_command; +pid_t sideload_child_pid; + +static void *ActionThread_work_wrapper(void *data); + +class ActionThread +{ +public: + ActionThread(); + ~ActionThread(); + + void threadActions(GUIAction *act); + void run(void *data); +private: + friend void *ActionThread_work_wrapper(void*); + struct ThreadData + { + ActionThread *this_; + GUIAction *act; + ThreadData(ActionThread *this_, GUIAction *act) : this_(this_), act(act) {} + }; + + pthread_t m_thread; + bool m_thread_running; + pthread_mutex_t m_act_lock; +}; + +static ActionThread action_thread; // for all kinds of longer running actions +static ActionThread cancel_thread; // for longer running "cancel" actions + +static void *ActionThread_work_wrapper(void *data) +{ + static_cast<ActionThread::ThreadData*>(data)->this_->run(data); + return NULL; +} + +ActionThread::ActionThread() +{ + m_thread_running = false; + pthread_mutex_init(&m_act_lock, NULL); +} + +ActionThread::~ActionThread() +{ + pthread_mutex_lock(&m_act_lock); + if(m_thread_running) { + pthread_mutex_unlock(&m_act_lock); + pthread_join(m_thread, NULL); + } else { + pthread_mutex_unlock(&m_act_lock); + } + pthread_mutex_destroy(&m_act_lock); +} + +void ActionThread::threadActions(GUIAction *act) +{ + pthread_mutex_lock(&m_act_lock); + if (m_thread_running) { + pthread_mutex_unlock(&m_act_lock); + LOGERR("Another threaded action is already running -- not running %u actions starting with '%s'\n", + act->mActions.size(), act->mActions[0].mFunction.c_str()); + } else { + m_thread_running = true; + pthread_mutex_unlock(&m_act_lock); + ThreadData *d = new ThreadData(this, act); + pthread_create(&m_thread, NULL, &ActionThread_work_wrapper, d); + } +} + +void ActionThread::run(void *data) +{ + ThreadData *d = (ThreadData*)data; + GUIAction* act = d->act; + + std::vector<GUIAction::Action>::iterator it; + for (it = act->mActions.begin(); it != act->mActions.end(); ++it) + act->doAction(*it); + + pthread_mutex_lock(&m_act_lock); + m_thread_running = false; + pthread_mutex_unlock(&m_act_lock); + delete d; +} + +GUIAction::GUIAction(xml_node<>* node) + : GUIObject(node) +{ + xml_node<>* child; + xml_node<>* actions; + xml_attribute<>* attr; + + if (!node) return; + + if (mf.empty()) { +#define ADD_ACTION(n) mf[#n] = &GUIAction::n +#define ADD_ACTION_EX(name, func) mf[name] = &GUIAction::func + // These actions will be run in the caller's thread + ADD_ACTION(reboot); + ADD_ACTION(home); + ADD_ACTION(key); + ADD_ACTION(page); + ADD_ACTION(reload); + ADD_ACTION(readBackup); + ADD_ACTION(set); + ADD_ACTION(clear); + ADD_ACTION(mount); + ADD_ACTION(unmount); + ADD_ACTION_EX("umount", unmount); + ADD_ACTION(restoredefaultsettings); + ADD_ACTION(copylog); + ADD_ACTION(compute); + ADD_ACTION_EX("addsubtract", compute); + ADD_ACTION(setguitimezone); + ADD_ACTION(overlay); + ADD_ACTION(queuezip); + ADD_ACTION(cancelzip); + ADD_ACTION(queueclear); + ADD_ACTION(sleep); + ADD_ACTION(appenddatetobackupname); + ADD_ACTION(generatebackupname); + ADD_ACTION(checkpartitionlist); + ADD_ACTION(getpartitiondetails); + ADD_ACTION(screenshot); + ADD_ACTION(setbrightness); + ADD_ACTION(fileexists); + ADD_ACTION(killterminal); + ADD_ACTION(checkbackupname); + ADD_ACTION(adbsideloadcancel); + ADD_ACTION(fixsu); + ADD_ACTION(startmtp); + ADD_ACTION(stopmtp); + ADD_ACTION(cancelbackup); + ADD_ACTION(checkpartitionlifetimewrites); + ADD_ACTION(mountsystemtoggle); + + // remember actions that run in the caller thread + for (mapFunc::const_iterator it = mf.begin(); it != mf.end(); ++it) + setActionsRunningInCallerThread.insert(it->first); + + // These actions will run in a separate thread + ADD_ACTION(flash); + ADD_ACTION(wipe); + ADD_ACTION(refreshsizes); + ADD_ACTION(nandroid); + ADD_ACTION(fixpermissions); + ADD_ACTION(dd); + ADD_ACTION(partitionsd); + ADD_ACTION(installhtcdumlock); + ADD_ACTION(htcdumlockrestoreboot); + ADD_ACTION(htcdumlockreflashrecovery); + ADD_ACTION(cmd); + ADD_ACTION(terminalcommand); + ADD_ACTION(reinjecttwrp); + ADD_ACTION(decrypt); + ADD_ACTION(adbsideload); + ADD_ACTION(openrecoveryscript); + ADD_ACTION(installsu); + ADD_ACTION(decrypt_backup); + ADD_ACTION(repair); + ADD_ACTION(resize); + ADD_ACTION(changefilesystem); + ADD_ACTION(flashimage); + } + + // First, get the action + actions = FindNode(node, "actions"); + if (actions) child = FindNode(actions, "action"); + else child = FindNode(node, "action"); + + if (!child) return; + + while (child) + { + Action action; + + attr = child->first_attribute("function"); + if (!attr) return; + + action.mFunction = attr->value(); + action.mArg = child->value(); + mActions.push_back(action); + + child = child->next_sibling("action"); + } + + // Now, let's get either the key or region + child = FindNode(node, "touch"); + if (child) + { + attr = child->first_attribute("key"); + if (attr) + { + 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 + { + attr = child->first_attribute("x"); + if (!attr) return; + mActionX = atol(attr->value()); + attr = child->first_attribute("y"); + if (!attr) return; + mActionY = atol(attr->value()); + attr = child->first_attribute("w"); + if (!attr) return; + mActionW = atol(attr->value()); + attr = child->first_attribute("h"); + if (!attr) return; + mActionH = atol(attr->value()); + } + } +} + +int GUIAction::NotifyTouch(TOUCH_STATE state, int x, int y) +{ + if (state == TOUCH_RELEASE) + doActions(); + + return 0; +} + +int GUIAction::NotifyKey(int key, bool down) +{ + 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(); + } + + return 0; +} + +int GUIAction::NotifyVarChange(const std::string& varName, const std::string& value) +{ + GUIObject::NotifyVarChange(varName, value); + + if (varName.empty() && !isConditionValid() && mKeys.empty() && !mActionW) + doActions(); + else if((varName.empty() || IsConditionVariable(varName)) && isConditionValid() && isConditionTrue()) + doActions(); + + return 0; +} + +void GUIAction::simulate_progress_bar(void) +{ + gui_print("Simulating actions...\n"); + for (int i = 0; i < 5; i++) + { + if (PartitionManager.stop_backup.get_value()) { + DataManager::SetValue("tw_cancel_backup", 1); + gui_print("Backup Canceled.\n"); + DataManager::SetValue("ui_progress", 0); + PartitionManager.stop_backup.set_value(0); + return; + } + usleep(500000); + DataManager::SetValue("ui_progress", i * 20); + } +} + +int GUIAction::flash_zip(std::string filename, int* wipe_cache) +{ + int ret_val = 0; + + DataManager::SetValue("ui_progress", 0); + + if (filename.empty()) + { + LOGERR("No file specified.\n"); + return -1; + } + + if (!PartitionManager.Mount_By_Path(filename, true)) + return -1; + + if (simulate) { + simulate_progress_bar(); + } else { + ret_val = TWinstall_zip(filename.c_str(), wipe_cache); + + // Now, check if we need to ensure TWRP remains installed... + struct stat st; + if (stat("/sbin/installTwrp", &st) == 0) + { + DataManager::SetValue("tw_operation", "Configuring TWRP"); + DataManager::SetValue("tw_partition", ""); + gui_print("Configuring TWRP...\n"); + if (TWFunc::Exec_Cmd("/sbin/installTwrp reinstall") < 0) + { + gui_print("Unable to configure TWRP with this kernel.\n"); + } + } + } + + // Done + DataManager::SetValue("ui_progress", 100); + DataManager::SetValue("ui_progress", 0); + return ret_val; +} + +GUIAction::ThreadType GUIAction::getThreadType(const GUIAction::Action& action) +{ + string func = gui_parse_text(action.mFunction); + bool needsThread = setActionsRunningInCallerThread.find(func) == setActionsRunningInCallerThread.end(); + if (needsThread) { + if (func == "cancelbackup") + return THREAD_CANCEL; + else + return THREAD_ACTION; + } + return THREAD_NONE; +} + +int GUIAction::doActions() +{ + if (mActions.size() < 1) + return -1; + + // Determine in which thread to run the actions. + // Do it for all actions at once before starting, so that we can cancel the whole batch if the thread is already busy. + ThreadType threadType = THREAD_NONE; + std::vector<Action>::iterator it; + for (it = mActions.begin(); it != mActions.end(); ++it) { + ThreadType tt = getThreadType(*it); + if (tt == THREAD_NONE) + continue; + if (threadType == THREAD_NONE) + threadType = tt; + else if (threadType != tt) { + LOGERR("Can't mix normal and cancel actions in the same list.\n" + "Running the whole batch in the cancel thread.\n"); + threadType = THREAD_CANCEL; + break; + } + } + + // Now run the actions in the desired thread. + switch (threadType) { + case THREAD_ACTION: + action_thread.threadActions(this); + break; + + case THREAD_CANCEL: + cancel_thread.threadActions(this); + break; + + default: { + // no iterators here because theme reloading might kill our object + const size_t cnt = mActions.size(); + for (size_t i = 0; i < cnt; ++i) + doAction(mActions[i]); + } + } + + return 0; +} + +int GUIAction::doAction(Action action) +{ + DataManager::GetValue(TW_SIMULATE_ACTIONS, simulate); + + std::string function = gui_parse_text(action.mFunction); + std::string arg = gui_parse_text(action.mArg); + + // find function and execute it + mapFunc::const_iterator funcitr = mf.find(function); + if (funcitr != mf.end()) + return (this->*funcitr->second)(arg); + + LOGERR("Unknown action '%s'\n", function.c_str()); + return -1; +} + +void GUIAction::operation_start(const string operation_name) +{ + LOGINFO("operation_start: '%s'\n", operation_name.c_str()); + time(&Start); + DataManager::SetValue(TW_ACTION_BUSY, 1); + DataManager::SetValue("ui_progress", 0); + DataManager::SetValue("tw_operation", operation_name); + DataManager::SetValue("tw_operation_state", 0); + DataManager::SetValue("tw_operation_status", 0); +} + +void GUIAction::operation_end(const int operation_status) +{ + time_t Stop; + int simulate_fail; + DataManager::SetValue("ui_progress", 100); + if (simulate) { + DataManager::GetValue(TW_SIMULATE_FAIL, simulate_fail); + if (simulate_fail != 0) + DataManager::SetValue("tw_operation_status", 1); + else + DataManager::SetValue("tw_operation_status", 0); + } else { + if (operation_status != 0) { + DataManager::SetValue("tw_operation_status", 1); + } + else { + DataManager::SetValue("tw_operation_status", 0); + } + } + DataManager::SetValue("tw_operation_state", 1); + DataManager::SetValue(TW_ACTION_BUSY, 0); + blankTimer.resetTimerAndUnblank(); + time(&Stop); + if ((int) difftime(Stop, Start) > 10) + DataManager::Vibrate("tw_action_vibrate"); + LOGINFO("operation_end - status=%d\n", operation_status); +} + +int GUIAction::reboot(std::string arg) +{ + //curtainClose(); this sometimes causes a crash + + sync(); + DataManager::SetValue("tw_gui_done", 1); + DataManager::SetValue("tw_reboot_arg", arg); + + return 0; +} + +int GUIAction::home(std::string arg) +{ + PageManager::SelectPackage("TWRP"); + gui_changePage("main"); + return 0; +} + +int GUIAction::key(std::string arg) +{ + const int key = getKeyByName(arg); + PageManager::NotifyKey(key, true); + PageManager::NotifyKey(key, false); + return 0; +} + +int GUIAction::page(std::string arg) +{ + std::string page_name = gui_parse_text(arg); + return gui_changePage(page_name); +} + +int GUIAction::reload(std::string arg) +{ + int check = 0, ret_val = 0; + std::string theme_path; + + theme_path = DataManager::GetSettingsStoragePath(); + if (PartitionManager.Mount_By_Path(theme_path.c_str(), 1) < 0) { + LOGERR("Unable to mount %s during reload function startup.\n", theme_path.c_str()); + check = 1; + } + + theme_path += "/TWRP/theme/ui.zip"; + if (check != 0 || PageManager::ReloadPackage("TWRP", theme_path) != 0) + { + // Loading the custom theme failed - try loading the stock theme + LOGINFO("Attempting to reload stock theme...\n"); + if (PageManager::ReloadPackage("TWRP", TWRES "ui.xml")) + { + LOGERR("Failed to load base packages.\n"); + ret_val = 1; + } + } + return 0; +} + +int GUIAction::readBackup(std::string arg) +{ + string Restore_Name; + DataManager::GetValue("tw_restore", Restore_Name); + PartitionManager.Set_Restore_Files(Restore_Name); + return 0; +} + +int GUIAction::set(std::string arg) +{ + if (arg.find('=') != string::npos) + { + string varName = arg.substr(0, arg.find('=')); + string value = arg.substr(arg.find('=') + 1, string::npos); + + DataManager::GetValue(value, value); + DataManager::SetValue(varName, value); + } + else + DataManager::SetValue(arg, "1"); + return 0; +} + +int GUIAction::clear(std::string arg) +{ + DataManager::SetValue(arg, "0"); + return 0; +} + +int GUIAction::mount(std::string arg) +{ + if (arg == "usb") { + DataManager::SetValue(TW_ACTION_BUSY, 1); + if (!simulate) + PartitionManager.usb_storage_enable(); + else + gui_print("Simulating actions...\n"); + } else if (!simulate) { + PartitionManager.Mount_By_Path(arg, true); + PartitionManager.Add_MTP_Storage(arg); + } else + gui_print("Simulating actions...\n"); + return 0; +} + +int GUIAction::unmount(std::string arg) +{ + if (arg == "usb") { + if (!simulate) + PartitionManager.usb_storage_disable(); + else + gui_print("Simulating actions...\n"); + DataManager::SetValue(TW_ACTION_BUSY, 0); + } else if (!simulate) { + PartitionManager.UnMount_By_Path(arg, true); + } else + gui_print("Simulating actions...\n"); + return 0; +} + +int GUIAction::restoredefaultsettings(std::string arg) +{ + operation_start("Restore Defaults"); + if (simulate) // Simulated so that people don't accidently wipe out the "simulation is on" setting + gui_print("Simulating actions...\n"); + else { + DataManager::ResetDefaults(); + PartitionManager.Update_System_Details(); + PartitionManager.Mount_Current_Storage(true); + } + operation_end(0); + return 0; +} + +int GUIAction::copylog(std::string arg) +{ + operation_start("Copy Log"); + if (!simulate) + { + string dst; + PartitionManager.Mount_Current_Storage(true); + dst = DataManager::GetCurrentStoragePath() + "/recovery.log"; + TWFunc::copy_file("/tmp/recovery.log", dst.c_str(), 0755); + tw_set_default_metadata(dst.c_str()); + sync(); + gui_print("Copied recovery log to %s.\n", DataManager::GetCurrentStoragePath().c_str()); + } else + simulate_progress_bar(); + operation_end(0); + return 0; +} + + +int GUIAction::compute(std::string arg) +{ + if (arg.find("+") != string::npos) + { + string varName = arg.substr(0, arg.find('+')); + string string_to_add = arg.substr(arg.find('+') + 1, string::npos); + int amount_to_add = atoi(string_to_add.c_str()); + int value; + + DataManager::GetValue(varName, value); + DataManager::SetValue(varName, value + amount_to_add); + return 0; + } + if (arg.find("-") != string::npos) + { + string varName = arg.substr(0, arg.find('-')); + string string_to_subtract = arg.substr(arg.find('-') + 1, string::npos); + int amount_to_subtract = atoi(string_to_subtract.c_str()); + int value; + + DataManager::GetValue(varName, value); + value -= amount_to_subtract; + if (value <= 0) + value = 0; + DataManager::SetValue(varName, value); + return 0; + } + if (arg.find("*") != string::npos) + { + string varName = arg.substr(0, arg.find('*')); + string multiply_by_str = gui_parse_text(arg.substr(arg.find('*') + 1, string::npos)); + int multiply_by = atoi(multiply_by_str.c_str()); + int value; + + DataManager::GetValue(varName, value); + DataManager::SetValue(varName, value*multiply_by); + return 0; + } + if (arg.find("/") != string::npos) + { + string varName = arg.substr(0, arg.find('/')); + string divide_by_str = gui_parse_text(arg.substr(arg.find('/') + 1, string::npos)); + int divide_by = atoi(divide_by_str.c_str()); + int value; + + if(divide_by != 0) + { + DataManager::GetValue(varName, value); + DataManager::SetValue(varName, value/divide_by); + } + return 0; + } + LOGERR("Unable to perform compute '%s'\n", arg.c_str()); + return -1; +} + +int GUIAction::setguitimezone(std::string arg) +{ + string SelectedZone; + DataManager::GetValue(TW_TIME_ZONE_GUISEL, SelectedZone); // read the selected time zone into SelectedZone + string Zone = SelectedZone.substr(0, SelectedZone.find(';')); // parse to get time zone + string DSTZone = SelectedZone.substr(SelectedZone.find(';') + 1, string::npos); // parse to get DST component + + int dst; + DataManager::GetValue(TW_TIME_ZONE_GUIDST, dst); // check wether user chose to use DST + + string offset; + DataManager::GetValue(TW_TIME_ZONE_GUIOFFSET, offset); // pull in offset + + string NewTimeZone = Zone; + if (offset != "0") + NewTimeZone += ":" + offset; + + if (dst != 0) + NewTimeZone += DSTZone; + + DataManager::SetValue(TW_TIME_ZONE_VAR, NewTimeZone); + DataManager::update_tz_environment_variables(); + return 0; +} + +int GUIAction::overlay(std::string arg) +{ + return gui_changeOverlay(arg); +} + +int GUIAction::queuezip(std::string arg) +{ + if (zip_queue_index >= 10) { + gui_print("Maximum zip queue reached!\n"); + return 0; + } + DataManager::GetValue("tw_filename", zip_queue[zip_queue_index]); + if (strlen(zip_queue[zip_queue_index].c_str()) > 0) { + zip_queue_index++; + DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index); + } + return 0; +} + +int GUIAction::cancelzip(std::string arg) +{ + if (zip_queue_index <= 0) { + gui_print("Minimum zip queue reached!\n"); + return 0; + } else { + zip_queue_index--; + DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index); + } + return 0; +} + +int GUIAction::queueclear(std::string arg) +{ + zip_queue_index = 0; + DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index); + return 0; +} + +int GUIAction::sleep(std::string arg) +{ + operation_start("Sleep"); + usleep(atoi(arg.c_str())); + operation_end(0); + return 0; +} + +int GUIAction::appenddatetobackupname(std::string arg) +{ + operation_start("AppendDateToBackupName"); + string Backup_Name; + DataManager::GetValue(TW_BACKUP_NAME, Backup_Name); + Backup_Name += TWFunc::Get_Current_Date(); + if (Backup_Name.size() > MAX_BACKUP_NAME_LEN) + Backup_Name.resize(MAX_BACKUP_NAME_LEN); + DataManager::SetValue(TW_BACKUP_NAME, Backup_Name); + operation_end(0); + return 0; +} + +int GUIAction::generatebackupname(std::string arg) +{ + operation_start("GenerateBackupName"); + TWFunc::Auto_Generate_Backup_Name(); + operation_end(0); + return 0; +} + +int GUIAction::checkpartitionlist(std::string arg) +{ + string Wipe_List, wipe_path; + int count = 0; + + DataManager::GetValue("tw_wipe_list", Wipe_List); + LOGINFO("checkpartitionlist list '%s'\n", Wipe_List.c_str()); + if (!Wipe_List.empty()) { + size_t start_pos = 0, end_pos = Wipe_List.find(";", start_pos); + while (end_pos != string::npos && start_pos < Wipe_List.size()) { + wipe_path = Wipe_List.substr(start_pos, end_pos - start_pos); + LOGINFO("checkpartitionlist wipe_path '%s'\n", wipe_path.c_str()); + if (wipe_path == "/and-sec" || wipe_path == "DALVIK" || wipe_path == "INTERNAL") { + // Do nothing + } else { + count++; + } + start_pos = end_pos + 1; + end_pos = Wipe_List.find(";", start_pos); + } + DataManager::SetValue("tw_check_partition_list", count); + } else { + DataManager::SetValue("tw_check_partition_list", 0); + } + return 0; +} + +int GUIAction::getpartitiondetails(std::string arg) +{ + string Wipe_List, wipe_path; + int count = 0; + + DataManager::GetValue("tw_wipe_list", Wipe_List); + LOGINFO("getpartitiondetails list '%s'\n", Wipe_List.c_str()); + if (!Wipe_List.empty()) { + size_t start_pos = 0, end_pos = Wipe_List.find(";", start_pos); + while (end_pos != string::npos && start_pos < Wipe_List.size()) { + wipe_path = Wipe_List.substr(start_pos, end_pos - start_pos); + LOGINFO("getpartitiondetails wipe_path '%s'\n", wipe_path.c_str()); + if (wipe_path == "/and-sec" || wipe_path == "DALVIK" || wipe_path == "INTERNAL") { + // Do nothing + } else { + DataManager::SetValue("tw_partition_path", wipe_path); + break; + } + start_pos = end_pos + 1; + end_pos = Wipe_List.find(";", start_pos); + } + if (!wipe_path.empty()) { + TWPartition* Part = PartitionManager.Find_Partition_By_Path(wipe_path); + if (Part) { + unsigned long long mb = 1048576; + + DataManager::SetValue("tw_partition_name", Part->Display_Name); + DataManager::SetValue("tw_partition_mount_point", Part->Mount_Point); + DataManager::SetValue("tw_partition_file_system", Part->Current_File_System); + DataManager::SetValue("tw_partition_size", Part->Size / mb); + DataManager::SetValue("tw_partition_used", Part->Used / mb); + DataManager::SetValue("tw_partition_free", Part->Free / mb); + DataManager::SetValue("tw_partition_backup_size", Part->Backup_Size / mb); + DataManager::SetValue("tw_partition_removable", Part->Removable); + DataManager::SetValue("tw_partition_is_present", Part->Is_Present); + + if (Part->Can_Repair()) + DataManager::SetValue("tw_partition_can_repair", 1); + else + DataManager::SetValue("tw_partition_can_repair", 0); + if (Part->Can_Resize()) + DataManager::SetValue("tw_partition_can_resize", 1); + else + DataManager::SetValue("tw_partition_can_resize", 0); + if (TWFunc::Path_Exists("/sbin/mkdosfs")) + DataManager::SetValue("tw_partition_vfat", 1); + else + DataManager::SetValue("tw_partition_vfat", 0); + if (TWFunc::Path_Exists("/sbin/mkfs.exfat")) + DataManager::SetValue("tw_partition_exfat", 1); + else + DataManager::SetValue("tw_partition_exfat", 0); + if (TWFunc::Path_Exists("/sbin/mkfs.f2fs")) + DataManager::SetValue("tw_partition_f2fs", 1); + else + DataManager::SetValue("tw_partition_f2fs", 0); + if (TWFunc::Path_Exists("/sbin/mke2fs")) + DataManager::SetValue("tw_partition_ext", 1); + else + DataManager::SetValue("tw_partition_ext", 0); + return 0; + } else { + LOGERR("Unable to locate partition: '%s'\n", wipe_path.c_str()); + } + } + } + DataManager::SetValue("tw_partition_name", ""); + DataManager::SetValue("tw_partition_file_system", ""); + return 0; +} + +int GUIAction::screenshot(std::string arg) +{ + time_t tm; + char path[256]; + int path_len; + uid_t uid = -1; + gid_t gid = -1; + + struct passwd *pwd = getpwnam("media_rw"); + if(pwd) { + uid = pwd->pw_uid; + gid = pwd->pw_gid; + } + + const std::string storage = DataManager::GetCurrentStoragePath(); + if(PartitionManager.Is_Mounted_By_Path(storage)) { + snprintf(path, sizeof(path), "%s/Pictures/Screenshots/", storage.c_str()); + } else { + strcpy(path, "/tmp/"); + } + + if(!TWFunc::Create_Dir_Recursive(path, 0666, uid, gid)) + return 0; + + tm = time(NULL); + path_len = strlen(path); + + // Screenshot_2014-01-01-18-21-38.png + strftime(path+path_len, sizeof(path)-path_len, "Screenshot_%Y-%m-%d-%H-%M-%S.png", localtime(&tm)); + + int res = gr_save_screenshot(path); + if(res == 0) { + chmod(path, 0666); + chown(path, uid, gid); + + gui_print("Screenshot was saved to %s\n", path); + + // blink to notify that the screenshow was taken + gr_color(255, 255, 255, 255); + gr_fill(0, 0, gr_fb_width(), gr_fb_height()); + gr_flip(); + gui_forceRender(); + } else { + LOGERR("Failed to take a screenshot!\n"); + } + return 0; +} + +int GUIAction::setbrightness(std::string arg) +{ + return TWFunc::Set_Brightness(arg); +} + +int GUIAction::fileexists(std::string arg) +{ + struct stat st; + string newpath = arg + "/."; + + operation_start("FileExists"); + if (stat(arg.c_str(), &st) == 0 || stat(newpath.c_str(), &st) == 0) + operation_end(0); + else + operation_end(1); + return 0; +} + +void GUIAction::reinject_after_flash() +{ + if (DataManager::GetIntValue(TW_HAS_INJECTTWRP) == 1 && DataManager::GetIntValue(TW_INJECT_AFTER_ZIP) == 1) { + gui_print("Injecting TWRP into boot image...\n"); + if (simulate) { + simulate_progress_bar(); + } else { + TWPartition* Boot = PartitionManager.Find_Partition_By_Path("/boot"); + if (Boot == NULL || Boot->Current_File_System != "emmc") + TWFunc::Exec_Cmd("injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash"); + else { + string injectcmd = "injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash bd=" + Boot->Actual_Block_Device; + TWFunc::Exec_Cmd(injectcmd); + } + gui_print("TWRP injection complete.\n"); + } + } +} + +int GUIAction::flash(std::string arg) +{ + int i, ret_val = 0, wipe_cache = 0; + // We're going to jump to this page first, like a loading page + gui_changePage(arg); + for (i=0; i<zip_queue_index; i++) { + string zip_path = zip_queue[i]; + size_t slashpos = zip_path.find_last_of('/'); + string zip_filename = (slashpos == string::npos) ? zip_path : zip_path.substr(slashpos + 1); + operation_start("Flashing"); + DataManager::SetValue("tw_filename", zip_path); + DataManager::SetValue("tw_file", zip_filename); + DataManager::SetValue(TW_ZIP_INDEX, (i + 1)); + + TWFunc::SetPerformanceMode(true); + ret_val = flash_zip(zip_path, &wipe_cache); + TWFunc::SetPerformanceMode(false); + if (ret_val != 0) { + gui_print("Error flashing zip '%s'\n", zip_path.c_str()); + ret_val = 1; + break; + } + } + zip_queue_index = 0; + + if (wipe_cache) { + gui_print("One or more zip requested a cache wipe\nWiping cache now.\n"); + PartitionManager.Wipe_By_Path("/cache"); + } + + reinject_after_flash(); + PartitionManager.Update_System_Details(); + operation_end(ret_val); + DataManager::SetValue(TW_ZIP_QUEUE_COUNT, zip_queue_index); + return 0; +} + +int GUIAction::wipe(std::string arg) +{ + operation_start("Format"); + DataManager::SetValue("tw_partition", arg); + + int ret_val = false; + + if (simulate) { + simulate_progress_bar(); + } else { + if (arg == "data") + ret_val = PartitionManager.Factory_Reset(); + else if (arg == "battery") + ret_val = PartitionManager.Wipe_Battery_Stats(); + else if (arg == "rotate") + ret_val = PartitionManager.Wipe_Rotate_Data(); + else if (arg == "dalvik") + ret_val = PartitionManager.Wipe_Dalvik_Cache(); + else if (arg == "DATAMEDIA") { + ret_val = PartitionManager.Format_Data(); + } else if (arg == "INTERNAL") { + int has_datamedia, dual_storage; + + DataManager::GetValue(TW_HAS_DATA_MEDIA, has_datamedia); + if (has_datamedia) { + ret_val = PartitionManager.Wipe_Media_From_Data(); + } else { + ret_val = PartitionManager.Wipe_By_Path(DataManager::GetSettingsStoragePath()); + } + } else if (arg == "EXTERNAL") { + string External_Path; + + DataManager::GetValue(TW_EXTERNAL_PATH, External_Path); + ret_val = PartitionManager.Wipe_By_Path(External_Path); + } else if (arg == "ANDROIDSECURE") { + ret_val = PartitionManager.Wipe_Android_Secure(); + } else if (arg == "LIST") { + string Wipe_List, wipe_path; + bool skip = false; + ret_val = true; + TWPartition* wipe_part = NULL; + + DataManager::GetValue("tw_wipe_list", Wipe_List); + LOGINFO("wipe list '%s'\n", Wipe_List.c_str()); + if (!Wipe_List.empty()) { + size_t start_pos = 0, end_pos = Wipe_List.find(";", start_pos); + while (end_pos != string::npos && start_pos < Wipe_List.size()) { + wipe_path = Wipe_List.substr(start_pos, end_pos - start_pos); + LOGINFO("wipe_path '%s'\n", wipe_path.c_str()); + if (wipe_path == "/and-sec") { + if (!PartitionManager.Wipe_Android_Secure()) { + LOGERR("Unable to wipe android secure\n"); + ret_val = false; + break; + } else { + skip = true; + } + } else if (wipe_path == "DALVIK") { + if (!PartitionManager.Wipe_Dalvik_Cache()) { + LOGERR("Failed to wipe dalvik\n"); + ret_val = false; + break; + } else { + skip = true; + } + } else if (wipe_path == "INTERNAL") { + if (!PartitionManager.Wipe_Media_From_Data()) { + ret_val = false; + break; + } else { + skip = true; + } + } + if (!skip) { + if (!PartitionManager.Wipe_By_Path(wipe_path)) { + LOGERR("Unable to wipe '%s'\n", wipe_path.c_str()); + ret_val = false; + break; + } else if (wipe_path == DataManager::GetSettingsStoragePath()) { + arg = wipe_path; + } + } else { + skip = false; + } + start_pos = end_pos + 1; + end_pos = Wipe_List.find(";", start_pos); + } + } + } else + ret_val = PartitionManager.Wipe_By_Path(arg); +#ifndef TW_OEM_BUILD + if (arg == DataManager::GetSettingsStoragePath()) { + // If we wiped the settings storage path, recreate the TWRP folder and dump the settings + string Storage_Path = DataManager::GetSettingsStoragePath(); + + if (PartitionManager.Mount_By_Path(Storage_Path, true)) { + LOGINFO("Making TWRP folder and saving settings.\n"); + Storage_Path += "/TWRP"; + mkdir(Storage_Path.c_str(), 0777); + DataManager::Flush(); + } else { + LOGERR("Unable to recreate TWRP folder and save settings.\n"); + } + } +#endif + } + PartitionManager.Update_System_Details(); + if (ret_val) + ret_val = 0; // 0 is success + else + ret_val = 1; // 1 is failure + operation_end(ret_val); + return 0; +} + +int GUIAction::refreshsizes(std::string arg) +{ + operation_start("Refreshing Sizes"); + if (simulate) { + simulate_progress_bar(); + } else + PartitionManager.Update_System_Details(); + operation_end(0); + return 0; +} + +int GUIAction::nandroid(std::string arg) +{ + if (simulate) { + PartitionManager.stop_backup.set_value(0); + DataManager::SetValue("tw_partition", "Simulation"); + simulate_progress_bar(); + operation_end(0); + } else { + operation_start("Nandroid"); + int ret = 0; + + if (arg == "backup") { + string Backup_Name; + DataManager::GetValue(TW_BACKUP_NAME, Backup_Name); + if (Backup_Name == "(Auto Generate)" || Backup_Name == "(Current Date)" || Backup_Name == "0" || Backup_Name == "(" || PartitionManager.Check_Backup_Name(true) == 0) { + ret = PartitionManager.Run_Backup(); + } + else { + operation_end(1); + return -1; + } + DataManager::SetValue(TW_BACKUP_NAME, "(Auto Generate)"); + } else if (arg == "restore") { + string Restore_Name; + DataManager::GetValue("tw_restore", Restore_Name); + ret = PartitionManager.Run_Restore(Restore_Name); + } else { + operation_end(1); + return -1; + } + DataManager::SetValue("tw_encrypt_backup", 0); + if (!PartitionManager.stop_backup.get_value()) { + if (ret == false) + ret = 1; // 1 for failure + else + ret = 0; // 0 for success + DataManager::SetValue("tw_cancel_backup", 0); + } + else { + DataManager::SetValue("tw_cancel_backup", 1); + gui_print("Backup Canceled.\n"); + ret = 0; + } + operation_end(ret); + return ret; + } + return 0; +} + +int GUIAction::cancelbackup(std::string arg) { + if (simulate) { + PartitionManager.stop_backup.set_value(1); + } + else { + int op_status = PartitionManager.Cancel_Backup(); + if (op_status != 0) + op_status = 1; // failure + } + + return 0; +} + +int GUIAction::fixpermissions(std::string arg) +{ + int op_status = 0; + + operation_start("Fix Permissions"); + LOGINFO("fix permissions started!\n"); + if (simulate) { + simulate_progress_bar(); + } else { + op_status = PartitionManager.Fix_Permissions(); + if (op_status != 0) + op_status = 1; // failure + } + operation_end(op_status); + return 0; +} + +int GUIAction::dd(std::string arg) +{ + operation_start("imaging"); + + if (simulate) { + simulate_progress_bar(); + } else { + string cmd = "dd " + arg; + TWFunc::Exec_Cmd(cmd); + } + operation_end(0); + return 0; +} + +int GUIAction::partitionsd(std::string arg) +{ + operation_start("Partition SD Card"); + int ret_val = 0; + + if (simulate) { + simulate_progress_bar(); + } else { + int allow_partition; + DataManager::GetValue(TW_ALLOW_PARTITION_SDCARD, allow_partition); + if (allow_partition == 0) { + gui_print("This device does not have a real SD Card!\nAborting!\n"); + } else { + if (!PartitionManager.Partition_SDCard()) + ret_val = 1; // failed + } + } + operation_end(ret_val); + return 0; + +} + +int GUIAction::installhtcdumlock(std::string arg) +{ + operation_start("Install HTC Dumlock"); + if (simulate) { + simulate_progress_bar(); + } else + TWFunc::install_htc_dumlock(); + + operation_end(0); + return 0; +} + +int GUIAction::htcdumlockrestoreboot(std::string arg) +{ + operation_start("HTC Dumlock Restore Boot"); + if (simulate) { + simulate_progress_bar(); + } else + TWFunc::htc_dumlock_restore_original_boot(); + + operation_end(0); + return 0; +} + +int GUIAction::htcdumlockreflashrecovery(std::string arg) +{ + operation_start("HTC Dumlock Reflash Recovery"); + if (simulate) { + simulate_progress_bar(); + } else + TWFunc::htc_dumlock_reflash_recovery_to_boot(); + + operation_end(0); + return 0; +} + +int GUIAction::cmd(std::string arg) +{ + int op_status = 0; + + operation_start("Command"); + LOGINFO("Running command: '%s'\n", arg.c_str()); + if (simulate) { + simulate_progress_bar(); + } else { + op_status = TWFunc::Exec_Cmd(arg); + if (op_status != 0) + op_status = 1; + } + + operation_end(op_status); + return 0; +} + +int GUIAction::terminalcommand(std::string arg) +{ + int op_status = 0; + string cmdpath, command; + + DataManager::GetValue("tw_terminal_location", cmdpath); + operation_start("CommandOutput"); + gui_print("%s # %s\n", cmdpath.c_str(), arg.c_str()); + if (simulate) { + simulate_progress_bar(); + operation_end(op_status); + } else if (arg == "exit") { + LOGINFO("Exiting terminal\n"); + operation_end(op_status); + page("main"); + } else { + command = "cd \"" + cmdpath + "\" && " + arg + " 2>&1";; + LOGINFO("Actual command is: '%s'\n", command.c_str()); + DataManager::SetValue("tw_terminal_state", 1); + DataManager::SetValue("tw_background_thread_running", 1); + FILE* fp; + char line[512]; + + fp = popen(command.c_str(), "r"); + if (fp == NULL) { + LOGERR("Error opening command to run.\n"); + } else { + int fd = fileno(fp), has_data = 0, check = 0, keep_going = -1, bytes_read = 0; + struct timeval timeout; + fd_set fdset; + + while(keep_going) + { + FD_ZERO(&fdset); + FD_SET(fd, &fdset); + timeout.tv_sec = 0; + timeout.tv_usec = 400000; + has_data = select(fd+1, &fdset, NULL, NULL, &timeout); + if (has_data == 0) { + // Timeout reached + DataManager::GetValue("tw_terminal_state", check); + if (check == 0) { + keep_going = 0; + } + } else if (has_data < 0) { + // End of execution + keep_going = 0; + } else { + // Try to read output + if(fgets(line, sizeof(line), fp) != NULL) + gui_print("%s", line); // Display output + else + keep_going = 0; // Done executing + } + } + fclose(fp); + } + DataManager::SetValue("tw_operation_status", 0); + DataManager::SetValue("tw_operation_state", 1); + DataManager::SetValue("tw_terminal_state", 0); + DataManager::SetValue("tw_background_thread_running", 0); + DataManager::SetValue(TW_ACTION_BUSY, 0); + } + return 0; +} + +int GUIAction::killterminal(std::string arg) +{ + int op_status = 0; + + LOGINFO("Sending kill command...\n"); + operation_start("KillCommand"); + DataManager::SetValue("tw_operation_status", 0); + DataManager::SetValue("tw_operation_state", 1); + DataManager::SetValue("tw_terminal_state", 0); + DataManager::SetValue("tw_background_thread_running", 0); + DataManager::SetValue(TW_ACTION_BUSY, 0); + return 0; +} + +int GUIAction::reinjecttwrp(std::string arg) +{ + int op_status = 0; + operation_start("ReinjectTWRP"); + gui_print("Injecting TWRP into boot image...\n"); + if (simulate) { + simulate_progress_bar(); + } else { + TWFunc::Exec_Cmd("injecttwrp --dump /tmp/backup_recovery_ramdisk.img /tmp/injected_boot.img --flash"); + gui_print("TWRP injection complete.\n"); + } + + operation_end(op_status); + return 0; +} + +int GUIAction::checkbackupname(std::string arg) +{ + int op_status = 0; + + operation_start("CheckBackupName"); + if (simulate) { + simulate_progress_bar(); + } else { + op_status = PartitionManager.Check_Backup_Name(true); + if (op_status != 0) + op_status = 1; + } + + operation_end(op_status); + return 0; +} + +int GUIAction::decrypt(std::string arg) +{ + int op_status = 0; + + operation_start("Decrypt"); + if (simulate) { + simulate_progress_bar(); + } else { + string Password; + DataManager::GetValue("tw_crypto_password", Password); + op_status = PartitionManager.Decrypt_Device(Password); + if (op_status != 0) + op_status = 1; + else { + + DataManager::SetValue(TW_IS_ENCRYPTED, 0); + + int has_datamedia; + + // Check for a custom theme and load it if exists + DataManager::GetValue(TW_HAS_DATA_MEDIA, has_datamedia); + if (has_datamedia != 0) { + if (tw_get_default_metadata(DataManager::GetSettingsStoragePath().c_str()) != 0) { + LOGINFO("Failed to get default contexts and file mode for storage files.\n"); + } else { + LOGINFO("Got default contexts and file mode for storage files.\n"); + } + } + } + } + + operation_end(op_status); + return 0; +} + +int GUIAction::adbsideload(std::string arg) +{ + operation_start("Sideload"); + if (simulate) { + simulate_progress_bar(); + operation_end(0); + } else { + gui_print("Starting ADB sideload feature...\n"); + bool mtp_was_enabled = TWFunc::Toggle_MTP(false); + + // wait for the adb connection + int ret = apply_from_adb("/", &sideload_child_pid); + DataManager::SetValue("tw_has_cancel", 0); // Remove cancel button from gui now that the zip install is going to start + + if (ret != 0) { + if (ret == -2) + gui_print("You need adb 1.0.32 or newer to sideload to this device.\n"); + ret = 1; // failure + } else { + int wipe_cache = 0; + int wipe_dalvik = 0; + DataManager::GetValue("tw_wipe_dalvik", wipe_dalvik); + + if (TWinstall_zip(FUSE_SIDELOAD_HOST_PATHNAME, &wipe_cache) == 0) { + if (wipe_cache || DataManager::GetIntValue("tw_wipe_cache")) + PartitionManager.Wipe_By_Path("/cache"); + if (wipe_dalvik) + PartitionManager.Wipe_Dalvik_Cache(); + } else { + ret = 1; // failure + } + } + if (sideload_child_pid) { + LOGINFO("Signaling child sideload process to exit.\n"); + struct stat st; + // Calling stat() on this magic filename signals the minadbd + // subprocess to shut down. + stat(FUSE_SIDELOAD_HOST_EXIT_PATHNAME, &st); + int status; + LOGINFO("Waiting for child sideload process to exit.\n"); + waitpid(sideload_child_pid, &status, 0); + } + property_set("ctl.start", "adbd"); + TWFunc::Toggle_MTP(mtp_was_enabled); + reinject_after_flash(); + operation_end(ret); + } + return 0; +} + +int GUIAction::adbsideloadcancel(std::string arg) +{ + struct stat st; + DataManager::SetValue("tw_has_cancel", 0); // Remove cancel button from gui + gui_print("Cancelling ADB sideload...\n"); + LOGINFO("Signaling child sideload process to exit.\n"); + // Calling stat() on this magic filename signals the minadbd + // subprocess to shut down. + stat(FUSE_SIDELOAD_HOST_EXIT_PATHNAME, &st); + if (!sideload_child_pid) { + LOGERR("Unable to get child ID\n"); + return 0; + } + ::sleep(1); + LOGINFO("Killing child sideload process.\n"); + kill(sideload_child_pid, SIGTERM); + int status; + LOGINFO("Waiting for child sideload process to exit.\n"); + waitpid(sideload_child_pid, &status, 0); + sideload_child_pid = 0; + DataManager::SetValue("tw_page_done", "1"); // For OpenRecoveryScript support + return 0; +} + +int GUIAction::openrecoveryscript(std::string arg) +{ + int op_status = 1; + + operation_start("OpenRecoveryScript"); + if (simulate) { + simulate_progress_bar(); + operation_end(0); + } else { + // Check for the SCRIPT_FILE_TMP first as these are AOSP recovery commands + // that we converted to ORS commands during boot in recovery.cpp. + // Run those first. + int reboot = 0; + if (TWFunc::Path_Exists(SCRIPT_FILE_TMP)) { + gui_print("Processing AOSP recovery commands...\n"); + if (OpenRecoveryScript::run_script_file() == 0) { + reboot = 1; + op_status = 0; + } + } + // Check for the ORS file in /cache and attempt to run those commands. + if (OpenRecoveryScript::check_for_script_file()) { + gui_print("Processing OpenRecoveryScript file...\n"); + if (OpenRecoveryScript::run_script_file() == 0) { + reboot = 1; + op_status = 0; + } + } + if (reboot) { + // Disable stock recovery reflashing + TWFunc::Disable_Stock_Recovery_Replace(); + usleep(2000000); // Sleep for 2 seconds before rebooting + TWFunc::tw_reboot(rb_system); + usleep(5000000); // Sleep for 5 seconds to allow reboot to occur + } else { + DataManager::SetValue("tw_page_done", 1); + } + operation_end(op_status); + } + return 0; +} + +int GUIAction::installsu(std::string arg) +{ + int op_status = 0; + + operation_start("Install SuperSU"); + if (simulate) { + simulate_progress_bar(); + } else { + if (!TWFunc::Install_SuperSU()) + op_status = 1; + } + + operation_end(op_status); + return 0; +} + +int GUIAction::fixsu(std::string arg) +{ + int op_status = 0; + + operation_start("Fixing Superuser Permissions"); + if (simulate) { + simulate_progress_bar(); + } else { + LOGERR("Fixing su permissions was deprecated from TWRP.\n"); + LOGERR("4.3+ ROMs with SELinux will always lose su perms.\n"); + } + + operation_end(op_status); + return 0; +} + +int GUIAction::decrypt_backup(std::string arg) +{ + int op_status = 0; + + operation_start("Try Restore Decrypt"); + if (simulate) { + simulate_progress_bar(); + } else { + string Restore_Path, Filename, Password; + DataManager::GetValue("tw_restore", Restore_Path); + Restore_Path += "/"; + DataManager::GetValue("tw_restore_password", Password); + TWFunc::SetPerformanceMode(true); + if (TWFunc::Try_Decrypting_Backup(Restore_Path, Password)) + op_status = 0; // success + else + op_status = 1; // fail + TWFunc::SetPerformanceMode(false); + } + + operation_end(op_status); + return 0; +} + +int GUIAction::repair(std::string arg) +{ + int op_status = 0; + + operation_start("Repair Partition"); + if (simulate) { + simulate_progress_bar(); + } else { + string part_path; + DataManager::GetValue("tw_partition_mount_point", part_path); + if (PartitionManager.Repair_By_Path(part_path, true)) { + op_status = 0; // success + } else { + LOGERR("Error repairing file system.\n"); + op_status = 1; // fail + } + } + + operation_end(op_status); + return 0; +} + +int GUIAction::resize(std::string arg) +{ + int op_status = 0; + + operation_start("Resize Partition"); + if (simulate) { + simulate_progress_bar(); + } else { + string part_path; + DataManager::GetValue("tw_partition_mount_point", part_path); + if (PartitionManager.Resize_By_Path(part_path, true)) { + op_status = 0; // success + } else { + LOGERR("Error resizing file system.\n"); + op_status = 1; // fail + } + } + + operation_end(op_status); + return 0; +} + +int GUIAction::changefilesystem(std::string arg) +{ + int op_status = 0; + + operation_start("Change File System"); + if (simulate) { + simulate_progress_bar(); + } else { + string part_path, file_system; + DataManager::GetValue("tw_partition_mount_point", part_path); + DataManager::GetValue("tw_action_new_file_system", file_system); + if (PartitionManager.Wipe_By_Path(part_path, file_system)) { + op_status = 0; // success + } else { + LOGERR("Error changing file system.\n"); + op_status = 1; // fail + } + } + PartitionManager.Update_System_Details(); + operation_end(op_status); + return 0; +} + +int GUIAction::startmtp(std::string arg) +{ + int op_status = 0; + + operation_start("Start MTP"); + if (PartitionManager.Enable_MTP()) + op_status = 0; // success + else + op_status = 1; // fail + + operation_end(op_status); + return 0; +} + +int GUIAction::stopmtp(std::string arg) +{ + int op_status = 0; + + operation_start("Stop MTP"); + if (PartitionManager.Disable_MTP()) + op_status = 0; // success + else + op_status = 1; // fail + + operation_end(op_status); + return 0; +} + +int GUIAction::flashimage(std::string arg) +{ + int op_status = 0; + + operation_start("Flash Image"); + string path, filename, full_filename; + DataManager::GetValue("tw_zip_location", path); + DataManager::GetValue("tw_file", filename); + full_filename = path + "/" + filename; + if (PartitionManager.Flash_Image(full_filename)) + op_status = 0; // success + else + op_status = 1; // fail + + operation_end(op_status); + return 0; +} + +int GUIAction::getKeyByName(std::string key) +{ + if (key == "home") return KEY_HOME; + else if (key == "menu") return KEY_MENU; + else if (key == "back") return KEY_BACK; + else if (key == "search") return KEY_SEARCH; + else if (key == "voldown") return KEY_VOLUMEDOWN; + else if (key == "volup") return KEY_VOLUMEUP; + else if (key == "power") { + int ret_val; + DataManager::GetValue(TW_POWER_BUTTON, ret_val); + if (!ret_val) + return KEY_POWER; + else + return ret_val; + } + + return atol(key.c_str()); +} + +int GUIAction::checkpartitionlifetimewrites(std::string arg) +{ + int op_status = 0; + TWPartition* sys = PartitionManager.Find_Partition_By_Path(arg); + + operation_start("Check Partition Lifetime Writes"); + if (sys) { + if (sys->Check_Lifetime_Writes() != 0) + DataManager::SetValue("tw_lifetime_writes", 1); + else + DataManager::SetValue("tw_lifetime_writes", 0); + op_status = 0; // success + } else { + DataManager::SetValue("tw_lifetime_writes", 1); + op_status = 1; // fail + } + + operation_end(op_status); + return 0; +} + +int GUIAction::mountsystemtoggle(std::string arg) +{ + int op_status = 0; + bool remount_system = PartitionManager.Is_Mounted_By_Path("/system"); + + operation_start("Toggle System Mount"); + if (!PartitionManager.UnMount_By_Path("/system", true)) { + op_status = 1; // fail + } else { + TWPartition* Part = PartitionManager.Find_Partition_By_Path("/system"); + if (Part) { + if (arg == "0") { + DataManager::SetValue("tw_mount_system_ro", 0); + Part->Change_Mount_Read_Only(false); + } else { + DataManager::SetValue("tw_mount_system_ro", 1); + Part->Change_Mount_Read_Only(true); + } + if (remount_system) { + Part->Mount(true); + } + op_status = 0; // success + } else { + op_status = 1; // fail + } + } + + operation_end(op_status); + return 0; +} diff --git a/gui/animation.cpp b/gui/animation.cpp new file mode 100644 index 000000000..888b4ab08 --- /dev/null +++ b/gui/animation.cpp @@ -0,0 +1,129 @@ +// animation.cpp - GUIAnimation object + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" + + +GUIAnimation::GUIAnimation(xml_node<>* node) : GUIObject(node) +{ + xml_node<>* child; + + mAnimation = NULL; + mFrame = 1; + mFPS = 1; + mLoop = -1; + mRender = 1; + mUpdateCount = 0; + + if (!node) return; + + mAnimation = LoadAttrAnimation(FindNode(node, "resource"), "name"); + + // Load the placement + LoadPlacement(FindNode(node, "placement"), &mRenderX, &mRenderY, NULL, NULL, &mPlacement); + + child = FindNode(node, "speed"); + if (child) + { + mFPS = LoadAttrInt(child, "fps", mFPS); + mRender = LoadAttrInt(child, "render", mRender); + } + if (mFPS > 30) mFPS = 30; + + child = FindNode(node, "loop"); + if (child) + { + xml_attribute<>* attr = child->first_attribute("frame"); + if (attr) + mLoop = atoi(attr->value()) - 1; + mFrame = LoadAttrInt(child, "start", mFrame); + } + + // Fetch the render sizes + if (mAnimation && mAnimation->GetResource()) + { + mRenderW = mAnimation->GetWidth(); + mRenderH = mAnimation->GetHeight(); + + // Adjust for placement + if (mPlacement != TOP_LEFT && mPlacement != BOTTOM_LEFT) + { + if (mPlacement == CENTER) + mRenderX -= (mRenderW / 2); + else + mRenderX -= mRenderW; + } + if (mPlacement != TOP_LEFT && mPlacement != TOP_RIGHT) + { + if (mPlacement == CENTER) + mRenderY -= (mRenderH / 2); + else + mRenderY -= mRenderH; + } + SetPlacement(TOP_LEFT); + } +} + +int GUIAnimation::Render(void) +{ + if(!isConditionTrue()) + return 0; + + if (!mAnimation || !mAnimation->GetResource(mFrame)) return -1; + + gr_blit(mAnimation->GetResource(mFrame), 0, 0, mRenderW, mRenderH, mRenderX, mRenderY); + return 0; +} + +int GUIAnimation::Update(void) +{ + if(!isConditionTrue()) + return 0; + + if (!mAnimation) return -1; + + // Handle the "end-of-animation" state + if (mLoop == -2) return 0; + + // Determine if we need the next frame yet... + if (++mUpdateCount > 30 / mFPS) + { + mUpdateCount = 0; + if (++mFrame >= mAnimation->GetResourceCount()) + { + if (mLoop < 0) + { + mFrame = mAnimation->GetResourceCount() - 1; + mLoop = -2; + } + else + mFrame = mLoop; + } + if (mRender == 2) return 2; + return (Render() == 0 ? 1 : -1); + } + return 0; +} + diff --git a/gui/blanktimer.cpp b/gui/blanktimer.cpp new file mode 100644 index 000000000..95b6c47ff --- /dev/null +++ b/gui/blanktimer.cpp @@ -0,0 +1,123 @@ +/* + Copyright 2012 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see <http://www.gnu.org/licenses/>. +*/ + +using namespace std; +#include <string> +#include <pthread.h> +#include <sys/time.h> +#include <time.h> +#include <unistd.h> +#include "pages.hpp" +#include "blanktimer.hpp" +#include "../data.hpp" +extern "C" { +#include "../minuitwrp/minui.h" +#include "../twcommon.h" +} +#include "../twrp-functions.hpp" +#include "../variables.h" + +blanktimer::blanktimer(void) { + pthread_mutex_init(&mutex, NULL); + setTime(0); // no timeout + state = kOn; + orig_brightness = getBrightness(); +} + +bool blanktimer::isScreenOff() { + return state >= kOff; +} + +void blanktimer::setTime(int newtime) { + pthread_mutex_lock(&mutex); + sleepTimer = newtime; + pthread_mutex_unlock(&mutex); +} + +void blanktimer::setTimer(void) { + clock_gettime(CLOCK_MONOTONIC, &btimer); +} + +void blanktimer::checkForTimeout() { +#ifndef TW_NO_SCREEN_TIMEOUT + pthread_mutex_lock(&mutex); + timespec curTime, diff; + clock_gettime(CLOCK_MONOTONIC, &curTime); + diff = TWFunc::timespec_diff(btimer, curTime); + if (sleepTimer > 2 && diff.tv_sec > (sleepTimer - 2) && state == kOn) { + orig_brightness = getBrightness(); + state = kDim; + TWFunc::Set_Brightness("5"); + } + if (sleepTimer && diff.tv_sec > sleepTimer && state < kOff) { + state = kOff; + TWFunc::Set_Brightness("0"); + TWFunc::check_and_run_script("/sbin/postscreenblank.sh", "blank"); + PageManager::ChangeOverlay("lock"); + } +#ifndef TW_NO_SCREEN_BLANK + if (state == kOff && gr_fb_blank(1) >= 0) { + state = kBlanked; + } +#endif + pthread_mutex_unlock(&mutex); +#endif +} + +string blanktimer::getBrightness(void) { + string result; + string brightness_path; + DataManager::GetValue("tw_brightness_file", brightness_path); + if (brightness_path == "/nobrightness") + return brightness_path; + DataManager::GetValue("tw_brightness", result); + if (result == "") { + result = "255"; + } + return result; + +} + +void blanktimer::resetTimerAndUnblank(void) { +#ifndef TW_NO_SCREEN_TIMEOUT + pthread_mutex_lock(&mutex); + setTimer(); + switch (state) { + case kBlanked: +#ifndef TW_NO_SCREEN_BLANK + if (gr_fb_blank(0) < 0) { + LOGINFO("blanktimer::resetTimerAndUnblank failed to gr_fb_blank(0)\n"); + break; + } +#endif + // TODO: this is asymmetric with postscreenblank.sh - shouldn't it be under the next case label? + TWFunc::check_and_run_script("/sbin/postscreenunblank.sh", "unblank"); + // No break here, we want to keep going + case kOff: + gui_forceRender(); + // No break here, we want to keep going + case kDim: + if (orig_brightness != "/nobrightness") + TWFunc::Set_Brightness(orig_brightness); + state = kOn; + case kOn: + break; + } + pthread_mutex_unlock(&mutex); +#endif +} diff --git a/gui/blanktimer.hpp b/gui/blanktimer.hpp new file mode 100644 index 000000000..5e617901f --- /dev/null +++ b/gui/blanktimer.hpp @@ -0,0 +1,56 @@ +/* + Copyright 2012 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __BLANKTIMER_HEADER_HPP +#define __BLANKTIMER_HEADER_HPP + +#include <sys/time.h> + +using namespace std; + +class blanktimer +{ +public: + blanktimer(); + + // set timeout in seconds + void setTime(int newtime); + + // call this in regular intervals + void checkForTimeout(); + + // call this when an input event is received or when an operation is finished + void resetTimerAndUnblank(); + + bool isScreenOff(); + +private: + void setTimer(void); + string getBrightness(void); + + pthread_mutex_t mutex; + enum State { kOn = 0, kDim = 1, kOff = 2, kBlanked = 3 }; + State state; + timespec btimer; + long sleepTimer; + string orig_brightness; +}; + +extern blanktimer blankTimer; + +#endif // __BLANKTIMER_HEADER_HPP diff --git a/gui/button.cpp b/gui/button.cpp new file mode 100644 index 000000000..18b5560c4 --- /dev/null +++ b/gui/button.cpp @@ -0,0 +1,261 @@ +/* + Copyright 2012 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> +#include "../data.hpp" + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" + +GUIButton::GUIButton(xml_node<>* node) + : GUIObject(node) +{ + xml_attribute<>* attr; + xml_node<>* child; + + mButtonImg = NULL; + mButtonIcon = NULL; + mButtonLabel = NULL; + mAction = NULL; + mRendered = false; + hasHighlightColor = false; + renderHighlight = false; + hasFill = false; + + if (!node) return; + + // These can be loaded directly from the node + mButtonLabel = new GUIText(node); + mAction = new GUIAction(node); + + mButtonImg = new GUIImage(node); + if (mButtonImg->Render() < 0) + { + delete mButtonImg; + mButtonImg = NULL; + } + if (mButtonLabel->Render() < 0) + { + delete mButtonLabel; + mButtonLabel = NULL; + } + // Load fill if it exists + mFillColor = LoadAttrColor(FindNode(node, "fill"), "color", &hasFill); + if (!hasFill && mButtonImg == NULL) { + LOGERR("No image resource or fill specified for button.\n"); + } + + // The icon is a special case + mButtonIcon = LoadAttrImage(FindNode(node, "icon"), "resource"); + + mHighlightColor = LoadAttrColor(FindNode(node, "highlight"), "color", &hasHighlightColor); + + int x, y, w, h; + TextPlacement = TOP_LEFT; + if (mButtonImg) { + mButtonImg->GetRenderPos(x, y, w, h); + } else if (hasFill) { + LoadPlacement(FindNode(node, "placement"), &x, &y, &w, &h, &TextPlacement); + } + SetRenderPos(x, y, w, h); +} + +GUIButton::~GUIButton() +{ + delete mButtonImg; + delete mButtonLabel; + delete mAction; +} + +int GUIButton::Render(void) +{ + if (!isConditionTrue()) + { + mRendered = false; + return 0; + } + + int ret = 0; + + if (mButtonImg) ret = mButtonImg->Render(); + if (ret < 0) return ret; + if (hasFill) { + gr_color(mFillColor.red, mFillColor.green, mFillColor.blue, mFillColor.alpha); + gr_fill(mRenderX, mRenderY, mRenderW, mRenderH); + } + if (mButtonIcon && mButtonIcon->GetResource()) + gr_blit(mButtonIcon->GetResource(), 0, 0, mIconW, mIconH, mIconX, mIconY); + if (mButtonLabel) { + int w, h; + mButtonLabel->GetCurrentBounds(w, h); + if (w != mTextW) { + mTextW = w; + if (TextPlacement == CENTER_X_ONLY) { + mTextX = ((mRenderW - mRenderX) / 2); + } else if (mTextW > mRenderW) { // As a special case, we'll allow large text which automatically moves it to the right. + mTextX = mRenderW + mRenderX + 5; + mRenderW += mTextW + 5; + } else { + mTextX = mRenderX + ((mRenderW - mTextW) / 2); + } + mButtonLabel->SetRenderPos(mTextX, mTextY); + } + ret = mButtonLabel->Render(); + if (ret < 0) return ret; + } + if (renderHighlight && hasHighlightColor) { + gr_color(mHighlightColor.red, mHighlightColor.green, mHighlightColor.blue, mHighlightColor.alpha); + gr_fill(mRenderX, mRenderY, mRenderW, mRenderH); + } + mRendered = true; + return ret; +} + +int GUIButton::Update(void) +{ + if (!isConditionTrue()) return (mRendered ? 2 : 0); + if (!mRendered) return 2; + + int ret = 0, ret2 = 0; + + if (mButtonImg) ret = mButtonImg->Update(); + if (ret < 0) return ret; + + if (ret == 0) + { + if (mButtonLabel) { + ret2 = mButtonLabel->Update(); + if (ret2 < 0) return ret2; + if (ret2 > ret) ret = ret2; + } + } + else if (ret == 1) + { + // The button re-rendered, so everyone else is a render + if (mButtonIcon && mButtonIcon->GetResource()) + gr_blit(mButtonIcon->GetResource(), 0, 0, mIconW, mIconH, mIconX, mIconY); + if (mButtonLabel) ret = mButtonLabel->Render(); + if (ret < 0) return ret; + ret = 1; + } + else + { + // Aparently, the button needs a background update + ret = 2; + } + return ret; +} + +int GUIButton::SetRenderPos(int x, int y, int w, int h) +{ + mRenderX = x; + mRenderY = y; + if (w || h) + { + mRenderW = w; + mRenderH = h; + } + + mIconW = mButtonIcon->GetWidth(); + mIconH = mButtonIcon->GetHeight(); + + mTextH = 0; + mTextW = 0; + mIconX = mRenderX + ((mRenderW - mIconW) / 2); + if (mButtonLabel) mButtonLabel->GetCurrentBounds(mTextW, mTextH); + if (mTextW) + { + if (TextPlacement == CENTER_X_ONLY) { + mTextX = ((mRenderW - mRenderX) / 2); + } else if (mTextW > mRenderW) { // As a special case, we'll allow large text which automatically moves it to the right. + mTextX = mRenderW + mRenderX + 5; + mRenderW += mTextW + 5; + } else { + mTextX = mRenderX + ((mRenderW - mTextW) / 2); + } + } + + if (mIconH == 0 || mTextH == 0 || mIconH + mTextH > mRenderH) + { + mIconY = mRenderY + (mRenderH / 2) - (mIconH / 2); + mTextY = mRenderY + (mRenderH / 2) - (mTextH / 2); + } + else + { + int divisor = mRenderH - (mIconH + mTextH); + mIconY = mRenderY + (divisor / 3); + mTextY = mRenderY + (divisor * 2 / 3) + mIconH; + } + + if (mButtonLabel) mButtonLabel->SetRenderPos(mTextX, mTextY); + if (mAction) mAction->SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH); + SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH); + return 0; +} + +int GUIButton::NotifyTouch(TOUCH_STATE state, int x, int y) +{ + static int last_state = 0; + + if (!isConditionTrue()) return -1; + if (x < mRenderX || x - mRenderX > mRenderW || y < mRenderY || y - mRenderY > mRenderH || state == TOUCH_RELEASE) { + if (last_state == 1) { + last_state = 0; + if (mButtonLabel != NULL) + mButtonLabel->isHighlighted = false; + if (mButtonImg != NULL) + mButtonImg->isHighlighted = false; + renderHighlight = false; + mRendered = false; + } + } else { + if (last_state == 0) { + last_state = 1; + DataManager::Vibrate("tw_button_vibrate"); + if (mButtonLabel != NULL) + mButtonLabel->isHighlighted = true; + if (mButtonImg != NULL) + mButtonImg->isHighlighted = true; + renderHighlight = true; + mRendered = false; + } + } + if (x < mRenderX || x - mRenderX > mRenderW || y < mRenderY || y - mRenderY > mRenderH) + return 0; + return (mAction ? mAction->NotifyTouch(state, x, y) : 1); +} diff --git a/gui/checkbox.cpp b/gui/checkbox.cpp new file mode 100644 index 000000000..46a770861 --- /dev/null +++ b/gui/checkbox.cpp @@ -0,0 +1,165 @@ +// checkbox.cpp - GUICheckbox object + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" + +GUICheckbox::GUICheckbox(xml_node<>* node) + : GUIObject(node) +{ + xml_attribute<>* attr; + xml_node<>* child; + + mChecked = NULL; + mUnchecked = NULL; + mLabel = NULL; + mRendered = false; + + mLastState = 0; + + if (!node) + return; + + // The label can be loaded directly + mLabel = new GUIText(node); + + // Read the check states + child = FindNode(node, "image"); + if (child) + { + mChecked = LoadAttrImage(child, "checked"); + mUnchecked = LoadAttrImage(child, "unchecked"); + } + + // Get the variable data + child = FindNode(node, "data"); + if (child) + { + attr = child->first_attribute("variable"); + if (attr) + mVarName = attr->value(); + attr = child->first_attribute("default"); + if (attr) + DataManager::SetValue(mVarName, attr->value()); + } + + mCheckW = mChecked->GetWidth(); + mCheckH = mChecked->GetHeight(); + if (mCheckW == 0) + { + mCheckW = mUnchecked->GetWidth(); + mCheckH = mUnchecked->GetHeight(); + } + + int x, y, w, h; + mLabel->GetRenderPos(x, y, w, h); + SetRenderPos(x, y, 0, 0); +} + +GUICheckbox::~GUICheckbox() +{ +} + +int GUICheckbox::Render(void) +{ + if (!isConditionTrue()) + { + mRendered = false; + return 0; + } + + int ret = 0; + int lastState = 0; + DataManager::GetValue(mVarName, lastState); + + if (lastState) + { + if (mChecked && mChecked->GetResource()) + gr_blit(mChecked->GetResource(), 0, 0, mCheckW, mCheckH, mRenderX, mRenderY); + } + else + { + if (mUnchecked && mUnchecked->GetResource()) + gr_blit(mUnchecked->GetResource(), 0, 0, mCheckW, mCheckH, mRenderX, mRenderY); + } + if (mLabel) + ret = mLabel->Render(); + mLastState = lastState; + mRendered = true; + return ret; +} + +int GUICheckbox::Update(void) +{ + if (!isConditionTrue()) return (mRendered ? 2 : 0); + if (!mRendered) return 2; + + int lastState = 0; + DataManager::GetValue(mVarName, lastState); + + if (lastState != mLastState) + return 2; + return 0; +} + +int GUICheckbox::SetRenderPos(int x, int y, int w, int h) +{ + mRenderX = x; + mRenderY = y; + + if (w || h) + return -1; + + int textW, textH; + mLabel->GetCurrentBounds(textW, textH); + + w = textW + mCheckW + 5; + mRenderW = w; + mRenderH = mCheckH; + + mTextX = mRenderX + mCheckW + 5; + mTextY = mRenderY + ((mCheckH / 2) - (textH / 2)); + + mLabel->SetRenderPos(mTextX, mTextY, 0, 0); + SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH); + return 0; +} + +int GUICheckbox::NotifyTouch(TOUCH_STATE state, int x, int y) +{ + if (!isConditionTrue()) + return -1; + + if (state == TOUCH_RELEASE) + { + int lastState; + DataManager::GetValue(mVarName, lastState); + lastState = (lastState == 0) ? 1 : 0; + DataManager::SetValue(mVarName, lastState); + + DataManager::Vibrate("tw_button_vibrate"); + } + return 0; +} + diff --git a/gui/console.cpp b/gui/console.cpp new file mode 100644 index 000000000..1544d77a1 --- /dev/null +++ b/gui/console.cpp @@ -0,0 +1,328 @@ +// console.cpp - GUIConsole object + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" + + +static std::vector<std::string> gConsole; +static std::vector<std::string> gConsoleColor; +static FILE* ors_file; + +extern "C" void __gui_print(const char *color, char *buf) +{ + char *start, *next; + + if (buf[0] == '\n' && strlen(buf) < 2) { + // This prevents the double lines bug seen in the console during zip installs + return; + } + + for (start = next = buf; *next != '\0';) + { + if (*next == '\n') + { + *next = '\0'; + gConsole.push_back(start); + gConsoleColor.push_back(color); + + start = ++next; + } + else + ++next; + } + + // The text after last \n (or whole string if there is no \n) + if(*start) { + gConsole.push_back(start); + gConsoleColor.push_back(color); + } + if (ors_file) { + fprintf(ors_file, "%s\n", buf); + fflush(ors_file); + } +} + +extern "C" void gui_print(const char *fmt, ...) +{ + char buf[512]; // We're going to limit a single request to 512 bytes + + va_list ap; + va_start(ap, fmt); + vsnprintf(buf, 512, fmt, ap); + va_end(ap); + + fputs(buf, stdout); + + __gui_print("normal", buf); + return; +} + +extern "C" void gui_print_color(const char *color, const char *fmt, ...) +{ + char buf[512]; // We're going to limit a single request to 512 bytes + + va_list ap; + va_start(ap, fmt); + vsnprintf(buf, 512, fmt, ap); + va_end(ap); + + fputs(buf, stdout); + + __gui_print(color, buf); + return; +} + +extern "C" void gui_set_FILE(FILE* f) +{ + ors_file = f; +} + +GUIConsole::GUIConsole(xml_node<>* node) : GUIScrollList(node) +{ + xml_node<>* child; + + mLastCount = 0; + scrollToEnd = true; + mSlideoutX = mSlideoutY = mSlideoutW = mSlideoutH = 0; + mSlideout = 0; + mSlideoutState = visible; + + allowSelection = false; // console doesn't support list item selections + + if (!node) + { + mRenderX = 0; mRenderY = 0; mRenderW = gr_fb_width(); mRenderH = gr_fb_height(); + } + else + { + child = FindNode(node, "color"); + if (child) + { + mFontColor = LoadAttrColor(child, "foreground", mFontColor); + mBackgroundColor = LoadAttrColor(child, "background", mBackgroundColor); + //mScrollColor = LoadAttrColor(child, "scroll", mScrollColor); + } + + child = FindNode(node, "slideout"); + if (child) + { + mSlideout = 1; + mSlideoutState = hidden; + LoadPlacement(child, &mSlideoutX, &mSlideoutY, &mSlideoutW, &mSlideoutH, &mPlacement); + + mSlideoutImage = LoadAttrImage(child, "resource"); + + if (mSlideoutImage && mSlideoutImage->GetResource()) + { + mSlideoutW = mSlideoutImage->GetWidth(); + mSlideoutH = mSlideoutImage->GetHeight(); + if (mPlacement == CENTER || mPlacement == CENTER_X_ONLY) { + mSlideoutX = mSlideoutX - (mSlideoutW / 2); + if (mPlacement == CENTER) { + mSlideoutY = mSlideoutY - (mSlideoutH / 2); + } + } + } + } + } +} + +int GUIConsole::RenderSlideout(void) +{ + if (!mSlideoutImage || !mSlideoutImage->GetResource()) + return -1; + + gr_blit(mSlideoutImage->GetResource(), 0, 0, mSlideoutW, mSlideoutH, mSlideoutX, mSlideoutY); + return 0; +} + +bool GUIConsole::AddLines() +{ + if (mLastCount == gConsole.size()) + return false; // nothing to add + + size_t prevCount = mLastCount; + mLastCount = gConsole.size(); + + // Due to word wrap, figure out what / how the newly added text needs to be added to the render vector that is word wrapped + // Note, that multiple consoles on different GUI pages may be different widths or use different fonts, so the word wrapping + // may different in different console windows + for (size_t i = prevCount; i < mLastCount; i++) { + string curr_line = gConsole[i]; + string curr_color = gConsoleColor[i]; + for(;;) { + size_t line_char_width = gr_maxExW(curr_line.c_str(), mFont->GetResource(), mRenderW); + if (line_char_width < curr_line.size()) { + rConsole.push_back(curr_line.substr(0, line_char_width)); + rConsoleColor.push_back(curr_color); + curr_line = curr_line.substr(line_char_width); + } else { + rConsole.push_back(curr_line); + rConsoleColor.push_back(curr_color); + break; + } + } + } + return true; +} + +int GUIConsole::RenderConsole(void) +{ + AddLines(); + GUIScrollList::Render(); + + // if last line is fully visible, keep tracking the last line when new lines are added + int bottom_offset = GetDisplayRemainder() - actualItemHeight; + bool isAtBottom = firstDisplayedItem == GetItemCount() - GetDisplayItemCount() - (bottom_offset != 0) && y_offset == bottom_offset; + if (isAtBottom) + scrollToEnd = true; +#if 0 + // debug - show if we are tracking the last line + if (scrollToEnd) { + gr_color(0,255,0,255); + gr_fill(mRenderX+mRenderW-5, mRenderY+mRenderH-5, 5, 5); + } else { + gr_color(255,0,0,255); + gr_fill(mRenderX+mRenderW-5, mRenderY+mRenderH-5, 5, 5); + } +#endif + return (mSlideout ? RenderSlideout() : 0); +} + +int GUIConsole::Render(void) +{ + if(!isConditionTrue()) + return 0; + + if (mSlideout && mSlideoutState == hidden) + return RenderSlideout(); + + return RenderConsole(); +} + +int GUIConsole::Update(void) +{ + if (mSlideout && mSlideoutState != visible) + { + if (mSlideoutState == hidden) + return 0; + + if (mSlideoutState == request_hide) + mSlideoutState = hidden; + + if (mSlideoutState == request_show) + mSlideoutState = visible; + + // Any time we activate the console, we reset the position + SetVisibleListLocation(rConsole.size() - 1); + mUpdate = 1; + scrollToEnd = true; + } + + if (AddLines()) { + // someone added new text + // at least the scrollbar must be updated, even if the new lines are currently not visible + mUpdate = 1; + } + + if (scrollToEnd) { + // keep the last line in view + SetVisibleListLocation(rConsole.size() - 1); + } + + GUIScrollList::Update(); + + if (mUpdate) { + mUpdate = 0; + if (Render() == 0) + return 2; + } + return 0; +} + +// IsInRegion - Checks if the request is handled by this object +// Return 1 if this object handles the request, 0 if not +int GUIConsole::IsInRegion(int x, int y) +{ + if (mSlideout) { + // Check if they tapped the slideout button + if (x >= mSlideoutX && x < mSlideoutX + mSlideoutW && y >= mSlideoutY && y < mSlideoutY + mSlideoutH) + return 1; + + // If we're only rendering the slideout, bail now + if (mSlideoutState == hidden) + return 0; + } + + return GUIScrollList::IsInRegion(x, y); +} + +// NotifyTouch - Notify of a touch event +// Return 0 on success, >0 to ignore remainder of touch, and <0 on error +int GUIConsole::NotifyTouch(TOUCH_STATE state, int x, int y) +{ + if(!isConditionTrue()) + return -1; + + if (mSlideout && x >= mSlideoutX && x < mSlideoutX + mSlideoutW && y >= mSlideoutY && y < mSlideoutY + mSlideoutH) { + if (state == TOUCH_START) { + if (mSlideoutState == hidden) + mSlideoutState = request_show; + else if (mSlideoutState == visible) + mSlideoutState = request_hide; + } + return 1; + } + scrollToEnd = false; + return GUIScrollList::NotifyTouch(state, x, y); +} + +size_t GUIConsole::GetItemCount() +{ + return rConsole.size(); +} + +void GUIConsole::RenderItem(size_t itemindex, int yPos, bool selected) +{ + // Set the color for the font + if (rConsoleColor[itemindex] == "normal") { + gr_color(mFontColor.red, mFontColor.green, mFontColor.blue, mFontColor.alpha); + } else { + COLOR FontColor; + std::string color = rConsoleColor[itemindex]; + ConvertStrToColor(color, &FontColor); + FontColor.alpha = 255; + gr_color(FontColor.red, FontColor.green, FontColor.blue, FontColor.alpha); + } + + // render text + const char* text = rConsole[itemindex].c_str(); + gr_textEx(mRenderX, yPos, text, mFont->GetResource()); +} + +void GUIConsole::NotifySelect(size_t item_selected) +{ + // do nothing - console ignores selections +} diff --git a/gui/devices/1080x1920/res/fonts/Roboto-Condensed-40.dat b/gui/devices/1080x1920/res/fonts/Roboto-Condensed-40.dat Binary files differnew file mode 100644 index 000000000..ff23add82 --- /dev/null +++ b/gui/devices/1080x1920/res/fonts/Roboto-Condensed-40.dat diff --git a/gui/devices/1080x1920/res/images/back-icon.png b/gui/devices/1080x1920/res/images/back-icon.png Binary files differnew file mode 100644 index 000000000..85c6a5d68 --- /dev/null +++ b/gui/devices/1080x1920/res/images/back-icon.png diff --git a/gui/devices/1080x1920/res/images/checkbox_checked.png b/gui/devices/1080x1920/res/images/checkbox_checked.png Binary files differnew file mode 100644 index 000000000..65d0b34da --- /dev/null +++ b/gui/devices/1080x1920/res/images/checkbox_checked.png diff --git a/gui/devices/1080x1920/res/images/checkbox_empty.png b/gui/devices/1080x1920/res/images/checkbox_empty.png Binary files differnew file mode 100644 index 000000000..89b4c9627 --- /dev/null +++ b/gui/devices/1080x1920/res/images/checkbox_empty.png diff --git a/gui/devices/1080x1920/res/images/cursor.png b/gui/devices/1080x1920/res/images/cursor.png Binary files differnew file mode 100644 index 000000000..32c8ae1ca --- /dev/null +++ b/gui/devices/1080x1920/res/images/cursor.png diff --git a/gui/devices/1080x1920/res/images/curtain.jpg b/gui/devices/1080x1920/res/images/curtain.jpg Binary files differnew file mode 100644 index 000000000..269941d5e --- /dev/null +++ b/gui/devices/1080x1920/res/images/curtain.jpg diff --git a/gui/devices/1080x1920/res/images/file.png b/gui/devices/1080x1920/res/images/file.png Binary files differnew file mode 100644 index 000000000..a69b61996 --- /dev/null +++ b/gui/devices/1080x1920/res/images/file.png diff --git a/gui/devices/1080x1920/res/images/folder.png b/gui/devices/1080x1920/res/images/folder.png Binary files differnew file mode 100644 index 000000000..fbea7a970 --- /dev/null +++ b/gui/devices/1080x1920/res/images/folder.png diff --git a/gui/devices/1080x1920/res/images/home-icon.png b/gui/devices/1080x1920/res/images/home-icon.png Binary files differnew file mode 100644 index 000000000..d6bc73d82 --- /dev/null +++ b/gui/devices/1080x1920/res/images/home-icon.png diff --git a/gui/devices/1080x1920/res/images/indeterminate001.png b/gui/devices/1080x1920/res/images/indeterminate001.png Binary files differnew file mode 100644 index 000000000..a205e91aa --- /dev/null +++ b/gui/devices/1080x1920/res/images/indeterminate001.png diff --git a/gui/devices/1080x1920/res/images/indeterminate002.png b/gui/devices/1080x1920/res/images/indeterminate002.png Binary files differnew file mode 100644 index 000000000..f777408be --- /dev/null +++ b/gui/devices/1080x1920/res/images/indeterminate002.png diff --git a/gui/devices/1080x1920/res/images/indeterminate003.png b/gui/devices/1080x1920/res/images/indeterminate003.png Binary files differnew file mode 100644 index 000000000..cbb597482 --- /dev/null +++ b/gui/devices/1080x1920/res/images/indeterminate003.png diff --git a/gui/devices/1080x1920/res/images/indeterminate004.png b/gui/devices/1080x1920/res/images/indeterminate004.png Binary files differnew file mode 100644 index 000000000..5ff77341d --- /dev/null +++ b/gui/devices/1080x1920/res/images/indeterminate004.png diff --git a/gui/devices/1080x1920/res/images/indeterminate005.png b/gui/devices/1080x1920/res/images/indeterminate005.png Binary files differnew file mode 100644 index 000000000..7cc9abb4f --- /dev/null +++ b/gui/devices/1080x1920/res/images/indeterminate005.png diff --git a/gui/devices/1080x1920/res/images/indeterminate006.png b/gui/devices/1080x1920/res/images/indeterminate006.png Binary files differnew file mode 100644 index 000000000..9eed17600 --- /dev/null +++ b/gui/devices/1080x1920/res/images/indeterminate006.png diff --git a/gui/devices/1080x1920/res/images/keyboard1.png b/gui/devices/1080x1920/res/images/keyboard1.png Binary files differnew file mode 100644 index 000000000..79a8b69cb --- /dev/null +++ b/gui/devices/1080x1920/res/images/keyboard1.png diff --git a/gui/devices/1080x1920/res/images/keyboard2.png b/gui/devices/1080x1920/res/images/keyboard2.png Binary files differnew file mode 100644 index 000000000..63a5b6a19 --- /dev/null +++ b/gui/devices/1080x1920/res/images/keyboard2.png diff --git a/gui/devices/1080x1920/res/images/keyboard3.png b/gui/devices/1080x1920/res/images/keyboard3.png Binary files differnew file mode 100644 index 000000000..a646c7557 --- /dev/null +++ b/gui/devices/1080x1920/res/images/keyboard3.png diff --git a/gui/devices/1080x1920/res/images/keyboard4.png b/gui/devices/1080x1920/res/images/keyboard4.png Binary files differnew file mode 100644 index 000000000..3b2905adb --- /dev/null +++ b/gui/devices/1080x1920/res/images/keyboard4.png diff --git a/gui/devices/1080x1920/res/images/medium-button.png b/gui/devices/1080x1920/res/images/medium-button.png Binary files differnew file mode 100644 index 000000000..a3bf30d58 --- /dev/null +++ b/gui/devices/1080x1920/res/images/medium-button.png diff --git a/gui/devices/1080x1920/res/images/menu-button.png b/gui/devices/1080x1920/res/images/menu-button.png Binary files differnew file mode 100644 index 000000000..36d3f0127 --- /dev/null +++ b/gui/devices/1080x1920/res/images/menu-button.png diff --git a/gui/devices/1080x1920/res/images/minus-button.png b/gui/devices/1080x1920/res/images/minus-button.png Binary files differnew file mode 100644 index 000000000..e2edbe45f --- /dev/null +++ b/gui/devices/1080x1920/res/images/minus-button.png diff --git a/gui/devices/1080x1920/res/images/plus-button.png b/gui/devices/1080x1920/res/images/plus-button.png Binary files differnew file mode 100644 index 000000000..b67d9b928 --- /dev/null +++ b/gui/devices/1080x1920/res/images/plus-button.png diff --git a/gui/devices/1080x1920/res/images/progress_empty.png b/gui/devices/1080x1920/res/images/progress_empty.png Binary files differnew file mode 100644 index 000000000..d4ea0c2fe --- /dev/null +++ b/gui/devices/1080x1920/res/images/progress_empty.png diff --git a/gui/devices/1080x1920/res/images/progress_fill.png b/gui/devices/1080x1920/res/images/progress_fill.png Binary files differnew file mode 100644 index 000000000..836e437ae --- /dev/null +++ b/gui/devices/1080x1920/res/images/progress_fill.png diff --git a/gui/devices/1080x1920/res/images/radio_empty.png b/gui/devices/1080x1920/res/images/radio_empty.png Binary files differnew file mode 100644 index 000000000..9c2c66bb0 --- /dev/null +++ b/gui/devices/1080x1920/res/images/radio_empty.png diff --git a/gui/devices/1080x1920/res/images/radio_selected.png b/gui/devices/1080x1920/res/images/radio_selected.png Binary files differnew file mode 100644 index 000000000..8d05b9d48 --- /dev/null +++ b/gui/devices/1080x1920/res/images/radio_selected.png diff --git a/gui/devices/1080x1920/res/images/slideout.png b/gui/devices/1080x1920/res/images/slideout.png Binary files differnew file mode 100644 index 000000000..56a9ac2aa --- /dev/null +++ b/gui/devices/1080x1920/res/images/slideout.png diff --git a/gui/devices/1080x1920/res/images/slider-touch.png b/gui/devices/1080x1920/res/images/slider-touch.png Binary files differnew file mode 100644 index 000000000..b3365afee --- /dev/null +++ b/gui/devices/1080x1920/res/images/slider-touch.png diff --git a/gui/devices/1080x1920/res/images/slider-used.png b/gui/devices/1080x1920/res/images/slider-used.png Binary files differnew file mode 100644 index 000000000..229d9109e --- /dev/null +++ b/gui/devices/1080x1920/res/images/slider-used.png diff --git a/gui/devices/1080x1920/res/images/slider.png b/gui/devices/1080x1920/res/images/slider.png Binary files differnew file mode 100644 index 000000000..1e034a621 --- /dev/null +++ b/gui/devices/1080x1920/res/images/slider.png diff --git a/gui/devices/1080x1920/res/images/sort-button.png b/gui/devices/1080x1920/res/images/sort-button.png Binary files differnew file mode 100644 index 000000000..c6783a15c --- /dev/null +++ b/gui/devices/1080x1920/res/images/sort-button.png diff --git a/gui/devices/1080x1920/res/images/twrplogo.png b/gui/devices/1080x1920/res/images/twrplogo.png Binary files differnew file mode 100644 index 000000000..16b1b2a1c --- /dev/null +++ b/gui/devices/1080x1920/res/images/twrplogo.png diff --git a/gui/devices/1080x1920/res/images/unlock.png b/gui/devices/1080x1920/res/images/unlock.png Binary files differnew file mode 100644 index 000000000..dc3894b76 --- /dev/null +++ b/gui/devices/1080x1920/res/images/unlock.png diff --git a/gui/devices/1080x1920/res/ui.xml b/gui/devices/1080x1920/res/ui.xml new file mode 100644 index 000000000..a611d0582 --- /dev/null +++ b/gui/devices/1080x1920/res/ui.xml @@ -0,0 +1,443 @@ +<?xml version="1.0"?> + +<recovery> + <details> + <resolution width="1080" height="1920" /> + <author>TeamWin</author> + <title>Backup Naowz</title> + <description>Default basic theme</description> + <preview>preview.jpg</preview> + </details> + + <include> + <xmlfile name="portrait.xml" /> + </include> + + <resources> + <resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="40" fallback="Roboto-Condensed-40" /> + <resource name="mediumfont" type="font" filename="RobotoCondensed-Regular.ttf" size="40" fallback="Roboto-Condensed-40" /> + <resource name="filelist" type="font" filename="RobotoCondensed-Regular.ttf" size="40" fallback="Roboto-Condensed-40" /> + <resource name="fixed" type="font" filename="DroidSansMono.ttf" size="30" /> + <resource name="twrplogo" type="image" filename="twrplogo" retainaspect="1" /> + <resource name="main_button" type="image" filename="menu-button" /> + <resource name="file_icon" type="image" filename="file" retainaspect="1" /> + <resource name="folder_icon" type="image" filename="folder" retainaspect="1" /> + <resource name="slideout" type="image" filename="slideout" retainaspect="1" /> + <resource name="progress" type="animation" filename="indeterminate" /> + <resource name="progress_empty" type="image" filename="progress_empty" /> + <resource name="progress_full" type="image" filename="progress_fill" /> + <resource name="checkbox_false" type="image" filename="checkbox_empty" retainaspect="1" /> + <resource name="checkbox_true" type="image" filename="checkbox_checked" retainaspect="1" /> + <resource name="radio_false" type="image" filename="radio_empty" retainaspect="1" /> + <resource name="radio_true" type="image" filename="radio_selected" retainaspect="1" /> + <resource name="medium_button" type="image" filename="medium-button" /> + <resource name="sort_button" type="image" filename="sort-button" /> + <resource name="minus_button" type="image" filename="minus-button" /> + <resource name="plus_button" type="image" filename="plus-button" /> + <resource name="home_icon" type="image" filename="home-icon" retainaspect="1" /> + <resource name="back_icon" type="image" filename="back-icon" retainaspect="1" /> + <resource name="slider" type="image" filename="slider" retainaspect="1" /> + <resource name="slider-used" type="image" filename="slider-used" retainaspect="1" /> + <resource name="slider-touch" type="image" filename="slider-touch" retainaspect="1" /> + <resource name="unlock-icon" type="image" filename="unlock" retainaspect="1" /> + <resource name="keyboard1" type="image" filename="keyboard1" /> + <resource name="keyboard2" type="image" filename="keyboard2" /> + <resource name="keyboard3" type="image" filename="keyboard3" /> + <resource name="keyboard4" type="image" filename="keyboard4" /> + <resource name="cursor" type="image" filename="cursor" retainaspect="1" /> + </resources> + + <variables> + <variable name="col1_x" value="10" /> + <variable name="col2_x" value="565" /> + <variable name="col_center_x" value="288" /> + <variable name="col_center_medium_x" value="414" /> + <variable name="center_x" value="540" /> + <variable name="row1_y" value="255" /> + <variable name="row2_y" value="615" /> + <variable name="row3_y" value="975" /> + <variable name="row4_y" value="1335" /> + <variable name="col1_center_x" value="179" /> + <variable name="col2_center_x" value="552" /> + <variable name="row1_text2_y" value="310" /> + <variable name="row2_text2_y" value="550" /> + <variable name="row_queue_y" value="1140" /> + <variable name="row1_header_y" value="180" /> + <variable name="row1_text_y" value="255" /> + <variable name="row2_text_y" value="330" /> + <variable name="row3_text_y" value="405" /> + <variable name="row4_text_y" value="480" /> + <variable name="row5_text_y" value="555" /> + <variable name="row6_text_y" value="630" /> + <variable name="row7_text_y" value="705" /> + <variable name="row8_text_y" value="780" /> + <variable name="row9_text_y" value="855" /> + <variable name="row10_text_y" value="930" /> + <variable name="row11_text_y" value="1005" /> + <variable name="row12_text_y" value="1080" /> + <variable name="row13_text_y" value="1155" /> + <variable name="row14_text_y" value="1230" /> + <variable name="row15_text_y" value="1305" /> + <variable name="row16_text_y" value="1380" /> + <variable name="row17_text_y" value="1455" /> + <variable name="row18_text_y" value="1530" /> + <variable name="zip_status_y" value="922" /> + <variable name="flash_list_height" value="500" /> + <variable name="tz_selected_y" value="240" /> + <variable name="tz_set_y" value="1500" /> + <variable name="tz_current_y" value="1425" /> + <variable name="system_ro_y" value="1770" /> + <variable name="col_progressbar_x" value="351" /> + <variable name="row_progressbar_y" value="1650" /> + <variable name="col1_medium_x" value="10" /> + <variable name="col2_medium_x" value="282" /> + <variable name="col3_medium_x" value="545" /> + <variable name="col4_medium_x" value="817" /> + <variable name="row1_medium_y" value="195" /> + <variable name="row2_medium_y" value="345" /> + <variable name="row3_medium_y" value="392" /> + <variable name="row4_medium_y" value="645" /> + <variable name="row5_medium_y" value="795" /> + <variable name="row6_medium_y" value="1260" /> + <variable name="row7_medium_y" value="730" /> + <variable name="slider_y" value="1575" /> + <variable name="slider_text_y" value="1676" /> + <variable name="button_text_color" value="#AAAAAA" /> + <variable name="text_color" value="#FFFFFF" /> + <variable name="text_success_color" value="#33B5E5" /> + <variable name="text_fail_color" value="#FF0101" /> + <variable name="highlight_color" value="#90909080" /> + <variable name="caps_highlight_color" value="#33B5E580" /> + <variable name="home_button_x" value="10" /> + <variable name="home_button_y" value="1839" /> + <variable name="back_button_x" value="1070" /> + <variable name="back_button_y" value="1839" /> + <variable name="sort_text_x" value="10" /> + <variable name="sort_asc_text_y" value="1635" /> + <variable name="sort_asc_button_y" value="1620" /> + <variable name="sort_desc_text_y" value="1725" /> + <variable name="sort_desc_button_y" value="1710" /> + <variable name="sort_col1_button_x" value="390" /> + <variable name="sort_col2_button_x" value="540" /> + <variable name="sort_col3_button_x" value="690" /> + <variable name="input_width" value="1060" /> + <variable name="input_height" value="75" /> + <variable name="input_background_color" value="#303030" /> + <variable name="input_cursor_color" value="#33B5E5" /> + <variable name="input_cursor_width" value="4" /> + <variable name="console_x" value="0" /> + <variable name="console_width" value="1080" /> + <variable name="console_foreground" value="#A0A0A0" /> + <variable name="warning" value="#F8F8A0" /> + <variable name="error" value="#FF4040" /> + <variable name="highlight" value="#33B5E5" /> + <variable name="console_background" value="#303030" /> + <variable name="console_scroll" value="#303030" /> + <variable name="console_action_height" value="705" /> + <variable name="console_install_height" value="900" /> + <variable name="console_installdone_height" value="660" /> + <variable name="fileselector_x" value="5" /> + <variable name="fileselector_width" value="1070" /> + <variable name="fileselector_install_height" value="1170" /> + <variable name="fileselector_header_background" value="#202020" /> + <variable name="fileselector_header_textcolor" value="#AAAAAA" /> + <variable name="fileselector_header_separatorcolor" value="#33B5E5" /> + <variable name="fileselector_header_separatorheight" value="4" /> + <variable name="fileselector_separatorcolor" value="#505050" /> + <variable name="fileselector_separatorheight" value="3" /> + <variable name="fileselector_background" value="#303030" /> + <variable name="fileselector_highlight_color" value="#505050" /> + <variable name="fileselector_highlight_font_color" value="#33B5E5" /> + <variable name="fileselector_spacing" value="48" /> + <variable name="fastscroll_linecolor" value="#50505080" /> + <variable name="fastscroll_rectcolor" value="#33B5E580" /> + <variable name="fastscroll_w" value="90" /> + <variable name="fastscroll_linew" value="3" /> + <variable name="fastscroll_rectw" value="21" /> + <variable name="fastscroll_recth" value="60" /> + <variable name="listbox_x" value="5" /> + <variable name="listbox_width" value="1070" /> + <variable name="listbox_tz_height" value="885" /> + <variable name="listbox_background" value="#303030" /> + <variable name="listbox_spacing" value="24" /> + <variable name="sd_plus_x" value="525" /> + <variable name="sdext_text_x" value="165" /> + <variable name="sdext_text_y" value="270" /> + <variable name="sdswap_button_y" value="390" /> + <variable name="sdswap_text_x" value="165" /> + <variable name="sdswap_text_y" value="405" /> + <variable name="sdfilesystem_text_y" value="510" /> + <variable name="sdfilesystem_button_y" value="570" /> + <variable name="lock_y" value="700" /> + <variable name="filemanager_select_x" value="840" /> + <variable name="filemanager_select_y" value="1620" /> + <variable name="backup_name_y" value="825" /> + <variable name="terminal_console_height" value="1050" /> + <variable name="terminal_text_y" value="1095" /> + <variable name="terminal_button_y" value="1050" /> + <variable name="row_dst_text_y" value="1080" /> + <variable name="row_offset_text_y" value="1155" /> + <variable name="row_offset_medium_y" value="1260" /> + <variable name="button_fill_color" value="#303030" /> + <variable name="button_fill_full_width" value="1060" /> + <variable name="button_fill_main_width" value="505" /> + <variable name="button_fill_main_height" value="324" /> + <variable name="button_fill_half_height" value="162" /> + <variable name="button_fill_quarter_height" value="81" /> + <variable name="backup_list_height" value="780" /> + <variable name="backup_button_row1" value="1118" /> + <variable name="backup_button_row2" value="1220" /> + <variable name="mount_list_height" value="1035" /> + <variable name="mount_storage_row" value="1240" /> + <variable name="storage_list_height" value="1000" /> + <variable name="wipe_list_height" value="1105" /> + <variable name="wipe_button_row1" value="1350" /> + <variable name="wipe_button_y" value="975" /> + <variable name="slidervalue_w" value="1060" /> + <variable name="slidervalue_line_clr" value="#FFFFFF" /> + <variable name="slidervalue_slider_clr" value="#33B5E5" /> + <variable name="slidervalue_lineh" value="3" /> + <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_y" value="508" /> + <variable name="pattern_width" value="648" /> + <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" /> + </variables> + + <mousecursor> + <placement w="15" h="15" /> + <background color="#FFFF00FF" resource="cursor" /> + <speed multiplier="2.5" /> + </mousecursor> + + <templates> + <template name="header"> + <background color="#000000FF" /> + + <object type="fill" color="%button_fill_color%"> + <placement x="0" y="0" w="1080" h="176" /> + </object> + + <object type="fill" color="%highlight%"> + <placement x="0" y="176" w="1080" h="4" /> + </object> + + <object type="image"> + <image resource="twrplogo" /> + <placement x="85" y="85" placement="4" /> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="180" y="15" /> + <text>Team Win Recovery Project v%tw_version%</text> + </object> + + <object type="text" color="%text_color%"> + <condition var1="tw_simulate_actions" var2="1" /> + <font resource="font" /> + <placement x="180" y="60" /> + <text>SIMULATING ACTIONS</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="180" y="114" /> + <text>%tw_time%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="405" y="114" /> + <conditions> + <condition var1="tw_no_battery_percent" var2="0" /> + <condition var1="tw_battery" op=">" var2="0" /> + <condition var1="tw_battery" op="<" var2="101" /> + </conditions> + <text>Battery: %tw_battery%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="760" y="114" /> + <conditions> + <condition var1="tw_no_cpu_temp" var2="0" /> + </conditions> + <text>CPU: %tw_cpu_temp% C</text> + </object> + + <object type="button"> + <highlight color="%highlight_color%" /> + <placement x="%home_button_x%" y="%home_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text></text> + <image resource="home_icon" /> + <condition var1="tw_busy" var2="0" /> + <action function="key">home</action> + </object> + + <object type="button"> + <highlight color="%highlight_color%" /> + <placement x="%back_button_x%" y="%back_button_y%" placement="1" /> + <font resource="font" color="%button_text_color%" /> + <text></text> + <image resource="back_icon" /> + <condition var1="tw_busy" var2="0" /> + <action function="key">back</action> + </object> + + <object type="action"> + <touch key="power" /> + <action function="overlay">lock</action> + </object> + + <object type="action"> + <touch key="power+voldown" /> + <action function="screenshot" /> + </object> + </template> + + <template name="progress_bar"> + <object type="progressbar"> + <placement x="%col_progressbar_x%" y="%row_progressbar_y%" /> + <resource empty="progress_empty" full="progress_full" /> + <data name="ui_progress" /> + </object> + + <object type="animation"> + <placement x="%col_progressbar_x%" y="%row_progressbar_y%" /> + <resource name="progress" /> + <speed fps="15" render="2" /> + <loop frame="1" /> + </object> + </template> + + <template name="sort_options"> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%sort_text_x%" y="%sort_asc_text_y%" /> + <text>Sort Ascending:</text> + </object> + + <object type="button"> + <highlight color="%highlight_color%" /> + <placement x="%sort_col1_button_x%" y="%sort_asc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Name</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=1</action> + </object> + + <object type="button"> + <highlight color="%highlight_color%" /> + <placement x="%sort_col2_button_x%" y="%sort_asc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Date</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=2</action> + </object> + + <object type="button"> + <highlight color="%highlight_color%" /> + <placement x="%sort_col3_button_x%" y="%sort_asc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Size</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=3</action> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%sort_text_x%" y="%sort_desc_text_y%" /> + <text>Sort Descending:</text> + </object> + + <object type="button"> + <highlight color="%highlight_color%" /> + <placement x="%sort_col1_button_x%" y="%sort_desc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Name</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=-1</action> + </object> + + <object type="button"> + <highlight color="%highlight_color%" /> + <placement x="%sort_col2_button_x%" y="%sort_desc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Date</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=-2</action> + </object> + + <object type="button"> + <highlight color="%highlight_color%" /> + <placement x="%sort_col3_button_x%" y="%sort_desc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Size</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=-3</action> + </object> + </template> + + <template name="action_page_console"> + <object type="console"> + <placement x="0" y="%row2_y%" w="1080" h="705" /> + <color foreground="%console_foreground%" background="%console_background%" scroll="%console_scroll%" /> + <font resource="fixed" /> + </object> + </template> + + <template name="footer"> + <object type="console"> + <slideout resource="slideout" x="%center_x%" y="1841" placement="5" /> + <placement x="%console_x%" y="0" w="%console_width%" h="1841" /> + <color foreground="%console_foreground%" background="%console_background%" scroll="%console_scroll%" /> + <font resource="fixed" /> + </object> + </template> + + <template name="keyboardtemplate"> + <object type="keyboard"> + <placement x="0" y="1200" /> + <layout resource1="keyboard1" resource2="keyboard2" resource3="keyboard3" resource4="keyboard4" /> + <highlight color="%highlight_color%" /> + <capshighlight color="%caps_highlight_color%" /> + <layout1> + <keysize height="161" width="108" /> + <row1 key01="q" long01="1" key02="w" long02="2" key03="e" long03="3" key04="r" long04="4" key05="t" long05="5" key06="y" long06="6" key07="u" long07="7" key08="i" long08="8" key09="o" long09="9" key10="p" long10="0" /> + <row2 key01="162:a" long01="@" key02="s" long02="#" key03="d" long03="$" key04="f" long04="%" key05="g" long05="&" key06="h" long06="*" key07="j" long07="-" key08="k" long08="+" key09="162:l" long09="_" /> + <row3 key01="162:layout2" key02="z" long02="!" key03="x" key04="c" long04="'" key05="v" long05=":" key06="b" long06=";" key07="n" long07="/" key08="m" long08="?" key09="162:c:8" /> + <row4 key01="162:layout3" key02="108:c:47" key03="108:" key04="432: " key05="." key06="162:action" /> + </layout1> + <layout2> + <keysize height="161" width="108" capslock="0" revert_layout="1" /> + <row1 key01="Q" long01="1" key02="W" long02="2" key03="E" long03="3" key04="R" long04="4" key05="T" long05="5" key06="Y" long06="6" key07="U" long07="7" key08="I" long08="8" key09="O" long09="9" key10="P" long10="0" /> + <row2 key01="162:A" long01="@" key02="S" long02="#" key03="D" long03="$" key04="F" long04="%" key05="G" long05="&" key06="H" long06="*" key07="J" long07="-" key08="K" long08="+" key09="162:L" long09="_" /> + <row3 key01="162:layout1" key02="Z" long02="!" key03="X" key04="C" long04="'" key05="V" long05=":" key06="B" long06=";" key07="N" long07="/" key08="M" long08="?" key09="162:c:8" /> + <row4 key01="162:layout3" key02="/" key03="108:" key04="432: " key05="." key06="162:action" /> + </layout2> + <layout3> + <keysize height="161" width="108" /> + <row1 key01="1" key02="2" key03="3" key04="4" key05="5" key06="6" key07="7" key08="8" key09="9" key10="0" /> + <row2 key01="@" key02="#" key03="$" key04="%" key05="&" key06="*" key07="-" key08="+" key09="(" key10=")" /> + <row3 key01="162:layout4" key02="!" key03="108:c:34" key04="'" key05=":" key06=";" key07="/" key08="?" key09="162:c:8" /> + <row4 key01="162:layout1" key02="," key03="108:" key04="432: " key05="." key06="162:action" /> + </layout3> + <layout4> + <keysize height="161" width="108" /> + <row1 key01="~" key02="`" key03="|" key04="108:" key05="108:" key06="108:" key07="%" key08="108:" key09="{" key10="}" /> + <row2 key01="108:" key02="108:" key03="108:" key04="108:" key05="108:" key06="^" key07="_" key08="=" key09="[" key10="]" /> + <row3 key01="162:layout3" key02="108:" key03="108:" key04="108:" key05="108:" key06="\" key07="<" key08=">" key09="162:c:8" /> + <row4 key01="162:layout1" key02="108:c:34" key03="108:" key04="432: " key05="." key06="162:action" /> + </layout4> + </object> + </template> + </templates> +</recovery> diff --git a/gui/devices/1920x1200/res/fonts/Roboto-Regular-30.dat b/gui/devices/1920x1200/res/fonts/Roboto-Regular-30.dat Binary files differnew file mode 100644 index 000000000..9f8082ccc --- /dev/null +++ b/gui/devices/1920x1200/res/fonts/Roboto-Regular-30.dat diff --git a/gui/devices/1920x1200/res/images/back-icon.png b/gui/devices/1920x1200/res/images/back-icon.png Binary files differnew file mode 100644 index 000000000..94dd69951 --- /dev/null +++ b/gui/devices/1920x1200/res/images/back-icon.png diff --git a/gui/devices/1920x1200/res/images/button.png b/gui/devices/1920x1200/res/images/button.png Binary files differnew file mode 100644 index 000000000..e1b49fc57 --- /dev/null +++ b/gui/devices/1920x1200/res/images/button.png diff --git a/gui/devices/1920x1200/res/images/checkbox_checked.png b/gui/devices/1920x1200/res/images/checkbox_checked.png Binary files differnew file mode 100644 index 000000000..cac9a30ee --- /dev/null +++ b/gui/devices/1920x1200/res/images/checkbox_checked.png diff --git a/gui/devices/1920x1200/res/images/checkbox_empty.png b/gui/devices/1920x1200/res/images/checkbox_empty.png Binary files differnew file mode 100644 index 000000000..ee01fa852 --- /dev/null +++ b/gui/devices/1920x1200/res/images/checkbox_empty.png diff --git a/gui/devices/1920x1200/res/images/console-icon.png b/gui/devices/1920x1200/res/images/console-icon.png Binary files differnew file mode 100644 index 000000000..c1f4d7165 --- /dev/null +++ b/gui/devices/1920x1200/res/images/console-icon.png diff --git a/gui/devices/1920x1200/res/images/console-toggle.png b/gui/devices/1920x1200/res/images/console-toggle.png Binary files differnew file mode 100644 index 000000000..2495165fc --- /dev/null +++ b/gui/devices/1920x1200/res/images/console-toggle.png diff --git a/gui/devices/1920x1200/res/images/cursor.png b/gui/devices/1920x1200/res/images/cursor.png Binary files differnew file mode 100644 index 000000000..32c8ae1ca --- /dev/null +++ b/gui/devices/1920x1200/res/images/cursor.png diff --git a/gui/devices/1920x1200/res/images/curtain.jpg b/gui/devices/1920x1200/res/images/curtain.jpg Binary files differnew file mode 100644 index 000000000..409664c6c --- /dev/null +++ b/gui/devices/1920x1200/res/images/curtain.jpg diff --git a/gui/devices/1920x1200/res/images/file.png b/gui/devices/1920x1200/res/images/file.png Binary files differnew file mode 100644 index 000000000..c77a1f483 --- /dev/null +++ b/gui/devices/1920x1200/res/images/file.png diff --git a/gui/devices/1920x1200/res/images/folder.png b/gui/devices/1920x1200/res/images/folder.png Binary files differnew file mode 100644 index 000000000..2770f0a24 --- /dev/null +++ b/gui/devices/1920x1200/res/images/folder.png diff --git a/gui/devices/1920x1200/res/images/home-icon.png b/gui/devices/1920x1200/res/images/home-icon.png Binary files differnew file mode 100644 index 000000000..8c1dde3c5 --- /dev/null +++ b/gui/devices/1920x1200/res/images/home-icon.png diff --git a/gui/devices/1920x1200/res/images/indeterminate001.png b/gui/devices/1920x1200/res/images/indeterminate001.png Binary files differnew file mode 100755 index 000000000..ea2b5e2ab --- /dev/null +++ b/gui/devices/1920x1200/res/images/indeterminate001.png diff --git a/gui/devices/1920x1200/res/images/indeterminate002.png b/gui/devices/1920x1200/res/images/indeterminate002.png Binary files differnew file mode 100755 index 000000000..f59b298ee --- /dev/null +++ b/gui/devices/1920x1200/res/images/indeterminate002.png diff --git a/gui/devices/1920x1200/res/images/indeterminate003.png b/gui/devices/1920x1200/res/images/indeterminate003.png Binary files differnew file mode 100755 index 000000000..cc6d7b535 --- /dev/null +++ b/gui/devices/1920x1200/res/images/indeterminate003.png diff --git a/gui/devices/1920x1200/res/images/indeterminate004.png b/gui/devices/1920x1200/res/images/indeterminate004.png Binary files differnew file mode 100755 index 000000000..9483117d6 --- /dev/null +++ b/gui/devices/1920x1200/res/images/indeterminate004.png diff --git a/gui/devices/1920x1200/res/images/indeterminate005.png b/gui/devices/1920x1200/res/images/indeterminate005.png Binary files differnew file mode 100755 index 000000000..850de0f88 --- /dev/null +++ b/gui/devices/1920x1200/res/images/indeterminate005.png diff --git a/gui/devices/1920x1200/res/images/indeterminate006.png b/gui/devices/1920x1200/res/images/indeterminate006.png Binary files differnew file mode 100755 index 000000000..e5194b39d --- /dev/null +++ b/gui/devices/1920x1200/res/images/indeterminate006.png diff --git a/gui/devices/1920x1200/res/images/keyboard1.png b/gui/devices/1920x1200/res/images/keyboard1.png Binary files differnew file mode 100644 index 000000000..8ee241671 --- /dev/null +++ b/gui/devices/1920x1200/res/images/keyboard1.png diff --git a/gui/devices/1920x1200/res/images/keyboard2.png b/gui/devices/1920x1200/res/images/keyboard2.png Binary files differnew file mode 100644 index 000000000..259bfecf5 --- /dev/null +++ b/gui/devices/1920x1200/res/images/keyboard2.png diff --git a/gui/devices/1920x1200/res/images/keyboard3.png b/gui/devices/1920x1200/res/images/keyboard3.png Binary files differnew file mode 100644 index 000000000..aaebd3084 --- /dev/null +++ b/gui/devices/1920x1200/res/images/keyboard3.png diff --git a/gui/devices/1920x1200/res/images/keyboard4.png b/gui/devices/1920x1200/res/images/keyboard4.png Binary files differnew file mode 100644 index 000000000..1fe856566 --- /dev/null +++ b/gui/devices/1920x1200/res/images/keyboard4.png diff --git a/gui/devices/1920x1200/res/images/medium-button.png b/gui/devices/1920x1200/res/images/medium-button.png Binary files differnew file mode 100644 index 000000000..b4eb49324 --- /dev/null +++ b/gui/devices/1920x1200/res/images/medium-button.png diff --git a/gui/devices/1920x1200/res/images/mediumwide-button.png b/gui/devices/1920x1200/res/images/mediumwide-button.png Binary files differnew file mode 100644 index 000000000..3ca436eb2 --- /dev/null +++ b/gui/devices/1920x1200/res/images/mediumwide-button.png diff --git a/gui/devices/1920x1200/res/images/minus-button.png b/gui/devices/1920x1200/res/images/minus-button.png Binary files differnew file mode 100644 index 000000000..8dc17bfe6 --- /dev/null +++ b/gui/devices/1920x1200/res/images/minus-button.png diff --git a/gui/devices/1920x1200/res/images/plus-button.png b/gui/devices/1920x1200/res/images/plus-button.png Binary files differnew file mode 100644 index 000000000..05b34392c --- /dev/null +++ b/gui/devices/1920x1200/res/images/plus-button.png diff --git a/gui/devices/1920x1200/res/images/progress_empty.png b/gui/devices/1920x1200/res/images/progress_empty.png Binary files differnew file mode 100644 index 000000000..ff02df652 --- /dev/null +++ b/gui/devices/1920x1200/res/images/progress_empty.png diff --git a/gui/devices/1920x1200/res/images/progress_fill.png b/gui/devices/1920x1200/res/images/progress_fill.png Binary files differnew file mode 100644 index 000000000..84a582885 --- /dev/null +++ b/gui/devices/1920x1200/res/images/progress_fill.png diff --git a/gui/devices/1920x1200/res/images/radio_empty.png b/gui/devices/1920x1200/res/images/radio_empty.png Binary files differnew file mode 100644 index 000000000..c77130019 --- /dev/null +++ b/gui/devices/1920x1200/res/images/radio_empty.png diff --git a/gui/devices/1920x1200/res/images/radio_selected.png b/gui/devices/1920x1200/res/images/radio_selected.png Binary files differnew file mode 100644 index 000000000..d3b22789a --- /dev/null +++ b/gui/devices/1920x1200/res/images/radio_selected.png diff --git a/gui/devices/1920x1200/res/images/slider-touch.png b/gui/devices/1920x1200/res/images/slider-touch.png Binary files differnew file mode 100644 index 000000000..8a21a3b74 --- /dev/null +++ b/gui/devices/1920x1200/res/images/slider-touch.png diff --git a/gui/devices/1920x1200/res/images/slider-used.png b/gui/devices/1920x1200/res/images/slider-used.png Binary files differnew file mode 100644 index 000000000..4963ff5ae --- /dev/null +++ b/gui/devices/1920x1200/res/images/slider-used.png diff --git a/gui/devices/1920x1200/res/images/slider.png b/gui/devices/1920x1200/res/images/slider.png Binary files differnew file mode 100644 index 000000000..dfeea6eda --- /dev/null +++ b/gui/devices/1920x1200/res/images/slider.png diff --git a/gui/devices/1920x1200/res/images/sort-button.png b/gui/devices/1920x1200/res/images/sort-button.png Binary files differnew file mode 100644 index 000000000..b1f82182f --- /dev/null +++ b/gui/devices/1920x1200/res/images/sort-button.png diff --git a/gui/devices/1920x1200/res/images/twrplogo.png b/gui/devices/1920x1200/res/images/twrplogo.png Binary files differnew file mode 100644 index 000000000..6847db69b --- /dev/null +++ b/gui/devices/1920x1200/res/images/twrplogo.png diff --git a/gui/devices/1920x1200/res/images/unlock.png b/gui/devices/1920x1200/res/images/unlock.png Binary files differnew file mode 100644 index 000000000..6ca95d125 --- /dev/null +++ b/gui/devices/1920x1200/res/images/unlock.png diff --git a/gui/devices/1920x1200/res/ui.xml b/gui/devices/1920x1200/res/ui.xml new file mode 100644 index 000000000..cac02796e --- /dev/null +++ b/gui/devices/1920x1200/res/ui.xml @@ -0,0 +1,456 @@ +<?xml version="1.0"?> + +<recovery> + <details> + <resolution width="1920" height="1200" /> + <author>TeamWin</author> + <title>Backup Naowz</title> + <description>Default basic theme</description> + <preview>preview.jpg</preview> + </details> + + <include> + <xmlfile name="landscape.xml" /> + </include> + + <resources> + <resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="30" fallback="Roboto-Regular-30" /> + <resource name="fixed" type="font" filename="DroidSansMono.ttf" size="22" /> + <resource name="twrplogo" type="image" filename="twrplogo" retainaspect="1" /> + <resource name="main_button" type="image" filename="button" /> + <resource name="file_icon" type="image" filename="file" retainaspect="1" /> + <resource name="folder_icon" type="image" filename="folder" retainaspect="1" /> + <resource name="progress" type="animation" filename="indeterminate" /> + <resource name="progress_empty" type="image" filename="progress_empty" /> + <resource name="progress_full" type="image" filename="progress_fill" /> + <resource name="checkbox_false" type="image" filename="checkbox_empty" retainaspect="1" /> + <resource name="checkbox_true" type="image" filename="checkbox_checked" retainaspect="1" /> + <resource name="radio_false" type="image" filename="radio_empty" retainaspect="1" /> + <resource name="radio_true" type="image" filename="radio_selected" retainaspect="1" /> + <resource name="medium_button" type="image" filename="medium-button" /> + <resource name="mediumwide_button" type="image" filename="mediumwide-button" /> + <resource name="sort_button" type="image" filename="sort-button" /> + <resource name="minus_button" type="image" filename="minus-button" /> + <resource name="plus_button" type="image" filename="plus-button" /> + <resource name="home_icon" type="image" filename="home-icon" retainaspect="1" /> + <resource name="back_icon" type="image" filename="back-icon" retainaspect="1" /> + <resource name="console_button" type="image" filename="console-toggle" retainaspect="1" /> + <resource name="slider" type="image" filename="slider" retainaspect="1" /> + <resource name="slider-used" type="image" filename="slider-used" retainaspect="1" /> + <resource name="slider-touch" type="image" filename="slider-touch" retainaspect="1" /> + <resource name="unlock-icon" type="image" filename="unlock" retainaspect="1" /> + <resource name="keyboard1" type="image" filename="keyboard1" /> + <resource name="keyboard2" type="image" filename="keyboard2" /> + <resource name="keyboard3" type="image" filename="keyboard3" /> + <resource name="keyboard4" type="image" filename="keyboard4" /> + <resource name="cursor" type="image" filename="cursor" retainaspect="1" /> + </resources> + + <variables> + <variable name="col1_x" value="210" /> + <variable name="col2_x" value="590" /> + <variable name="col3_x" value="970" /> + <variable name="col4_x" value="1350" /> + <variable name="row1_y" value="220" /> + <variable name="row2_y" value="680" /> + <variable name="col_center_x" value="780" /> + <variable name="center_x" value="960" /> + <variable name="screen_width" value="1920" /> + <variable name="screen_height" value="1200" /> + <variable name="col_progressbar_x" value="771" /> + <variable name="row_progressbar_y" value="1100" /> + <variable name="col1_medium_x" value="570" /> + <variable name="col2_medium_x" value="770" /> + <variable name="col3_medium_x" value="970" /> + <variable name="col4_medium_x" value="1170" /> + <variable name="row1_medium_y" value="105" /> + <variable name="row2_medium_y" value="365" /> + <variable name="row3_medium_y" value="245" /> + <variable name="row4_medium_y" value="720" /> + <variable name="row5_medium_y" value="700" /> + <variable name="row1_text_y" value="90" /> + <variable name="row2_text_y" value="140" /> + <variable name="row3_text_y" value="190" /> + <variable name="row4_text_y" value="240" /> + <variable name="row5_text_y" value="290" /> + <variable name="row6_text_y" value="340" /> + <variable name="row7_text_y" value="390" /> + <variable name="row8_text_y" value="440" /> + <variable name="row9_text_y" value="490" /> + <variable name="row10_text_y" value="540" /> + <variable name="row11_text_y" value="590" /> + <variable name="row12_text_y" value="640" /> + <variable name="row13_text_y" value="690" /> + <variable name="row14_text_y" value="740" /> + <variable name="row15_text_y" value="790" /> + <variable name="row16_text_y" value="840" /> + <variable name="row17_text_y" value="890" /> + <variable name="row18_text_y" value="940" /> + <variable name="row_offsetmedium_y" value="775" /> + <variable name="home_button_x" value="1620" /> + <variable name="home_button_y" value="5" /> + <variable name="back_button_x" value="1720" /> + <variable name="back_button_y" value="5" /> + <variable name="console_button_x" value="1820" /> + <variable name="console_button_y" value="5" /> + <variable name="nandcheck_col1" value="328" /> + <variable name="nandcheck_col2" value="800" /> + <variable name="nandcheck_row1" value="200" /> + <variable name="nandcheck_row2" value="275" /> + <variable name="nandcheck_row3" value="350" /> + <variable name="nandcheck_row4" value="425" /> + <variable name="nandcheck_row5" value="500" /> + <variable name="nandcheck_row6" value="575" /> + <variable name="nandcheck_row7" value="650" /> + <variable name="nandcheck_row8" value="725" /> + <variable name="button_text_color" value="#AAAAAA" /> + <variable name="text_color" value="#A0A0A0" /> + <variable name="text_success_color" value="#33B5E5" /> + <variable name="text_fail_color" value="#FF0101" /> + <variable name="highlight_color" value="#90909080" /> + <variable name="caps_highlight_color" value="#33B5E580" /> + <variable name="slider_y" value="1000" /> + <variable name="slider_text_y" value="1075" /> + <variable name="sort_text_x" value="400" /> + <variable name="sort_asc_text_y" value="1045" /> + <variable name="sort_asc_button_y" value="1040" /> + <variable name="sort_desc_text_y" value="1105" /> + <variable name="sort_desc_button_y" value="1100" /> + <variable name="sort_col1_button_x" value="670" /> + <variable name="sort_col2_button_x" value="770" /> + <variable name="sort_col3_button_x" value="870" /> + <variable name="col1_sdext_x" value="720" /> + <variable name="col2_sdext_x" value="1100" /> + <variable name="row1_sdext_y" value="180" /> + <variable name="row2_sdext_y" value="265" /> + <variable name="row_extsize_y" value="175" /> + <variable name="row_swapsize_y" value="260" /> + <variable name="input_x" value="50" /> + <variable name="input_width" value="1820" /> + <variable name="input_height" value="50" /> + <variable name="input_background_color" value="#303030" /> + <variable name="input_cursor_color" value="#33B5E5" /> + <variable name="input_cursor_width" value="3" /> + <variable name="console_x" value="50" /> + <variable name="console_width" value="1820" /> + <variable name="console_foreground" value="#A0A0A0" /> + <variable name="warning" value="#F8F8A0" /> + <variable name="error" value="#FF4040" /> + <variable name="highlight" value="#33B5E5" /> + <variable name="console_background" value="#303030" /> + <variable name="console_scroll" value="#303030" /> + <variable name="console_action_height" value="320" /> + <variable name="console_install_height" value="440" /> + <variable name="console_installdone_height" value="300" /> + <variable name="fileselector_folder_x" value="50" /> + <variable name="fileselector_folder_width" value="610" /> + <variable name="fileselector_folderonly_width" value="800" /> + <variable name="fileselector_file_x" value="700" /> + <variable name="fileselector_file_width" value="1170" /> + <variable name="fileselector_install_y" value="205" /> + <variable name="fileselector_install_height" value="800" /> + <variable name="fileselector_header_background" value="#202020" /> + <variable name="fileselector_header_textcolor" value="#AAAAAA" /> + <variable name="fileselector_header_separatorcolor" value="#33B5E5" /> + <variable name="fileselector_header_separatorheight" value="3" /> + <variable name="fileselector_separatorcolor" value="#505050" /> + <variable name="fileselector_separatorheight" value="2" /> + <variable name="fileselector_background" value="#303030" /> + <variable name="fileselector_highlight_color" value="#505050" /> + <variable name="fileselector_highlight_font_color" value="#33B5E5" /> + <variable name="fileselector_spacing" value="18" /> + <variable name="fastscroll_linecolor" value="#50505080" /> + <variable name="fastscroll_rectcolor" value="#33B5E580" /> + <variable name="fastscroll_w" value="60" /> + <variable name="fastscroll_linew" value="3" /> + <variable name="fastscroll_rectw" value="15" /> + <variable name="fastscroll_recth" value="40" /> + <variable name="zipstorage_text_y" value="130" /> + <variable name="listbox_x" value="560" /> + <variable name="listbox_y" value="150" /> + <variable name="listbox_width" value="800" /> + <variable name="listbox_tz_height" value="400" /> + <variable name="listbox_background" value="#303030" /> + <variable name="listbox_spacing" value="18" /> + <variable name="sd_plus_x" value="408" /> + <variable name="lock_y" value="300" /> + <variable name="filemanager_select_x" value="1500" /> + <variable name="filemanager_select_y" value="980" /> + <variable name="backup_name_text_y" value="440" /> + <variable name="backup_name_button_y" value="390" /> + <variable name="col_right_x" value="1870" /> + <variable name="cancel_button_y" value="240" /> + <variable name="terminal_console_y" value="0" /> + <variable name="terminal_console_height" value="610" /> + <variable name="terminal_text_y" value="624" /> + <variable name="terminal_button_y" value="615" /> + <variable name="terminal_input_width" value="1550" /> + <variable name="button_fill_color" value="#303030" /> + <variable name="button_fill_full_width" value="960" /> + <variable name="button_fill_main_width" value="900" /> + <variable name="button_fill_main_height" value="240" /> + <variable name="button_fill_half_height" value="80" /> + <variable name="button_fill_quarter_height" value="60" /> + <variable name="button_full_center_x" value="480" /> + <variable name="flash_list_height" value="300" /> + <variable name="backup_list_x" value="50" /> + <variable name="backup_list_y" value="160" /> + <variable name="backup_list_width" value="900" /> + <variable name="backup_list_height" value="660" /> + <variable name="backup_storage_y" value="405" /> + <variable name="backup_encrypt_y" value="495" /> + <variable name="restore_list_y" value="190" /> + <variable name="restore_list_height" value="600" /> + <variable name="mount_list_height" value="900" /> + <variable name="mount_storage_row" value="850" /> + <variable name="wipe_list_height" value="850" /> + <variable name="wipe_button_y" value="375" /> + <variable name="slidervalue_x" value="540" /> + <variable name="slidervalue_w" value="960" /> + <variable name="slidervalue_line_clr" value="#FFFFFF" /> + <variable name="slidervalue_slider_clr" value="#33B5E5" /> + <variable name="slidervalue_lineh" value="3" /> + <variable name="slidervalue_padding" value="0" /> + <variable name="slidervalue_sliderw" value="20" /> + <variable name="slidervalue_sliderh" value="80" /> + <variable name="pattern_x" value="480" /> + <variable name="pattern_y" value="240" /> + <variable name="pattern_width" value="720" /> + <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" /> + </variables> + + <mousecursor> + <placement w="15" h="15" /> + <background color="#FFFF00FF" resource="cursor" /> + <speed multiplier="2.5" /> + </mousecursor> + + <templates> + <template name="header"> + <background color="#000000FF" /> + + <object type="fill" color="%button_fill_color%"> + <placement x="0" y="0" w="1920" h="87" /> + </object> + + <object type="fill" color="%highlight%"> + <placement x="0" y="87" w="1920" h="3" /> + </object> + + <object type="image"> + <image resource="twrplogo" /> + <placement x="55" y="45" placement="4" /> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="100" y="5" /> + <text>Team Win Recovery Project v%tw_version%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="100" y="40" /> + <conditions> + <condition var1="tw_no_battery_percent" var2="0" /> + <condition var1="tw_battery" op=">" var2="0" /> + <condition var1="tw_battery" op="<" var2="101" /> + </conditions> + <text>Battery Level: %tw_battery%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="600" y="40" /> + <text>%tw_time%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="1150" y="40" /> + <conditions> + <condition var1="tw_no_cpu_temp" var2="0" /> + </conditions> + <text>CPU: %tw_cpu_temp% C</text> + </object> + + <object type="text" color="%text_color%"> + <condition var1="tw_simulate_actions" var2="1" /> + <font resource="font" /> + <placement x="750" y="40" /> + <text>SIMULATING ACTIONS</text> + </object> + + <object type="button"> + <placement x="%home_button_x%" y="%home_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text></text> + <image resource="home_icon" /> + <condition var1="tw_busy" var2="0" /> + <action function="key">home</action> + </object> + + <object type="button"> + <placement x="%back_button_x%" y="%back_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text></text> + <image resource="back_icon" /> + <condition var1="tw_busy" var2="0" /> + <action function="key">back</action> + </object> + + <object type="action"> + <touch key="power" /> + <action function="overlay">lock</action> + </object> + + <object type="action"> + <touch key="power+voldown" /> + <action function="screenshot" /> + </object> + </template> + + <template name="progress_bar"> + <object type="progressbar"> + <placement x="%col_progressbar_x%" y="%row_progressbar_y%" /> + <resource empty="progress_empty" full="progress_full" /> + <data name="ui_progress" /> + </object> + + <object type="animation"> + <placement x="%col_progressbar_x%" y="%row_progressbar_y%" /> + <resource name="progress" /> + <speed fps="15" render="6" /> + <loop frame="1" /> + </object> + </template> + + <template name="sort_options"> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%sort_text_x%" y="%sort_asc_text_y%" /> + <text>Sort Ascending:</text> + </object> + + <object type="button"> + <placement x="%sort_col1_button_x%" y="%sort_asc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Name</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=1</action> + </object> + + <object type="button"> + <placement x="%sort_col2_button_x%" y="%sort_asc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Date</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=2</action> + </object> + + <object type="button"> + <placement x="%sort_col3_button_x%" y="%sort_asc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Size</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=3</action> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%sort_text_x%" y="%sort_desc_text_y%" /> + <text>Sort Descending:</text> + </object> + + <object type="button"> + <placement x="%sort_col1_button_x%" y="%sort_desc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Name</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=-1</action> + </object> + + <object type="button"> + <placement x="%sort_col2_button_x%" y="%sort_desc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Date</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=-2</action> + </object> + + <object type="button"> + <placement x="%sort_col3_button_x%" y="%sort_desc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Size</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=-3</action> + </object> + </template> + + <template name="flash_zip_console"> + <object type="console"> + <placement x="%console_x%" y="140" w="%console_width%" h="700" /> + <color foreground="%console_foreground%" background="%console_background%" scroll="%console_scroll%" /> + <font resource="fixed" /> + </object> + </template> + + <template name="action_page_console"> + <object type="console"> + <placement x="%console_x%" y="400" w="%console_width%" h="600" /> + <color foreground="%console_foreground%" background="%console_background%" scroll="%console_scroll%" /> + <font resource="fixed" /> + </object> + </template> + + <template name="footer"> + <object type="console"> + <slideout resource="console_button" x="%console_button_x%" y="%console_button_y%" /> + <placement x="%console_x%" y="150" w="%console_width%" h="1000" /> + <color foreground="%console_foreground%" background="%console_background%" scroll="%console_scroll%" /> + <font resource="fixed" /> + </object> + </template> + + <template name="keyboardtemplate"> + <object type="keyboard"> + <placement x="0" y="684" /> + <layout resource1="keyboard1" resource2="keyboard2" resource3="keyboard3" resource4="keyboard4" /> + <highlight color="%highlight_color%" /> + <capshighlight color="%caps_highlight_color%" /> + <layout1> + <keysize height="129" width="159" /> + <row1 key01="153:" key02="q" long02="1" key03="w" long03="2" key04="e" long04="3" key05="r" long05="4" key06="t" long06="5" key07="y" long07="6" key08="u" long08="7" key09="i" long09="8" key10="o" long10="9" key11="p" long11="0" key12="177:c:8" /> + <row2 key01="213:layout3" key02="156:a" key03="156:s" key04="156:d" key05="156:f" key06="156:g" key07="156:h" key08="156:j" key09="k" key10="156:l" key11="303:action" /> + <row3 key01="269:layout2" key02="154:z" key03="154:x" key04="154:c" key05="154:v" key06="154:b" key07="154:n" key08="154:m" key09="154:," long09="!" key10="154:." long10="?" key11="265:layout2" /> + <row4 key01="600:" key02="720: " key03="/" long03=":" key04="-" long04="_" /> + </layout1> + <layout2> + <keysize height="129" width="159" capslock="0" revert_layout="1" /> + <row1 key01="153:" key02="Q" long02="1" key03="W" long03="2" key04="E" long04="3" key05="R" long05="4" key06="T" long06="5" key07="Y" long07="6" key08="U" long08="7" key09="I" long09="8" key10="O" long10="9" key11="P" long11="0" key12="177:c:8" /> + <row2 key01="213:layout3" key02="156:A" key03="156:S" key04="156:D" key05="156:F" key06="156:G" key07="156:H" key08="156:J" key09="156:K" key10="156:L" key11="303:action" /> + <row3 key01="269:layout1" key02="154:Z" key03="154:X" key04="154:C" key05="154:V" key06="154:B" key07="154:N" key08="154:M" key09="154:!" key10="154:?" key11="265:layout1" /> + <row4 key01="600:" key02="720: " key03=":" key04="_" /> + </layout2> + <layout3> + <keysize height="129" width="159" /> + <row1 key01="153:" key02="1" key03="2" key04="3" key05="4" key06="5" key07="6" key08="7" key09="8" key10="9" key11="0" key12="177:c:8" /> + <row2 key01="213:layout1" key02="156:#" key03="156:$" key04="156:%" key05="156:&" key06="156:*" key07="156:-" key08="156:+" key09="156:(" key10="156:)" key11="303:action" /> + <row3 key01="269:layout4" key02="154:<" key03="154:>" key04="154:=" key05="154:'" key06="154:;" key07="154:," key08="154:." key09="154:!" key10="154:?" key11="265:layout4" /> + <row4 key01="282:" key02="/" key03="@" key04="720: " key05="159:c:34" key06="_" /> + </layout3> + <layout4> + <keysize height="129" width="159" /> + <row1 key01="153:" key02="~" key03="`" key04="|" key05="159:" key06="159:" key07="159:" key08="159:" key09="159:" key10="159:" key11="159:" key12="177:c:8" /> + <row2 key01="213:layout1" key02="156:" key03="156:" key04="156:" key05="156:" key06="156:^" key07="156:" key08="156:" key09="156:{" key10="156:}" key11="303:action" /> + <row3 key01="269:layout3" key02="154:\" key03="154:" key04="154:" key05="154:" key06="154:" key07="154:[" key08="154:]" key09="154:!" key10="154:?" key11="265:layout3" /> + <row4 key01="600:" key02="720: " /> + </layout4> + </object> + </template> + </templates> +</recovery> diff --git a/gui/devices/320x320/res/fonts/Roboto-Condensed-14.dat b/gui/devices/320x320/res/fonts/Roboto-Condensed-14.dat Binary files differnew file mode 100644 index 000000000..f7b174cb1 --- /dev/null +++ b/gui/devices/320x320/res/fonts/Roboto-Condensed-14.dat diff --git a/gui/devices/320x320/res/images/back-icon.png b/gui/devices/320x320/res/images/back-icon.png Binary files differnew file mode 100644 index 000000000..fa365f734 --- /dev/null +++ b/gui/devices/320x320/res/images/back-icon.png diff --git a/gui/devices/320x320/res/images/checkbox_checked.png b/gui/devices/320x320/res/images/checkbox_checked.png Binary files differnew file mode 100644 index 000000000..81037cb70 --- /dev/null +++ b/gui/devices/320x320/res/images/checkbox_checked.png diff --git a/gui/devices/320x320/res/images/checkbox_empty.png b/gui/devices/320x320/res/images/checkbox_empty.png Binary files differnew file mode 100644 index 000000000..94bb057f5 --- /dev/null +++ b/gui/devices/320x320/res/images/checkbox_empty.png diff --git a/gui/devices/320x320/res/images/cursor.png b/gui/devices/320x320/res/images/cursor.png Binary files differnew file mode 100644 index 000000000..32c8ae1ca --- /dev/null +++ b/gui/devices/320x320/res/images/cursor.png diff --git a/gui/devices/320x320/res/images/curtain.jpg b/gui/devices/320x320/res/images/curtain.jpg Binary files differnew file mode 100644 index 000000000..0368a6574 --- /dev/null +++ b/gui/devices/320x320/res/images/curtain.jpg diff --git a/gui/devices/320x320/res/images/file.png b/gui/devices/320x320/res/images/file.png Binary files differnew file mode 100644 index 000000000..81ba38113 --- /dev/null +++ b/gui/devices/320x320/res/images/file.png diff --git a/gui/devices/320x320/res/images/folder.png b/gui/devices/320x320/res/images/folder.png Binary files differnew file mode 100644 index 000000000..feeffe181 --- /dev/null +++ b/gui/devices/320x320/res/images/folder.png diff --git a/gui/devices/320x320/res/images/home-icon.png b/gui/devices/320x320/res/images/home-icon.png Binary files differnew file mode 100644 index 000000000..444ffa509 --- /dev/null +++ b/gui/devices/320x320/res/images/home-icon.png diff --git a/gui/devices/320x320/res/images/indeterminate001.png b/gui/devices/320x320/res/images/indeterminate001.png Binary files differnew file mode 100644 index 000000000..4a80bc5ac --- /dev/null +++ b/gui/devices/320x320/res/images/indeterminate001.png diff --git a/gui/devices/320x320/res/images/indeterminate002.png b/gui/devices/320x320/res/images/indeterminate002.png Binary files differnew file mode 100644 index 000000000..a0b1a03d5 --- /dev/null +++ b/gui/devices/320x320/res/images/indeterminate002.png diff --git a/gui/devices/320x320/res/images/indeterminate003.png b/gui/devices/320x320/res/images/indeterminate003.png Binary files differnew file mode 100644 index 000000000..c59c24260 --- /dev/null +++ b/gui/devices/320x320/res/images/indeterminate003.png diff --git a/gui/devices/320x320/res/images/indeterminate004.png b/gui/devices/320x320/res/images/indeterminate004.png Binary files differnew file mode 100644 index 000000000..0d7a3a49e --- /dev/null +++ b/gui/devices/320x320/res/images/indeterminate004.png diff --git a/gui/devices/320x320/res/images/indeterminate005.png b/gui/devices/320x320/res/images/indeterminate005.png Binary files differnew file mode 100644 index 000000000..a9a6638d9 --- /dev/null +++ b/gui/devices/320x320/res/images/indeterminate005.png diff --git a/gui/devices/320x320/res/images/indeterminate006.png b/gui/devices/320x320/res/images/indeterminate006.png Binary files differnew file mode 100644 index 000000000..386abba25 --- /dev/null +++ b/gui/devices/320x320/res/images/indeterminate006.png diff --git a/gui/devices/320x320/res/images/keyboard1.png b/gui/devices/320x320/res/images/keyboard1.png Binary files differnew file mode 100644 index 000000000..49e2d50b4 --- /dev/null +++ b/gui/devices/320x320/res/images/keyboard1.png diff --git a/gui/devices/320x320/res/images/keyboard2.png b/gui/devices/320x320/res/images/keyboard2.png Binary files differnew file mode 100644 index 000000000..bf7668a6a --- /dev/null +++ b/gui/devices/320x320/res/images/keyboard2.png diff --git a/gui/devices/320x320/res/images/keyboard3.png b/gui/devices/320x320/res/images/keyboard3.png Binary files differnew file mode 100644 index 000000000..ff4d63e8b --- /dev/null +++ b/gui/devices/320x320/res/images/keyboard3.png diff --git a/gui/devices/320x320/res/images/keyboard4.png b/gui/devices/320x320/res/images/keyboard4.png Binary files differnew file mode 100644 index 000000000..5939b5231 --- /dev/null +++ b/gui/devices/320x320/res/images/keyboard4.png diff --git a/gui/devices/320x320/res/images/medium-button.png b/gui/devices/320x320/res/images/medium-button.png Binary files differnew file mode 100644 index 000000000..379eb8616 --- /dev/null +++ b/gui/devices/320x320/res/images/medium-button.png diff --git a/gui/devices/320x320/res/images/menu-button.png b/gui/devices/320x320/res/images/menu-button.png Binary files differnew file mode 100644 index 000000000..109a148e7 --- /dev/null +++ b/gui/devices/320x320/res/images/menu-button.png diff --git a/gui/devices/320x320/res/images/minus-button.png b/gui/devices/320x320/res/images/minus-button.png Binary files differnew file mode 100644 index 000000000..2f1b27fff --- /dev/null +++ b/gui/devices/320x320/res/images/minus-button.png diff --git a/gui/devices/320x320/res/images/plus-button.png b/gui/devices/320x320/res/images/plus-button.png Binary files differnew file mode 100644 index 000000000..f223a98ac --- /dev/null +++ b/gui/devices/320x320/res/images/plus-button.png diff --git a/gui/devices/320x320/res/images/progress_empty.png b/gui/devices/320x320/res/images/progress_empty.png Binary files differnew file mode 100644 index 000000000..6d906d264 --- /dev/null +++ b/gui/devices/320x320/res/images/progress_empty.png diff --git a/gui/devices/320x320/res/images/progress_fill.png b/gui/devices/320x320/res/images/progress_fill.png Binary files differnew file mode 100644 index 000000000..c4b590300 --- /dev/null +++ b/gui/devices/320x320/res/images/progress_fill.png diff --git a/gui/devices/320x320/res/images/radio_empty.png b/gui/devices/320x320/res/images/radio_empty.png Binary files differnew file mode 100644 index 000000000..0766a307e --- /dev/null +++ b/gui/devices/320x320/res/images/radio_empty.png diff --git a/gui/devices/320x320/res/images/radio_selected.png b/gui/devices/320x320/res/images/radio_selected.png Binary files differnew file mode 100644 index 000000000..cf0d92539 --- /dev/null +++ b/gui/devices/320x320/res/images/radio_selected.png diff --git a/gui/devices/320x320/res/images/slideout.png b/gui/devices/320x320/res/images/slideout.png Binary files differnew file mode 100644 index 000000000..df7a0fa70 --- /dev/null +++ b/gui/devices/320x320/res/images/slideout.png diff --git a/gui/devices/320x320/res/images/slider-touch.png b/gui/devices/320x320/res/images/slider-touch.png Binary files differnew file mode 100644 index 000000000..e069c0fbb --- /dev/null +++ b/gui/devices/320x320/res/images/slider-touch.png diff --git a/gui/devices/320x320/res/images/slider-used.png b/gui/devices/320x320/res/images/slider-used.png Binary files differnew file mode 100644 index 000000000..bd37e5457 --- /dev/null +++ b/gui/devices/320x320/res/images/slider-used.png diff --git a/gui/devices/320x320/res/images/slider.png b/gui/devices/320x320/res/images/slider.png Binary files differnew file mode 100644 index 000000000..d735417f1 --- /dev/null +++ b/gui/devices/320x320/res/images/slider.png diff --git a/gui/devices/320x320/res/images/sort-button.png b/gui/devices/320x320/res/images/sort-button.png Binary files differnew file mode 100644 index 000000000..07b1b2498 --- /dev/null +++ b/gui/devices/320x320/res/images/sort-button.png diff --git a/gui/devices/320x320/res/images/twrplogo.png b/gui/devices/320x320/res/images/twrplogo.png Binary files differnew file mode 100644 index 000000000..a95be1a30 --- /dev/null +++ b/gui/devices/320x320/res/images/twrplogo.png diff --git a/gui/devices/320x320/res/images/unlock.png b/gui/devices/320x320/res/images/unlock.png Binary files differnew file mode 100644 index 000000000..c6b5cffea --- /dev/null +++ b/gui/devices/320x320/res/images/unlock.png diff --git a/gui/devices/320x320/res/ui.xml b/gui/devices/320x320/res/ui.xml new file mode 100644 index 000000000..1dec40504 --- /dev/null +++ b/gui/devices/320x320/res/ui.xml @@ -0,0 +1,434 @@ +<?xml version="1.0"?> + +<recovery> + <details> + <resolution width="320" height="320" /> + <roundscreen offset_x="40" offset_y="40" /> + <author>TeamWin</author> + <title>Backup Naowz</title> + <description>Default basic theme</description> + <preview>preview.jpg</preview> + </details> + + <include> + <xmlfile name="watch.xml" /> + </include> + + <resources> + <resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="14" fallback="Roboto-Condensed-14" /> + <resource name="mediumfont" type="font" filename="RobotoCondensed-Regular.ttf" size="14" fallback="Roboto-Condensed-14" /> + <resource name="filelist" type="font" filename="RobotoCondensed-Regular.ttf" size="14" fallback="Roboto-Condensed-14" /> + <resource name="fixed" type="font" filename="DroidSansMono.ttf" size="12" /> + <resource name="twrplogo" type="image" filename="twrplogo" retainaspect="1" /> + <resource name="main_button" type="image" filename="menu-button" /> + <resource name="file_icon" type="image" filename="file" retainaspect="1" /> + <resource name="folder_icon" type="image" filename="folder" retainaspect="1" /> + <resource name="slideout" type="image" filename="slideout" retainaspect="1" /> + <resource name="progress" type="animation" filename="indeterminate" /> + <resource name="progress_empty" type="image" filename="progress_empty" /> + <resource name="progress_full" type="image" filename="progress_fill" /> + <resource name="checkbox_false" type="image" filename="checkbox_empty" retainaspect="1" /> + <resource name="checkbox_true" type="image" filename="checkbox_checked" retainaspect="1" /> + <resource name="radio_false" type="image" filename="radio_empty" retainaspect="1" /> + <resource name="radio_true" type="image" filename="radio_selected" retainaspect="1" /> + <resource name="medium_button" type="image" filename="medium-button" /> + <resource name="sort_button" type="image" filename="sort-button" /> + <resource name="minus_button" type="image" filename="minus-button" /> + <resource name="plus_button" type="image" filename="plus-button" /> + <resource name="home_icon" type="image" filename="home-icon" retainaspect="1" /> + <resource name="back_icon" type="image" filename="back-icon" retainaspect="1" /> + <resource name="slider" type="image" filename="slider" retainaspect="1" /> + <resource name="slider-used" type="image" filename="slider-used" retainaspect="1" /> + <resource name="slider-touch" type="image" filename="slider-touch" retainaspect="1" /> + <resource name="unlock-icon" type="image" filename="unlock" retainaspect="1" /> + <resource name="keyboard1" type="image" filename="keyboard1" /> + <resource name="keyboard2" type="image" filename="keyboard2" /> + <resource name="keyboard3" type="image" filename="keyboard3" /> + <resource name="keyboard4" type="image" filename="keyboard4" /> + <resource name="cursor" type="image" filename="cursor" retainaspect="1" /> + </resources> + + <variables> + <variable name="col1_x" value="6" /> + <variable name="col2_x" value="170" /> + <variable name="col_center_x" value="88" /> + <variable name="col_center_medium_x" value="130" /> + <variable name="center_x" value="160" /> + <variable name="row1_home_y" value="50" /> + <variable name="row2_home_y" value="110" /> + <variable name="row3_home_y" value="170" /> + <variable name="row4_home_y" value="230" /> + <variable name="row1_y" value="30" /> + <variable name="row2_y" value="100" /> + <variable name="row3_y" value="170" /> + <variable name="row4_y" value="240" /> + <variable name="row_queue_y" value="184" /> + <variable name="row1_header_y" value="0" /> + <variable name="row1_text_y" value="22" /> + <variable name="row2_text_y" value="44" /> + <variable name="row3_text_y" value="66" /> + <variable name="row4_text_y" value="88" /> + <variable name="row5_text_y" value="110" /> + <variable name="row6_text_y" value="132" /> + <variable name="row7_text_y" value="154" /> + <variable name="row8_text_y" value="176" /> + <variable name="row9_text_y" value="198" /> + <variable name="row10_text_y" value="220" /> + <variable name="row11_text_y" value="242" /> + <variable name="row12_text_y" value="284" /> + <variable name="row13_text_y" value="306" /> + <variable name="zip_status_y" value="300" /> + <variable name="flash_list_height" value="160" /> + <variable name="backup_text_y" value="60" /> + <variable name="col_progressbar_x" value="34" /> + <variable name="row_progressbar_y" value="285" /> + <variable name="col1_medium_x" value="6" /> + <variable name="col2_medium_x" value="83" /> + <variable name="col3_medium_x" value="174" /> + <variable name="col4_medium_x" value="254" /> + <variable name="row1_medium_y" value="24" /> + <variable name="row2_medium_y" value="40" /> + <variable name="row3_medium_y" value="56" /> + <variable name="row4_medium_y" value="72" /> + <variable name="row5_medium_y" value="88" /> + <variable name="row6_medium_y" value="104" /> + <variable name="row7_medium_y" value="120" /> + <variable name="slider_y" value="268" /> + <variable name="slider_text_y" value="294" /> + <variable name="button_text_color" value="#AAAAAA" /> + <variable name="text_color" value="#FFFFFF" /> + <variable name="text_success_color" value="#33B5E5" /> + <variable name="text_fail_color" value="#FF0101" /> + <variable name="highlight_color" value="#90909080" /> + <variable name="caps_highlight_color" value="#33B5E580" /> + <variable name="home_button_x" value="3" /> + <variable name="home_button_y" value="300" /> + <variable name="back_button_x" value="317" /> + <variable name="back_button_y" value="300" /> + <variable name="sort_text_x" value="20" /> + <variable name="sort_asc_text_y" value="232" /> + <variable name="sort_asc_button_y" value="230" /> + <variable name="sort_desc_text_y" value="262" /> + <variable name="sort_desc_button_y" value="260" /> + <variable name="sort_col1_button_x" value="135" /> + <variable name="sort_col2_button_x" value="195" /> + <variable name="sort_col3_button_x" value="255" /> + <variable name="input_width" value="308" /> + <variable name="input_width_conf" value="10" /> + <variable name="input_height" value="18" /> + <variable name="input_background_color" value="#303030" /> + <variable name="input_cursor_color" value="#33B5E5" /> + <variable name="input_cursor_width" value="2" /> + <variable name="console_x" value="0" /> + <variable name="console_width" value="320" /> + <variable name="console_foreground" value="#A0A0A0" /> + <variable name="warning" value="#F8F8A0" /> + <variable name="error" value="#FF4040" /> + <variable name="highlight" value="#33B5E5" /> + <variable name="console_background" value="#303030" /> + <variable name="console_scroll" value="#303030" /> + <variable name="console_action_height" value="160" /> + <variable name="console_install_height" value="160" /> + <variable name="console_installdone_height" value="160" /> + <variable name="fileselector_x" value="0" /> + <variable name="fileselector_y" value="44" /> + <variable name="fileselector_width" value="320" /> + <variable name="fileselector_install_height" value="182" /> + <variable name="fileselector_header_background" value="#202020" /> + <variable name="fileselector_header_textcolor" value="#AAAAAA" /> + <variable name="fileselector_header_separatorcolor" value="#33B5E5" /> + <variable name="fileselector_header_separatorheight" value="2" /> + <variable name="fileselector_separatorcolor" value="#505050" /> + <variable name="fileselector_separatorheight" value="1" /> + <variable name="fileselector_background" value="#303030" /> + <variable name="fileselector_highlight_color" value="#505050" /> + <variable name="fileselector_highlight_font_color" value="#33B5E5" /> + <variable name="fileselector_spacing" value="12" /> + <variable name="fastscroll_linecolor" value="#50505080" /> + <variable name="fastscroll_rectcolor" value="#33B5E580" /> + <variable name="fastscroll_w" value="32" /> + <variable name="fastscroll_linew" value="1" /> + <variable name="fastscroll_rectw" value="7" /> + <variable name="fastscroll_recth" value="24" /> + <variable name="listbox_x" value="0" /> + <variable name="listbox_width" value="320" /> + <variable name="listbox_background" value="#303030" /> + <variable name="listbox_spacing" value="12" /> + <variable name="sd_plus_x" value="174" /> + <variable name="sdext_text_x" value="56" /> + <variable name="sdext_text_y" value="18" /> + <variable name="sdswap_button_y" value="45" /> + <variable name="sdswap_text_x" value="56" /> + <variable name="sdswap_text_y" value="47" /> + <variable name="sdfilesystem_text_y" value="92" /> + <variable name="sdfilesystem_button_y" value="120" /> + <variable name="lock_y" value="120" /> + <variable name="filemanager_select_x" value="130" /> + <variable name="filemanager_select_y" value="280" /> + <variable name="terminal_console_height" value="126" /> + <variable name="terminal_text_y" value="128" /> + <variable name="terminal_button_y" value="300" /> + <variable name="listbox_tz_height" value="159" /> + <variable name="row_dst_text_y" value="162" /> + <variable name="row_offset_text_y" value="184" /> + <variable name="row_offset_medium_y" value="206" /> + <variable name="tz_set_y" value="271" /> + <variable name="tz_current_y" value="249" /> + <variable name="system_ro_y" value="216" /> + <variable name="button_fill_color" value="#303030" /> + <variable name="button_fill_full_width" value="308" /> + <variable name="button_fill_main_width" value="150" /> + <variable name="button_fill_med_width" value="72" /> + <variable name="button_fill_small_width" value="36" /> + <variable name="button_fill_main_height" value="44" /> + <variable name="button_fill_half_height" value="22" /> + <variable name="button_fill_quarter_height" value="22" /> + <variable name="button_refresh_x" value="152" /> + <variable name="backup_list_y" value="26" /> + <variable name="backup_list_height" value="184" /> + <variable name="restore_list_height" value="206" /> + <variable name="backup_button_row1" value="214" /> + <variable name="backup_button_row2" value="242" /> + <variable name="mount_list_height" value="190" /> + <variable name="mount_storage_row" value="193" /> + <variable name="storage_list_height" value="134" /> + <variable name="wipe_list_height" value="216" /> + <variable name="wipe_button_y" value="170" /> + <variable name="slidervalue_w" value="308" /> + <variable name="slidervalue_line_clr" value="#FFFFFF" /> + <variable name="slidervalue_slider_clr" value="#33B5E5" /> + <variable name="slidervalue_lineh" value="1" /> + <variable name="slidervalue_padding" value="8" /> + <variable name="slidervalue_sliderw" value="4" /> + <variable name="slidervalue_sliderh" value="20" /> + <variable name="wipe_button_row1" value="240" /> + <variable name="invalid_partition_y" value="218" /> + <variable name="pattern_x" value="70" /> + <variable name="pattern_y" value="22" /> + <variable name="pattern_width" value="180" /> + <variable name="pattern_dot_color" value="#33B5E5" /> + <variable name="pattern_dot_color_active" value="#FFFFFF" /> + <variable name="pattern_dot_radius" value="7" /> + <variable name="pattern_line_color" value="#33B5E5" /> + <variable name="pattern_line_width" value="4" /> + </variables> + + <templates> + <template name="twrpheader"> + <object type="fill" color="%button_fill_color%"> + <placement x="0" y="0" w="320" h="26" /> + </object> + + <object type="fill" color="%highlight%"> + <placement x="0" y="26" w="320" h="1" /> + </object> + + <object type="image"> + <image resource="twrplogo" /> + <placement x="13" y="13" placement="4" /> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="25" y="3" /> + <text>TWRP v%tw_version%</text> + </object> + + <object type="text" color="%text_fail_color%"> + <condition var1="tw_simulate_actions" var2="1" /> + <font resource="font" /> + <placement x="25" y="21" /> + <text>SIMULATION</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="160" y="3" placement="5" /> + <text>%tw_time%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="316" y="3" placement="1" /> + <conditions> + <condition var1="tw_no_battery_percent" var2="0" /> + <condition var1="tw_battery" op=">" var2="0" /> + <condition var1="tw_battery" op="<" var2="101" /> + </conditions> + <text>%tw_battery%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="190" y="3" /> + <conditions> + <condition var1="tw_no_cpu_temp" var2="0" /> + </conditions> + <text>CPU: %tw_cpu_temp% C</text> + </object> + </template> + + <template name="header"> + <background color="#000000FF" /> + + <object type="button"> + <placement x="%home_button_x%" y="%home_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text></text> + <image resource="home_icon" /> + <condition var1="tw_busy" var2="0" /> + <action function="key">home</action> + </object> + + <object type="button"> + <placement x="%back_button_x%" y="%back_button_y%" placement="1" /> + <font resource="font" color="%button_text_color%" /> + <text></text> + <image resource="back_icon" /> + <condition var1="tw_busy" var2="0" /> + <action function="key">back</action> + </object> + + <object type="action"> + <touch key="power" /> + <action function="key">back</action> + </object> + + <object type="action"> + <touch key="power+voldown" /> + <action function="screenshot" /> + </object> + </template> + + <template name="progress_bar"> + <object type="progressbar"> + <placement x="%col_progressbar_x%" y="%row_progressbar_y%" /> + <resource empty="progress_empty" full="progress_full" /> + <data name="ui_progress" /> + </object> + + <object type="animation"> + <placement x="%col_progressbar_x%" y="%row_progressbar_y%" /> + <resource name="progress" /> + <speed fps="15" render="2" /> + <loop frame="1" /> + </object> + </template> + + <template name="action_page_console"> + <object type="console"> + <placement x="%console_x%" y="%row2_y%" w="%console_width%" h="%console_action_height%" /> + <color foreground="%console_foreground%" background="%console_background%" scroll="%console_scroll%" /> + <font resource="fixed" /> + </object> + </template> + + <template name="sort_options"> + <object type="text" color="%text_color%"> + <font resource="mediumfont" /> + <placement x="%sort_text_x%" y="%sort_asc_text_y%" /> + <text>Sort Ascending:</text> + </object> + + <object type="button"> + <placement x="%sort_col1_button_x%" y="%sort_asc_button_y%" /> + <font resource="mediumfont" color="%button_text_color%" /> + <text>Name</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=1</action> + </object> + + <object type="button"> + <placement x="%sort_col2_button_x%" y="%sort_asc_button_y%" /> + <font resource="mediumfont" color="%button_text_color%" /> + <text>Date</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=2</action> + </object> + + <object type="button"> + <placement x="%sort_col3_button_x%" y="%sort_asc_button_y%" /> + <font resource="mediumfont" color="%button_text_color%" /> + <text>Size</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=3</action> + </object> + + <object type="text" color="%text_color%"> + <font resource="mediumfont" /> + <placement x="%sort_text_x%" y="%sort_desc_text_y%" /> + <text>Sort Descending:</text> + </object> + + <object type="button"> + <placement x="%sort_col1_button_x%" y="%sort_desc_button_y%" /> + <font resource="mediumfont" color="%button_text_color%" /> + <text>Name</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=-1</action> + </object> + + <object type="button"> + <placement x="%sort_col2_button_x%" y="%sort_desc_button_y%" /> + <font resource="mediumfont" color="%button_text_color%" /> + <text>Date</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=-2</action> + </object> + + <object type="button"> + <placement x="%sort_col3_button_x%" y="%sort_desc_button_y%" /> + <font resource="mediumfont" color="%button_text_color%" /> + <text>Size</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=-3</action> + </object> + </template> + + <template name="footer"> + <object type="console"> + <slideout resource="slideout" x="%center_x%" y="288" placement="5" /> + <placement x="%console_x%" y="0" w="%console_width%" h="288" /> + <color foreground="%console_foreground%" background="%console_background%" scroll="%console_scroll%" /> + <font resource="fixed" /> + </object> + </template> + + <template name="keyboardtemplate"> + <object type="keyboard"> + <placement x="0" y="150" /> + <layout resource1="keyboard1" resource2="keyboard2" resource3="keyboard3" resource4="keyboard4" /> + <highlight color="%highlight_color%" /> + <capshighlight color="%caps_highlight_color%" /> + <layout1> + <keysize height="36" width="32" /> + <row1 key01="q" long01="1" key02="w" long02="2" key03="e" long03="3" key04="r" long04="4" key05="t" long05="5" key06="y" long06="6" key07="u" long07="7" key08="i" long08="8" key09="o" long09="9" key10="p" long10="0" /> + <row2 key01="48:a" key02="s" key03="d" key04="f" key05="g" key06="h" key07="j" key08="k" key09="48:l" /> + <row3 key01="48:layout2" key02="z" key03="x" key04="c" key05="v" key06="b" key07="n" key08="m" key09="48:c:8" /> + <row4 key01="48:layout3" key02="32:," key03="160: " key04="32:." key05="48:a:action" /> + </layout1> + <layout2> + <keysize height="36" width="32" capslock="0" revert_layout="1" /> + <row1 key01="Q" long01="1" key02="W" long02="2" key03="E" long03="3" key04="R" long04="4" key05="T" long05="5" key06="Y" long06="6" key07="U" long07="7" key08="I" long08="8" key09="O" long09="9" key10="P" long10="0" /> + <row2 key01="48:A" key02="S" key03="D" key04="F" key05="G" key06="H" key07="J" key08="K" key09="48:L" /> + <row3 key01="48:layout1" key02="Z" key03="X" key04="C" key05="V" key06="B" key07="N" key08="M" key09="48:c:8" /> + <row4 key01="48:layout3" key02="32:," key03="160: " key04="32:." key05="48:action" /> + </layout2> + <layout3> + <keysize height="36" width="32" /> + <row1 key01="1" key02="2" key03="3" key04="4" key05="5" key06="6" key07="7" key08="8" key09="9" key10="0" /> + <row2 key01="@" key02="#" key03="$" key04="%" key05="&" key06="*" key07="-" key08="+" key09="(" key10=")" /> + <row3 key01="48:layout4" key02="!" key03="32:c:34" key04="'" key05=":" key06=";" key07="/" key08="?" key09="48:c:8" /> + <row4 key01="48:layout1" key02="32:," key03="160: " key04="32:." key05="48:action" /> + </layout3> + <layout4> + <keysize height="36" width="32" /> + <row1 key01="~" key02="`" key03="|" key04="32:" key05="32:" key06="32:" key07="%" key08="32:" key09="{" key10="}" /> + <row2 key01="32:" key02="32:" key03="32:" key04="32:" key05="32:" key06="^" key07="_" key08="=" key09="[" key10="]" /> + <row3 key01="48:layout3" key02="32:" key03="32:" key04="32:" key05="32:" key06="\" key07="<" key08=">" key09="48:c:8" /> + <row4 key01="48:layout1" key02="32:c:34" key03="160: " key04="32:." key05="48:action" /> + </layout4> + </object> + </template> + </templates> +</recovery> diff --git a/gui/devices/480x800/res/fonts/Roboto-Regular-20.dat b/gui/devices/480x800/res/fonts/Roboto-Regular-20.dat Binary files differnew file mode 100644 index 000000000..6588b41e7 --- /dev/null +++ b/gui/devices/480x800/res/fonts/Roboto-Regular-20.dat diff --git a/gui/devices/480x800/res/images/back-icon.png b/gui/devices/480x800/res/images/back-icon.png Binary files differnew file mode 100644 index 000000000..688436eb2 --- /dev/null +++ b/gui/devices/480x800/res/images/back-icon.png diff --git a/gui/devices/480x800/res/images/checkbox_checked.png b/gui/devices/480x800/res/images/checkbox_checked.png Binary files differnew file mode 100644 index 000000000..3447349cf --- /dev/null +++ b/gui/devices/480x800/res/images/checkbox_checked.png diff --git a/gui/devices/480x800/res/images/checkbox_empty.png b/gui/devices/480x800/res/images/checkbox_empty.png Binary files differnew file mode 100644 index 000000000..f5f35d8d1 --- /dev/null +++ b/gui/devices/480x800/res/images/checkbox_empty.png diff --git a/gui/devices/480x800/res/images/cursor.png b/gui/devices/480x800/res/images/cursor.png Binary files differnew file mode 100644 index 000000000..32c8ae1ca --- /dev/null +++ b/gui/devices/480x800/res/images/cursor.png diff --git a/gui/devices/480x800/res/images/curtain.jpg b/gui/devices/480x800/res/images/curtain.jpg Binary files differnew file mode 100644 index 000000000..dfd59d96b --- /dev/null +++ b/gui/devices/480x800/res/images/curtain.jpg diff --git a/gui/devices/480x800/res/images/file.png b/gui/devices/480x800/res/images/file.png Binary files differnew file mode 100644 index 000000000..8556bc7fa --- /dev/null +++ b/gui/devices/480x800/res/images/file.png diff --git a/gui/devices/480x800/res/images/folder.png b/gui/devices/480x800/res/images/folder.png Binary files differnew file mode 100644 index 000000000..a3a5f69df --- /dev/null +++ b/gui/devices/480x800/res/images/folder.png diff --git a/gui/devices/480x800/res/images/home-icon.png b/gui/devices/480x800/res/images/home-icon.png Binary files differnew file mode 100644 index 000000000..551952015 --- /dev/null +++ b/gui/devices/480x800/res/images/home-icon.png diff --git a/gui/devices/480x800/res/images/indeterminate001.png b/gui/devices/480x800/res/images/indeterminate001.png Binary files differnew file mode 100644 index 000000000..e6fa1c574 --- /dev/null +++ b/gui/devices/480x800/res/images/indeterminate001.png diff --git a/gui/devices/480x800/res/images/indeterminate002.png b/gui/devices/480x800/res/images/indeterminate002.png Binary files differnew file mode 100644 index 000000000..e1fceaba1 --- /dev/null +++ b/gui/devices/480x800/res/images/indeterminate002.png diff --git a/gui/devices/480x800/res/images/indeterminate003.png b/gui/devices/480x800/res/images/indeterminate003.png Binary files differnew file mode 100644 index 000000000..670286743 --- /dev/null +++ b/gui/devices/480x800/res/images/indeterminate003.png diff --git a/gui/devices/480x800/res/images/indeterminate004.png b/gui/devices/480x800/res/images/indeterminate004.png Binary files differnew file mode 100644 index 000000000..ff65e0930 --- /dev/null +++ b/gui/devices/480x800/res/images/indeterminate004.png diff --git a/gui/devices/480x800/res/images/indeterminate005.png b/gui/devices/480x800/res/images/indeterminate005.png Binary files differnew file mode 100644 index 000000000..e61e2cc15 --- /dev/null +++ b/gui/devices/480x800/res/images/indeterminate005.png diff --git a/gui/devices/480x800/res/images/indeterminate006.png b/gui/devices/480x800/res/images/indeterminate006.png Binary files differnew file mode 100644 index 000000000..c9c21ba9c --- /dev/null +++ b/gui/devices/480x800/res/images/indeterminate006.png diff --git a/gui/devices/480x800/res/images/keyboard1.png b/gui/devices/480x800/res/images/keyboard1.png Binary files differnew file mode 100644 index 000000000..5a691ac02 --- /dev/null +++ b/gui/devices/480x800/res/images/keyboard1.png diff --git a/gui/devices/480x800/res/images/keyboard2.png b/gui/devices/480x800/res/images/keyboard2.png Binary files differnew file mode 100644 index 000000000..69b015458 --- /dev/null +++ b/gui/devices/480x800/res/images/keyboard2.png diff --git a/gui/devices/480x800/res/images/keyboard3.png b/gui/devices/480x800/res/images/keyboard3.png Binary files differnew file mode 100644 index 000000000..498cef84b --- /dev/null +++ b/gui/devices/480x800/res/images/keyboard3.png diff --git a/gui/devices/480x800/res/images/keyboard4.png b/gui/devices/480x800/res/images/keyboard4.png Binary files differnew file mode 100644 index 000000000..e8f9dde0e --- /dev/null +++ b/gui/devices/480x800/res/images/keyboard4.png diff --git a/gui/devices/480x800/res/images/medium-button.png b/gui/devices/480x800/res/images/medium-button.png Binary files differnew file mode 100644 index 000000000..1d5b816ec --- /dev/null +++ b/gui/devices/480x800/res/images/medium-button.png diff --git a/gui/devices/480x800/res/images/menu-button.png b/gui/devices/480x800/res/images/menu-button.png Binary files differnew file mode 100644 index 000000000..c8d3794e5 --- /dev/null +++ b/gui/devices/480x800/res/images/menu-button.png diff --git a/gui/devices/480x800/res/images/minus-button.png b/gui/devices/480x800/res/images/minus-button.png Binary files differnew file mode 100644 index 000000000..9c92d2f46 --- /dev/null +++ b/gui/devices/480x800/res/images/minus-button.png diff --git a/gui/devices/480x800/res/images/plus-button.png b/gui/devices/480x800/res/images/plus-button.png Binary files differnew file mode 100644 index 000000000..5d3068ed9 --- /dev/null +++ b/gui/devices/480x800/res/images/plus-button.png diff --git a/gui/devices/480x800/res/images/progress_empty.png b/gui/devices/480x800/res/images/progress_empty.png Binary files differnew file mode 100644 index 000000000..b85371014 --- /dev/null +++ b/gui/devices/480x800/res/images/progress_empty.png diff --git a/gui/devices/480x800/res/images/progress_fill.png b/gui/devices/480x800/res/images/progress_fill.png Binary files differnew file mode 100644 index 000000000..669c6efa9 --- /dev/null +++ b/gui/devices/480x800/res/images/progress_fill.png diff --git a/gui/devices/480x800/res/images/radio_empty.png b/gui/devices/480x800/res/images/radio_empty.png Binary files differnew file mode 100644 index 000000000..88d1c1f5e --- /dev/null +++ b/gui/devices/480x800/res/images/radio_empty.png diff --git a/gui/devices/480x800/res/images/radio_selected.png b/gui/devices/480x800/res/images/radio_selected.png Binary files differnew file mode 100644 index 000000000..864065dea --- /dev/null +++ b/gui/devices/480x800/res/images/radio_selected.png diff --git a/gui/devices/480x800/res/images/slideout.png b/gui/devices/480x800/res/images/slideout.png Binary files differnew file mode 100644 index 000000000..963b9fdba --- /dev/null +++ b/gui/devices/480x800/res/images/slideout.png diff --git a/gui/devices/480x800/res/images/slider-touch.png b/gui/devices/480x800/res/images/slider-touch.png Binary files differnew file mode 100644 index 000000000..c8c0f43c3 --- /dev/null +++ b/gui/devices/480x800/res/images/slider-touch.png diff --git a/gui/devices/480x800/res/images/slider-used.png b/gui/devices/480x800/res/images/slider-used.png Binary files differnew file mode 100644 index 000000000..2f3d51969 --- /dev/null +++ b/gui/devices/480x800/res/images/slider-used.png diff --git a/gui/devices/480x800/res/images/slider.png b/gui/devices/480x800/res/images/slider.png Binary files differnew file mode 100644 index 000000000..6fcce6f5b --- /dev/null +++ b/gui/devices/480x800/res/images/slider.png diff --git a/gui/devices/480x800/res/images/sort-button.png b/gui/devices/480x800/res/images/sort-button.png Binary files differnew file mode 100644 index 000000000..69d511bea --- /dev/null +++ b/gui/devices/480x800/res/images/sort-button.png diff --git a/gui/devices/480x800/res/images/twrplogo.png b/gui/devices/480x800/res/images/twrplogo.png Binary files differnew file mode 100644 index 000000000..4b39da89b --- /dev/null +++ b/gui/devices/480x800/res/images/twrplogo.png diff --git a/gui/devices/480x800/res/images/unlock.png b/gui/devices/480x800/res/images/unlock.png Binary files differnew file mode 100644 index 000000000..904122120 --- /dev/null +++ b/gui/devices/480x800/res/images/unlock.png diff --git a/gui/devices/480x800/res/ui.xml b/gui/devices/480x800/res/ui.xml new file mode 100644 index 000000000..341332f83 --- /dev/null +++ b/gui/devices/480x800/res/ui.xml @@ -0,0 +1,430 @@ +<?xml version="1.0"?> + +<recovery> + <details> + <resolution width="480" height="800" /> + <author>TeamWin</author> + <title>Backup Naowz</title> + <description>Default basic theme</description> + <preview>preview.jpg</preview> + </details> + + <include> + <xmlfile name="portrait.xml" /> + </include> + + <resources> + <resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="20" fallback="Roboto-Regular-20" /> + <resource name="mediumfont" type="font" filename="RobotoCondensed-Regular.ttf" size="20" fallback="Roboto-Regular-20" /> + <resource name="filelist" type="font" filename="RobotoCondensed-Regular.ttf" size="20" fallback="Roboto-Regular-20" /> + <resource name="fixed" type="font" filename="DroidSansMono.ttf" size="16" /> + <resource name="twrplogo" type="image" filename="twrplogo" retainaspect="1" /> + <resource name="main_button" type="image" filename="menu-button" /> + <resource name="file_icon" type="image" filename="file" retainaspect="1" /> + <resource name="folder_icon" type="image" filename="folder" retainaspect="1" /> + <resource name="slideout" type="image" filename="slideout" retainaspect="1" /> + <resource name="progress" type="animation" filename="indeterminate" /> + <resource name="progress_empty" type="image" filename="progress_empty" /> + <resource name="progress_full" type="image" filename="progress_fill" /> + <resource name="checkbox_false" type="image" filename="checkbox_empty" retainaspect="1" /> + <resource name="checkbox_true" type="image" filename="checkbox_checked" retainaspect="1" /> + <resource name="radio_false" type="image" filename="radio_empty" retainaspect="1" /> + <resource name="radio_true" type="image" filename="radio_selected" retainaspect="1" /> + <resource name="medium_button" type="image" filename="medium-button" /> + <resource name="sort_button" type="image" filename="sort-button" /> + <resource name="minus_button" type="image" filename="minus-button" /> + <resource name="plus_button" type="image" filename="plus-button" /> + <resource name="home_icon" type="image" filename="home-icon" retainaspect="1" /> + <resource name="back_icon" type="image" filename="back-icon" retainaspect="1" /> + <resource name="slider" type="image" filename="slider" retainaspect="1" /> + <resource name="slider-used" type="image" filename="slider-used" retainaspect="1" /> + <resource name="slider-touch" type="image" filename="slider-touch" retainaspect="1" /> + <resource name="unlock-icon" type="image" filename="unlock" retainaspect="1" /> + <resource name="keyboard1" type="image" filename="keyboard1" /> + <resource name="keyboard2" type="image" filename="keyboard2" /> + <resource name="keyboard3" type="image" filename="keyboard3" /> + <resource name="keyboard4" type="image" filename="keyboard4" /> + <resource name="cursor" type="image" filename="cursor" retainaspect="1" /> + </resources> + + <variables> + <variable name="col1_x" value="10" /> + <variable name="col2_x" value="240" /> + <variable name="col_center_x" value="128" /> + <variable name="col_center_medium_x" value="183" /> + <variable name="center_x" value="240" /> + <variable name="row1_y" value="140" /> + <variable name="row2_y" value="290" /> + <variable name="row3_y" value="450" /> + <variable name="row4_y" value="610" /> + <variable name="row_queue_y" value="510" /> + <variable name="row1_header_y" value="110" /> + <variable name="row1_text_y" value="140" /> + <variable name="row2_text_y" value="170" /> + <variable name="row3_text_y" value="200" /> + <variable name="row4_text_y" value="230" /> + <variable name="row5_text_y" value="260" /> + <variable name="row6_text_y" value="290" /> + <variable name="row7_text_y" value="320" /> + <variable name="row8_text_y" value="350" /> + <variable name="row9_text_y" value="380" /> + <variable name="row10_text_y" value="410" /> + <variable name="row11_text_y" value="440" /> + <variable name="row12_text_y" value="470" /> + <variable name="row13_text_y" value="500" /> + <variable name="row14_text_y" value="530" /> + <variable name="row15_text_y" value="560" /> + <variable name="row16_text_y" value="590" /> + <variable name="row17_text_y" value="620" /> + <variable name="row18_text_y" value="650" /> + <variable name="zip_status_y" value="585" /> + <variable name="flash_list_height" value="210" /> + <variable name="tz_selected_y" value="110" /> + <variable name="tz_set_y" value="580" /> + <variable name="tz_current_y" value="730" /> + <variable name="system_ro_y" value="550" /> + <variable name="col_progressbar_x" value="114" /> + <variable name="row_progressbar_y" value="720" /> + <variable name="col1_medium_x" value="10" /> + <variable name="col2_medium_x" value="125" /> + <variable name="col3_medium_x" value="240" /> + <variable name="col4_medium_x" value="355" /> + <variable name="row1_medium_y" value="130" /> + <variable name="row2_medium_y" value="205" /> + <variable name="row3_medium_y" value="280" /> + <variable name="row4_medium_y" value="355" /> + <variable name="row5_medium_y" value="430" /> + <variable name="row6_medium_y" value="505" /> + <variable name="row7_medium_y" value="580" /> + <variable name="slider_y" value="680" /> + <variable name="slider_text_y" value="721" /> + <variable name="button_text_color" value="#AAAAAA" /> + <variable name="text_color" value="#FFFFFF" /> + <variable name="text_success_color" value="#33B5E5" /> + <variable name="text_fail_color" value="#FF0101" /> + <variable name="highlight_color" value="#90909080" /> + <variable name="caps_highlight_color" value="#33B5E580" /> + <variable name="home_button_x" value="10" /> + <variable name="home_button_y" value="766" /> + <variable name="back_button_x" value="470" /> + <variable name="back_button_y" value="766" /> + <variable name="sort_asc_text_y" value="685" /> + <variable name="sort_asc_button_y" value="685" /> + <variable name="sort_desc_text_y" value="725" /> + <variable name="sort_desc_button_y" value="725" /> + <variable name="sort_col1_button_x" value="180" /> + <variable name="sort_col2_button_x" value="240" /> + <variable name="sort_col3_button_x" value="300" /> + <variable name="input_width" value="460" /> + <variable name="input_height" value="40" /> + <variable name="input_background_color" value="#303030" /> + <variable name="input_cursor_color" value="#33B5E5" /> + <variable name="input_cursor_width" value="3" /> + <variable name="console_x" value="0" /> + <variable name="console_width" value="480" /> + <variable name="console_foreground" value="#A0A0A0" /> + <variable name="warning" value="#F8F8A0" /> + <variable name="error" value="#FF4040" /> + <variable name="highlight" value="#33B5E5" /> + <variable name="console_background" value="#303030" /> + <variable name="console_scroll" value="#303030" /> + <variable name="console_action_height" value="320" /> + <variable name="console_install_height" value="440" /> + <variable name="console_installdone_height" value="300" /> + <variable name="fileselector_x" value="5" /> + <variable name="fileselector_width" value="470" /> + <variable name="fileselector_install_height" value="480" /> + <variable name="fileselector_header_background" value="#202020" /> + <variable name="fileselector_header_textcolor" value="#AAAAAA" /> + <variable name="fileselector_header_separatorcolor" value="#33B5E5" /> + <variable name="fileselector_header_separatorheight" value="3" /> + <variable name="fileselector_separatorcolor" value="#505050" /> + <variable name="fileselector_separatorheight" value="2" /> + <variable name="fileselector_background" value="#303030" /> + <variable name="fileselector_highlight_color" value="#505050" /> + <variable name="fileselector_highlight_font_color" value="#33B5E5" /> + <variable name="fileselector_spacing" value="18" /> + <variable name="fastscroll_linecolor" value="#50505080" /> + <variable name="fastscroll_rectcolor" value="#33B5E580" /> + <variable name="fastscroll_w" value="40" /> + <variable name="fastscroll_linew" value="2" /> + <variable name="fastscroll_rectw" value="10" /> + <variable name="fastscroll_recth" value="30" /> + <variable name="listbox_x" value="5" /> + <variable name="listbox_width" value="470" /> + <variable name="listbox_tz_height" value="310" /> + <variable name="listbox_background" value="#303030" /> + <variable name="listbox_spacing" value="18" /> + <variable name="sd_plus_x" value="280" /> + <variable name="sdext_text_x" value="84" /> + <variable name="sdext_text_y" value="145" /> + <variable name="sdswap_button_y" value="185" /> + <variable name="sdswap_text_x" value="84" /> + <variable name="sdswap_text_y" value="190" /> + <variable name="sdfilesystem_text_y" value="240" /> + <variable name="sdfilesystem_button_y" value="280" /> + <variable name="lock_y" value="250" /> + <variable name="filemanager_select_x" value="365" /> + <variable name="filemanager_select_y" value="690" /> + <variable name="backup_name_y" value="350" /> + <variable name="terminal_console_height" value="370" /> + <variable name="terminal_text_y" value="390" /> + <variable name="terminal_button_y" value="380" /> + <variable name="row_dst_text_y" value="440" /> + <variable name="row_offset_text_y" value="480" /> + <variable name="row_offset_medium_y" value="505" /> + <variable name="button_fill_color" value="#303030" /> + <variable name="button_fill_full_width" value="455" /> + <variable name="button_fill_main_width" value="225" /> + <variable name="button_fill_main_height" value="135" /> + <variable name="button_fill_half_height" value="67" /> + <variable name="button_fill_quarter_height" value="34" /> + <variable name="backup_list_height" value="300" /> + <variable name="backup_button_row1" value="480" /> + <variable name="backup_button_row2" value="520" /> + <variable name="mount_list_height" value="380" /> + <variable name="mount_storage_row" value="500" /> + <variable name="storage_list_height" value="400" /> + <variable name="wipe_list_height" value="460" /> + <variable name="wipe_button_row1" value="600" /> + <variable name="wipe_button_y" value="400" /> + <variable name="slidervalue_w" value="460" /> + <variable name="slidervalue_line_clr" value="#FFFFFF" /> + <variable name="slidervalue_slider_clr" value="#33B5E5" /> + <variable name="slidervalue_lineh" value="1" /> + <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_y" value="250" /> + <variable name="pattern_width" value="300" /> + <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" /> + </variables> + + <mousecursor> + <placement w="15" h="15" /> + <background color="#FFFF00FF" resource="cursor" /> + <speed multiplier="1.5" /> + </mousecursor> + + <templates> + <template name="header"> + <background color="#000000FF" /> + + <object type="fill" color="%button_fill_color%"> + <placement x="0" y="0" w="480" h="98" /> + </object> + + <object type="fill" color="%highlight%"> + <placement x="0" y="98" w="480" h="2" /> + </object> + + <object type="image"> + <image resource="twrplogo" /> + <placement x="50" y="50" placement="4" /> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="100" y="10" /> + <text>Team Win Recovery Project v%tw_version%</text> + </object> + + <object type="text" color="%text_color%"> + <condition var1="tw_simulate_actions" var2="1" /> + <font resource="font" /> + <placement x="100" y="40" /> + <text>SIMULATING ACTIONS</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="100" y="70" /> + <text>%tw_time%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="190" y="70" /> + <conditions> + <condition var1="tw_no_battery_percent" var2="0" /> + <condition var1="tw_battery" op=">" var2="0" /> + <condition var1="tw_battery" op="<" var2="101" /> + </conditions> + <text>Battery: %tw_battery%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="350" y="70" /> + <conditions> + <condition var1="tw_no_cpu_temp" var2="0" /> + </conditions> + <text>CPU: %tw_cpu_temp% C</text> + </object> + + <object type="button"> + <placement x="%home_button_x%" y="%home_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text></text> + <image resource="home_icon" /> + <condition var1="tw_busy" var2="0" /> + <action function="key">home</action> + </object> + + <object type="button"> + <placement x="%back_button_x%" y="%back_button_y%" placement="1" /> + <font resource="font" color="%button_text_color%" /> + <text></text> + <image resource="back_icon" /> + <condition var1="tw_busy" var2="0" /> + <action function="key">back</action> + </object> + + <object type="action"> + <touch key="power" /> + <action function="overlay">lock</action> + </object> + + <object type="action"> + <touch key="power+voldown" /> + <action function="screenshot" /> + </object> + </template> + + <template name="progress_bar"> + <object type="progressbar"> + <placement x="%col_progressbar_x%" y="%row_progressbar_y%" /> + <resource empty="progress_empty" full="progress_full" /> + <data name="ui_progress" /> + </object> + + <object type="animation"> + <placement x="%col_progressbar_x%" y="%row_progressbar_y%" /> + <resource name="progress" /> + <speed fps="15" render="2" /> + <loop frame="1" /> + </object> + </template> + + <template name="action_page_console"> + <object type="console"> + <placement x="%console_x%" y="%row2_y%" w="%console_width%" h="%console_action_height%" /> + <color foreground="%console_foreground%" background="%console_background%" scroll="%console_scroll%" /> + <font resource="fixed" /> + </object> + </template> + + <template name="sort_options"> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%col1_x%" y="%sort_asc_text_y%" /> + <text>Sort Ascending:</text> + </object> + + <object type="button"> + <placement x="%sort_col1_button_x%" y="%sort_asc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Name</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=1</action> + </object> + + <object type="button"> + <placement x="%sort_col2_button_x%" y="%sort_asc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Date</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=2</action> + </object> + + <object type="button"> + <placement x="%sort_col3_button_x%" y="%sort_asc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Size</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=3</action> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%col1_x%" y="%sort_desc_text_y%" /> + <text>Sort Descending:</text> + </object> + + <object type="button"> + <placement x="%sort_col1_button_x%" y="%sort_desc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Name</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=-1</action> + </object> + + <object type="button"> + <placement x="%sort_col2_button_x%" y="%sort_desc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Date</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=-2</action> + </object> + + <object type="button"> + <placement x="%sort_col3_button_x%" y="%sort_desc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Size</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=-3</action> + </object> + </template> + + <template name="footer"> + <object type="console"> + <slideout resource="slideout" x="%center_x%" y="760" placement="5" /> + <placement x="%console_x%" y="0" w="%console_width%" h="760" /> + <color foreground="%console_foreground%" background="%console_background%" scroll="%console_scroll%" /> + <font resource="fixed" /> + </object> + </template> + + <template name="keyboardtemplate"> + <object type="keyboard"> + <placement x="0" y="450" /> + <layout resource1="keyboard1" resource2="keyboard2" resource3="keyboard3" resource4="keyboard4" /> + <highlight color="%highlight_color%" /> + <capshighlight color="%caps_highlight_color%" /> + <layout1> + <keysize height="78" width="48" /> + <row1 key01="q" long01="1" key02="w" long02="2" key03="e" long03="3" key04="r" long04="4" key05="t" long05="5" key06="y" long06="6" key07="u" long07="7" key08="i" long08="8" key09="o" long09="9" key10="p" long10="0" /> + <row2 key01="72:a" key02="s" key03="d" key04="f" key05="g" key06="h" key07="j" key08="k" key09="72:l" /> + <row3 key01="72:layout2" key02="z" key03="x" key04="c" key05="v" key06="b" key07="n" key08="m" key09="72:c:8" /> + <row4 key01="72:layout3" key02="48:" key03="240: " key04="48:." key05="72:a:action" /> + </layout1> + <layout2> + <keysize height="78" width="48" capslock="0" revert_layout="1" /> + <row1 key01="Q" long01="1" key02="W" long02="2" key03="E" long03="3" key04="R" long04="4" key05="T" long05="5" key06="Y" long06="6" key07="U" long07="7" key08="I" long08="8" key09="O" long09="9" key10="P" long10="0" /> + <row2 key01="72:A" key02="S" key03="D" key04="F" key05="G" key06="H" key07="J" key08="K" key09="72:L" /> + <row3 key01="72:layout1" key02="Z" key03="X" key04="C" key05="V" key06="B" key07="N" key08="M" key09="72:c:8" /> + <row4 key01="72:layout3" key02="48:" key03="240: " key04="48:." key05="72:action" /> + </layout2> + <layout3> + <keysize height="78" width="48" /> + <row1 key01="1" key02="2" key03="3" key04="4" key05="5" key06="6" key07="7" key08="8" key09="9" key10="0" /> + <row2 key01="@" key02="#" key03="$" key04="%" key05="&" key06="*" key07="-" key08="+" key09="(" key10=")" /> + <row3 key01="72:layout4" key02="!" key03="48:c:34" key04="'" key05=":" key06=";" key07="/" key08="?" key09="72:c:8" /> + <row4 key01="72:layout1" key02="48:," key03="240: " key04="48:." key05="72:action" /> + </layout3> + <layout4> + <keysize height="78" width="48" /> + <row1 key01="~" key02="`" key03="|" key04="48:" key05="48:" key06="48:" key07="%" key08="48:" key09="{" key10="}" /> + <row2 key01="48:" key02="48:" key03="48:" key04="48:" key05="48:" key06="^" key07="_" key08="=" key09="[" key10="]" /> + <row3 key01="72:layout3" key02="48:" key03="48:" key04="48:" key05="48:" key06="\" key07="<" key08=">" key09="72:c:8" /> + <row4 key01="72:layout1" key02="48:c:34" key03="240: " key04="48:." key05="72:action" /> + </layout4> + </object> + </template> + </templates> +</recovery> diff --git a/gui/devices/800x480/res/fonts/Roboto-Condensed-16.dat b/gui/devices/800x480/res/fonts/Roboto-Condensed-16.dat Binary files differnew file mode 100644 index 000000000..19c11470d --- /dev/null +++ b/gui/devices/800x480/res/fonts/Roboto-Condensed-16.dat diff --git a/gui/devices/800x480/res/images/back-icon.png b/gui/devices/800x480/res/images/back-icon.png Binary files differnew file mode 100644 index 000000000..1096c9090 --- /dev/null +++ b/gui/devices/800x480/res/images/back-icon.png diff --git a/gui/devices/800x480/res/images/button.png b/gui/devices/800x480/res/images/button.png Binary files differnew file mode 100644 index 000000000..49b878498 --- /dev/null +++ b/gui/devices/800x480/res/images/button.png diff --git a/gui/devices/800x480/res/images/checkbox_checked.png b/gui/devices/800x480/res/images/checkbox_checked.png Binary files differnew file mode 100644 index 000000000..3759b7fd9 --- /dev/null +++ b/gui/devices/800x480/res/images/checkbox_checked.png diff --git a/gui/devices/800x480/res/images/checkbox_empty.png b/gui/devices/800x480/res/images/checkbox_empty.png Binary files differnew file mode 100644 index 000000000..43a640427 --- /dev/null +++ b/gui/devices/800x480/res/images/checkbox_empty.png diff --git a/gui/devices/800x480/res/images/console-icon.png b/gui/devices/800x480/res/images/console-icon.png Binary files differnew file mode 100644 index 000000000..91a727d40 --- /dev/null +++ b/gui/devices/800x480/res/images/console-icon.png diff --git a/gui/devices/800x480/res/images/console-toggle.png b/gui/devices/800x480/res/images/console-toggle.png Binary files differnew file mode 100644 index 000000000..963b9fdba --- /dev/null +++ b/gui/devices/800x480/res/images/console-toggle.png diff --git a/gui/devices/800x480/res/images/cursor.png b/gui/devices/800x480/res/images/cursor.png Binary files differnew file mode 100644 index 000000000..32c8ae1ca --- /dev/null +++ b/gui/devices/800x480/res/images/cursor.png diff --git a/gui/devices/800x480/res/images/curtain.jpg b/gui/devices/800x480/res/images/curtain.jpg Binary files differnew file mode 100644 index 000000000..1f03eb5e5 --- /dev/null +++ b/gui/devices/800x480/res/images/curtain.jpg diff --git a/gui/devices/800x480/res/images/file.png b/gui/devices/800x480/res/images/file.png Binary files differnew file mode 100644 index 000000000..8556bc7fa --- /dev/null +++ b/gui/devices/800x480/res/images/file.png diff --git a/gui/devices/800x480/res/images/folder.png b/gui/devices/800x480/res/images/folder.png Binary files differnew file mode 100644 index 000000000..a3a5f69df --- /dev/null +++ b/gui/devices/800x480/res/images/folder.png diff --git a/gui/devices/800x480/res/images/home-icon.png b/gui/devices/800x480/res/images/home-icon.png Binary files differnew file mode 100644 index 000000000..e42d774b1 --- /dev/null +++ b/gui/devices/800x480/res/images/home-icon.png diff --git a/gui/devices/800x480/res/images/indeterminate001.png b/gui/devices/800x480/res/images/indeterminate001.png Binary files differnew file mode 100755 index 000000000..e6fa1c574 --- /dev/null +++ b/gui/devices/800x480/res/images/indeterminate001.png diff --git a/gui/devices/800x480/res/images/indeterminate002.png b/gui/devices/800x480/res/images/indeterminate002.png Binary files differnew file mode 100755 index 000000000..e1fceaba1 --- /dev/null +++ b/gui/devices/800x480/res/images/indeterminate002.png diff --git a/gui/devices/800x480/res/images/indeterminate003.png b/gui/devices/800x480/res/images/indeterminate003.png Binary files differnew file mode 100755 index 000000000..670286743 --- /dev/null +++ b/gui/devices/800x480/res/images/indeterminate003.png diff --git a/gui/devices/800x480/res/images/indeterminate004.png b/gui/devices/800x480/res/images/indeterminate004.png Binary files differnew file mode 100755 index 000000000..ff65e0930 --- /dev/null +++ b/gui/devices/800x480/res/images/indeterminate004.png diff --git a/gui/devices/800x480/res/images/indeterminate005.png b/gui/devices/800x480/res/images/indeterminate005.png Binary files differnew file mode 100755 index 000000000..e61e2cc15 --- /dev/null +++ b/gui/devices/800x480/res/images/indeterminate005.png diff --git a/gui/devices/800x480/res/images/indeterminate006.png b/gui/devices/800x480/res/images/indeterminate006.png Binary files differnew file mode 100755 index 000000000..c9c21ba9c --- /dev/null +++ b/gui/devices/800x480/res/images/indeterminate006.png diff --git a/gui/devices/800x480/res/images/keyboard1.png b/gui/devices/800x480/res/images/keyboard1.png Binary files differnew file mode 100644 index 000000000..1ccb64bb4 --- /dev/null +++ b/gui/devices/800x480/res/images/keyboard1.png diff --git a/gui/devices/800x480/res/images/keyboard2.png b/gui/devices/800x480/res/images/keyboard2.png Binary files differnew file mode 100644 index 000000000..f19eaccab --- /dev/null +++ b/gui/devices/800x480/res/images/keyboard2.png diff --git a/gui/devices/800x480/res/images/keyboard3.png b/gui/devices/800x480/res/images/keyboard3.png Binary files differnew file mode 100644 index 000000000..022086064 --- /dev/null +++ b/gui/devices/800x480/res/images/keyboard3.png diff --git a/gui/devices/800x480/res/images/keyboard4.png b/gui/devices/800x480/res/images/keyboard4.png Binary files differnew file mode 100644 index 000000000..7fc0ea50f --- /dev/null +++ b/gui/devices/800x480/res/images/keyboard4.png diff --git a/gui/devices/800x480/res/images/medium-button.png b/gui/devices/800x480/res/images/medium-button.png Binary files differnew file mode 100644 index 000000000..77dc54072 --- /dev/null +++ b/gui/devices/800x480/res/images/medium-button.png diff --git a/gui/devices/800x480/res/images/mediumwide-button.png b/gui/devices/800x480/res/images/mediumwide-button.png Binary files differnew file mode 100644 index 000000000..b2b7d4de9 --- /dev/null +++ b/gui/devices/800x480/res/images/mediumwide-button.png diff --git a/gui/devices/800x480/res/images/minus-button.png b/gui/devices/800x480/res/images/minus-button.png Binary files differnew file mode 100644 index 000000000..5a49c758e --- /dev/null +++ b/gui/devices/800x480/res/images/minus-button.png diff --git a/gui/devices/800x480/res/images/plus-button.png b/gui/devices/800x480/res/images/plus-button.png Binary files differnew file mode 100644 index 000000000..da1326c92 --- /dev/null +++ b/gui/devices/800x480/res/images/plus-button.png diff --git a/gui/devices/800x480/res/images/progress_empty.png b/gui/devices/800x480/res/images/progress_empty.png Binary files differnew file mode 100644 index 000000000..b85371014 --- /dev/null +++ b/gui/devices/800x480/res/images/progress_empty.png diff --git a/gui/devices/800x480/res/images/progress_fill.png b/gui/devices/800x480/res/images/progress_fill.png Binary files differnew file mode 100644 index 000000000..669c6efa9 --- /dev/null +++ b/gui/devices/800x480/res/images/progress_fill.png diff --git a/gui/devices/800x480/res/images/radio_empty.png b/gui/devices/800x480/res/images/radio_empty.png Binary files differnew file mode 100644 index 000000000..d118aaf8b --- /dev/null +++ b/gui/devices/800x480/res/images/radio_empty.png diff --git a/gui/devices/800x480/res/images/radio_selected.png b/gui/devices/800x480/res/images/radio_selected.png Binary files differnew file mode 100644 index 000000000..5a8a0fd55 --- /dev/null +++ b/gui/devices/800x480/res/images/radio_selected.png diff --git a/gui/devices/800x480/res/images/slider-touch.png b/gui/devices/800x480/res/images/slider-touch.png Binary files differnew file mode 100644 index 000000000..dee19eec2 --- /dev/null +++ b/gui/devices/800x480/res/images/slider-touch.png diff --git a/gui/devices/800x480/res/images/slider-used.png b/gui/devices/800x480/res/images/slider-used.png Binary files differnew file mode 100644 index 000000000..754395a21 --- /dev/null +++ b/gui/devices/800x480/res/images/slider-used.png diff --git a/gui/devices/800x480/res/images/slider.png b/gui/devices/800x480/res/images/slider.png Binary files differnew file mode 100644 index 000000000..b0cc079eb --- /dev/null +++ b/gui/devices/800x480/res/images/slider.png diff --git a/gui/devices/800x480/res/images/sort-button.png b/gui/devices/800x480/res/images/sort-button.png Binary files differnew file mode 100644 index 000000000..13ab929de --- /dev/null +++ b/gui/devices/800x480/res/images/sort-button.png diff --git a/gui/devices/800x480/res/images/twrplogo.png b/gui/devices/800x480/res/images/twrplogo.png Binary files differnew file mode 100644 index 000000000..309012fc4 --- /dev/null +++ b/gui/devices/800x480/res/images/twrplogo.png diff --git a/gui/devices/800x480/res/images/unlock.png b/gui/devices/800x480/res/images/unlock.png Binary files differnew file mode 100644 index 000000000..914c60d20 --- /dev/null +++ b/gui/devices/800x480/res/images/unlock.png diff --git a/gui/devices/800x480/res/ui.xml b/gui/devices/800x480/res/ui.xml new file mode 100644 index 000000000..12e0ee702 --- /dev/null +++ b/gui/devices/800x480/res/ui.xml @@ -0,0 +1,465 @@ +<?xml version="1.0"?> + +<recovery> + <details> + <resolution width="800" height="480" /> + <author>TeamWin</author> + <title>Backup Naowz</title> + <description>Default basic theme</description> + <preview>preview.jpg</preview> + </details> + + <include> + <xmlfile name="landscape.xml" /> + </include> + + <resources> + <resource name="font" type="font" filename="RobotoCondensed-Regular.ttf" size="16" fallback="Roboto-Condensed-16" /> + <resource name="fixed" type="font" filename="DroidSansMono.ttf" size="12" /> + <resource name="twrplogo" type="image" filename="twrplogo" retainaspect="1" /> + <resource name="main_button" type="image" filename="button" /> + <resource name="file_icon" type="image" filename="file" retainaspect="1" /> + <resource name="folder_icon" type="image" filename="folder" retainaspect="1" /> + <resource name="progress" type="animation" filename="indeterminate" /> + <resource name="progress_empty" type="image" filename="progress_empty" /> + <resource name="progress_full" type="image" filename="progress_fill" /> + <resource name="checkbox_false" type="image" filename="checkbox_empty" retainaspect="1" /> + <resource name="checkbox_true" type="image" filename="checkbox_checked" retainaspect="1" /> + <resource name="radio_false" type="image" filename="radio_empty" retainaspect="1" /> + <resource name="radio_true" type="image" filename="radio_selected" retainaspect="1" /> + <resource name="medium_button" type="image" filename="medium-button" /> + <resource name="mediumwide_button" type="image" filename="mediumwide-button" /> + <resource name="sort_button" type="image" filename="sort-button" /> + <resource name="minus_button" type="image" filename="minus-button" /> + <resource name="plus_button" type="image" filename="plus-button" /> + <resource name="home_icon" type="image" filename="home-icon" retainaspect="1" /> + <resource name="back_icon" type="image" filename="back-icon" retainaspect="1" /> + <resource name="console_button" type="image" filename="console-toggle" retainaspect="1" /> + <resource name="slider" type="image" filename="slider" retainaspect="1" /> + <resource name="slider-used" type="image" filename="slider-used" retainaspect="1" /> + <resource name="slider-touch" type="image" filename="slider-touch" retainaspect="1" /> + <resource name="unlock-icon" type="image" filename="unlock" retainaspect="1" /> + <resource name="keyboard1" type="image" filename="keyboard1" /> + <resource name="keyboard2" type="image" filename="keyboard2" /> + <resource name="keyboard3" type="image" filename="keyboard3" /> + <resource name="keyboard4" type="image" filename="keyboard4" /> + <resource name="cursor" type="image" filename="cursor" retainaspect="1" /> + </resources> + + <variables> + <variable name="col1_x" value="23" /> + <variable name="col2_x" value="210" /> + <variable name="col3_x" value="410" /> + <variable name="col4_x" value="610" /> + <variable name="row1_y" value="90" /> + <variable name="row2_y" value="340" /> + <variable name="col_center_x" value="310" /> + <variable name="center_x" value="400" /> + <variable name="screen_width" value="800" /> + <variable name="screen_height" value="480" /> + <variable name="col_progressbar_x" value="300" /> + <variable name="row_progressbar_y" value="440" /> + <variable name="col1_medium_x" value="120" /> + <variable name="col2_medium_x" value="250" /> + <variable name="col3_medium_x" value="380" /> + <variable name="col4_medium_x" value="510" /> + <variable name="row1_medium_y" value="105" /> + <variable name="row2_medium_y" value="175" /> + <variable name="row3_medium_y" value="245" /> + <variable name="row4_medium_y" value="340" /> + <variable name="row5_medium_y" value="320" /> + <variable name="row1_text_y" value="58" /> + <variable name="row2_text_y" value="78" /> + <variable name="row3_text_y" value="100" /> + <variable name="row4_text_y" value="120" /> + <variable name="row5_text_y" value="140" /> + <variable name="row6_text_y" value="160" /> + <variable name="row7_text_y" value="180" /> + <variable name="row8_text_y" value="200" /> + <variable name="row9_text_y" value="220" /> + <variable name="row10_text_y" value="240" /> + <variable name="row11_text_y" value="260" /> + <variable name="row12_text_y" value="280" /> + <variable name="row13_text_y" value="300" /> + <variable name="row14_text_y" value="320" /> + <variable name="row15_text_y" value="340" /> + <variable name="row16_text_y" value="360" /> + <variable name="row17_text_y" value="380" /> + <variable name="row18_text_y" value="400" /> + <variable name="row_offsetmedium_y" value="320" /> + <variable name="home_button_x" value="589" /> + <variable name="home_button_y" value="5" /> + <variable name="back_button_x" value="659" /> + <variable name="back_button_y" value="5" /> + <variable name="console_button_x" value="729" /> + <variable name="console_button_y" value="5" /> + <variable name="nandcheck_col1" value="23" /> + <variable name="nandcheck_col2" value="360" /> + <variable name="nandcheck_row1" value="130" /> + <variable name="nandcheck_row2" value="160" /> + <variable name="nandcheck_row3" value="190" /> + <variable name="nandcheck_row4" value="220" /> + <variable name="nandcheck_row5" value="250" /> + <variable name="nandcheck_row6" value="280" /> + <variable name="nandcheck_row7" value="310" /> + <variable name="nandcheck_row8" value="340" /> + <variable name="button_text_color" value="#AAAAAA" /> + <variable name="text_color" value="#A0A0A0" /> + <variable name="text_success_color" value="#33B5E5" /> + <variable name="text_fail_color" value="#FF0101" /> + <variable name="highlight_color" value="#90909080" /> + <variable name="caps_highlight_color" value="#33B5E580" /> + <variable name="slider_x" value="225" /> + <variable name="slider_y" value="390" /> + <variable name="slider_text_y" value="425" /> + <variable name="sort_text_x" value="170" /> + <variable name="sort_asc_text_y" value="418" /> + <variable name="sort_asc_button_y" value="413" /> + <variable name="sort_desc_text_y" value="452" /> + <variable name="sort_desc_button_y" value="447" /> + <variable name="sort_col1_button_x" value="300" /> + <variable name="sort_col2_button_x" value="370" /> + <variable name="sort_col3_button_x" value="440" /> + <variable name="col1_sdext_x" value="265" /> + <variable name="col2_sdext_x" value="475" /> + <variable name="row1_sdext_y" value="85" /> + <variable name="row2_sdext_y" value="150" /> + <variable name="row_extsize_y" value="85" /> + <variable name="row_swapsize_y" value="150" /> + <variable name="input_x" value="28" /> + <variable name="input_width" value="720" /> + <variable name="input_height" value="25" /> + <variable name="input_background_color" value="#303030" /> + <variable name="input_cursor_color" value="#33B5E5" /> + <variable name="input_cursor_width" value="2" /> + <variable name="console_x" value="25" /> + <variable name="console_width" value="750" /> + <variable name="console_foreground" value="#A0A0A0" /> + <variable name="warning" value="#F8F8A0" /> + <variable name="error" value="#FF4040" /> + <variable name="highlight" value="#33B5E5" /> + <variable name="console_background" value="#303030" /> + <variable name="console_scroll" value="#303030" /> + <variable name="console_action_height" value="230" /> + <variable name="console_install_height" value="260" /> + <variable name="console_installdone_height" value="260" /> + <variable name="fileselector_folder_x" value="28" /> + <variable name="fileselector_folder_width" value="248" /> + <variable name="fileselector_folderonly_width" value="400" /> + <variable name="fileselector_file_x" value="278" /> + <variable name="fileselector_file_width" value="506" /> + <variable name="fileselector_install_y" value="120" /> + <variable name="fileselector_install_height" value="290" /> + <variable name="fileselector_header_background" value="#202020" /> + <variable name="fileselector_header_textcolor" value="#AAAAAA" /> + <variable name="fileselector_header_separatorcolor" value="#33B5E5" /> + <variable name="fileselector_header_separatorheight" value="2" /> + <variable name="fileselector_separatorcolor" value="#505050" /> + <variable name="fileselector_separatorheight" value="1" /> + <variable name="fileselector_background" value="#303030" /> + <variable name="fileselector_highlight_color" value="#505050" /> + <variable name="fileselector_highlight_font_color" value="#33B5E5" /> + <variable name="fileselector_spacing" value="12" /> + <variable name="fastscroll_linecolor" value="#50505080" /> + <variable name="fastscroll_rectcolor" value="#33B5E580" /> + <variable name="fastscroll_w" value="25" /> + <variable name="fastscroll_linew" value="2" /> + <variable name="fastscroll_rectw" value="12" /> + <variable name="fastscroll_recth" value="20" /> + <variable name="zipstorage_text_y" value="88" /> + <variable name="listbox_x" value="156" /> + <variable name="listbox_y" value="90" /> + <variable name="listbox_width" value="460" /> + <variable name="listbox_tz_height" value="170" /> + <variable name="listbox_background" value="#303030" /> + <variable name="listbox_spacing" value="12" /> + <variable name="sd_plus_x" value="280" /> + <variable name="lock_y" value="150" /> + <variable name="filemanager_select_x" value="610" /> + <variable name="filemanager_select_y" value="413" /> + <variable name="backup_name_text_y" value="440" /> + <variable name="backup_name_button_y" value="195" /> + <variable name="col_right_x" value="772" /> + <variable name="cancel_button_y" value="180" /> + <variable name="terminal_console_y" value="0" /> + <variable name="terminal_console_height" value="240" /> + <variable name="terminal_text_y" value="247" /> + <variable name="terminal_button_y" value="237" /> + <variable name="terminal_input_width" value="551" /> + <variable name="button_fill_color" value="#303030" /> + <variable name="button_fill_full_width" value="400" /> + <variable name="button_fill_main_width" value="367" /> + <variable name="button_fill_main_height" value="120" /> + <variable name="button_fill_half_height" value="40" /> + <variable name="button_fill_quarter_height" value="30" /> + <variable name="button_full_center_x" value="200" /> + <variable name="flash_list_height" value="140" /> + <variable name="backup_list_x" value="23" /> + <variable name="backup_list_y" value="80" /> + <variable name="backup_list_width" value="367" /> + <variable name="backup_list_height" value="290" /> + <variable name="backup_storage_y" value="190" /> + <variable name="backup_encrypt_y" value="235" /> + <variable name="restore_list_y" value="100" /> + <variable name="restore_list_height" value="270" /> + <variable name="mount_list_height" value="360" /> + <variable name="mount_storage_row" value="500" /> + <variable name="wipe_list_height" value="300" /> + <variable name="wipe_button_y" value="150" /> + <variable name="slidervalue_x" value="200" /> + <variable name="slidervalue_w" value="400" /> + <variable name="slidervalue_line_clr" value="#FFFFFF" /> + <variable name="slidervalue_slider_clr" value="#33B5E5" /> + <variable name="slidervalue_lineh" value="1" /> + <variable name="slidervalue_padding" value="0" /> + <variable name="slidervalue_sliderw" value="7" /> + <variable name="slidervalue_sliderh" value="40" /> + <variable name="pattern_x" value="200" /> + <variable name="pattern_y" value="110" /> + <variable name="pattern_width" value="300" /> + <variable name="pattern_dot_color" value="#33B5E5" /> + <variable name="pattern_dot_color_active" value="#FFFFFF" /> + <variable name="pattern_dot_radius" value="10" /> + <variable name="pattern_line_color" value="#33B5E5" /> + <variable name="pattern_line_width" value="7" /> + </variables> + + <mousecursor> + <placement w="15" h="15" /> + <background color="#FFFF00FF" resource="cursor" /> + <speed multiplier="1.5" /> + </mousecursor> + + <templates> + <template name="header"> + <background color="#000000FF" /> + + <object type="fill" color="%button_fill_color%"> + <placement x="0" y="0" w="800" h="58" /> + </object> + + <object type="fill" color="%highlight%"> + <placement x="0" y="58" w="800" h="2" /> + </object> + + <object type="image"> + <image resource="twrplogo" /> + <placement x="35" y="29" placement="4" /> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="70" y="2" /> + <text>Team Win Recovery Project v%tw_version%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="70" y="37" /> + <conditions> + <condition var1="tw_no_battery_percent" var2="0" /> + <condition var1="tw_battery" op=">" var2="0" /> + <condition var1="tw_battery" op="<" var2="101" /> + </conditions> + <text>Battery Level: %tw_battery%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="425" y="37" /> + <text>%tw_time%</text> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="500" y="37" /> + <conditions> + <condition var1="tw_no_cpu_temp" var2="0" /> + </conditions> + <text>CPU: %tw_cpu_temp% C</text> + </object> + + <object type="text" color="%text_color%"> + <condition var1="tw_simulate_actions" var2="1" /> + <font resource="font" /> + <placement x="250" y="20" /> + <text>SIMULATING ACTIONS</text> + </object> + + <object type="button"> + <highlight color="%highlight_color%" /> + <placement x="%home_button_x%" y="%home_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text></text> + <image resource="home_icon" /> + <condition var1="tw_busy" var2="0" /> + <action function="key">home</action> + </object> + + <object type="button"> + <highlight color="%highlight_color%" /> + <placement x="%back_button_x%" y="%back_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text></text> + <image resource="back_icon" /> + <condition var1="tw_busy" var2="0" /> + <action function="key">back</action> + </object> + + <object type="action"> + <touch key="power" /> + <action function="overlay">lock</action> + </object> + + <object type="action"> + <touch key="power+voldown" /> + <action function="screenshot" /> + </object> + </template> + + <template name="progress_bar"> + <object type="progressbar"> + <placement x="%col_progressbar_x%" y="%row_progressbar_y%" /> + <resource empty="progress_empty" full="progress_full" /> + <data name="ui_progress" /> + </object> + + <object type="animation"> + <placement x="%col_progressbar_x%" y="%row_progressbar_y%" /> + <resource name="progress" /> + <speed fps="15" render="2" /> + <loop frame="1" /> + </object> + </template> + + <template name="sort_options"> + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%sort_text_x%" y="%sort_asc_text_y%" /> + <text>Sort Ascending:</text> + </object> + + <object type="button"> + <highlight color="%highlight_color%" /> + <placement x="%sort_col1_button_x%" y="%sort_asc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Name</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=1</action> + </object> + + <object type="button"> + <highlight color="%highlight_color%" /> + <placement x="%sort_col2_button_x%" y="%sort_asc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Date</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=2</action> + </object> + + <object type="button"> + <highlight color="%highlight_color%" /> + <placement x="%sort_col3_button_x%" y="%sort_asc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Size</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=3</action> + </object> + + <object type="text" color="%text_color%"> + <font resource="font" /> + <placement x="%sort_text_x%" y="%sort_desc_text_y%" /> + <text>Sort Descending:</text> + </object> + + <object type="button"> + <highlight color="%highlight_color%" /> + <placement x="%sort_col1_button_x%" y="%sort_desc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Name</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=-1</action> + </object> + + <object type="button"> + <highlight color="%highlight_color%" /> + <placement x="%sort_col2_button_x%" y="%sort_desc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Date</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=-2</action> + </object> + + <object type="button"> + <highlight color="%highlight_color%" /> + <placement x="%sort_col3_button_x%" y="%sort_desc_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>Size</text> + <image resource="sort_button" /> + <action function="set">tw_gui_sort_order=-3</action> + </object> + </template> + + <template name="flash_zip_console"> + <object type="console"> + <placement x="%console_x%" y="85" w="%console_width%" h="260" /> + <color foreground="%console_foreground%" background="%console_background%" scroll="%console_scroll%" /> + <font resource="fixed" /> + </object> + </template> + + <template name="action_page_console"> + <object type="console"> + <placement x="%console_x%" y="160" w="%console_width%" h="230" /> + <color foreground="%console_foreground%" background="%console_background%" scroll="%console_scroll%" /> + <font resource="fixed" /> + </object> + </template> + + <template name="footer"> + <object type="console"> + <slideout resource="console_button" x="%console_button_x%" y="%console_button_y%" /> + <placement x="%console_x%" y="60" w="%console_width%" h="380" /> + <color foreground="%console_foreground%" background="%console_background%" scroll="%console_scroll%" /> + <font resource="fixed" /> + </object> + </template> + + <template name="keyboardtemplate"> + <object type="keyboard"> + <placement x="0" y="277" /> + <layout resource1="keyboard1" resource2="keyboard2" resource3="keyboard3" resource4="keyboard4" /> + <highlight color="%highlight_color%" /> + <capshighlight color="%caps_highlight_color%" /> + <layout1> + <keysize height="51" width="73" /> + <row1 key01="q" long01="1" key02="w" long02="2" key03="e" long03="3" key04="r" long04="4" key05="t" long05="5" key06="y" long06="6" key07="u" long07="7" key08="i" long08="8" key09="o" long09="9" key10="p" long10="0" key11="70:c:8" /> + <row2 key01="107:a" key02="s" key03="d" key04="f" key05="g" key06="h" key07="j" key08="k" key09="l" key10="109:action" /> + <row3 key01="79:layout2" key02="72:z" key03="72:x" key04="72:c" key05="72:v" key06="72:b" key07="72:n" key08="72:m" key09="72:," long09="!" key10="72:." long10="?" key11="73::" long11="+" /> + <row4 key01="103:layout3" key02="72:" key03="/" long03="@" key04="315: " key05="'" long05="73:c:34" key06="-" long06="_" /> + </layout1> + <layout2> + <keysize height="51" width="73" capslock="0" revert_layout="1" /> + <row1 key01="Q" long01="1" key02="W" long02="2" key03="E" long03="3" key04="R" long04="4" key05="T" long05="5" key06="Y" long06="6" key07="U" long07="7" key08="I" long08="8" key09="O" long09="9" key10="P" long10="0" key11="70:c:8" /> + <row2 key01="107:A" key02="S" key03="D" key04="F" key05="G" key06="H" key07="J" key08="K" key09="L" key10="109:action" /> + <row3 key01="79:layout1" key02="72:Z" key03="72:X" key04="72:C" key05="72:V" key06="72:B" key07="72:N" key08="72:M" key09="72:," long09="!" key10="72:." long10="?" key11="73::" long11="+" /> + <row4 key01="103:layout3" key02="72:" key03="/" long03="@" key04="315: " key05="'" long05="73:c:34" key06="-" long06="_" /> + </layout2> + <layout3> + <keysize height="51" width="73" /> + <row1 key01="1" key02="2" key03="3" key04="4" key05="5" key06="6" key07="7" key08="8" key09="9" key10="0" key11="70:c:8" /> + <row2 key01="107:#" key02="$" key03="%" key04="&" key05="*" key06="-" key07="+" key08="(" key09=")" key10="109:action" /> + <row3 key01="79:layout4" key02="72:<" key03="72:>" key04="72:=" key05="72::" key06="72:;" key07="72:," key08="72:." key09="72:!" key10="72:?" key11="73:/" /> + <row4 key01="103:layout1" key02="72:" key03="@" key04="315: " key05="73:c:34" key06="_" /> + </layout3> + <layout4> + <keysize height="51" width="73" /> + <row1 key01="~" key02="`" key03="|" key04="73:" key05="73:" key06="73:" key07="73:" key08="73:" key09="73:" key10="73:" key11="70:c:8" /> + <row2 key01="107:" key02="73:" key03="73:" key04="73:" key05="^" key06="73:" key07="73:" key08="{" key09="}" key10="109:action" /> + <row3 key01="79:layout3" key02="72:\" key03="72:" key04="72:" key05="72:" key06="72:" key07="72:[" key08="72:]" key09="72:!" key10="72:?" /> + <row4 key01="103:layout1" key02="72:" key03="72:" key04="315: " /> + </layout4> + </object> + </template> + </templates> +</recovery> diff --git a/gui/devices/common/res/fonts/DroidSansMono.ttf b/gui/devices/common/res/fonts/DroidSansMono.ttf Binary files differnew file mode 100644 index 000000000..4085cee84 --- /dev/null +++ b/gui/devices/common/res/fonts/DroidSansMono.ttf diff --git a/gui/devices/common/res/fonts/RobotoCondensed-Regular.ttf b/gui/devices/common/res/fonts/RobotoCondensed-Regular.ttf Binary files differnew file mode 100644 index 000000000..b9fc49c95 --- /dev/null +++ b/gui/devices/common/res/fonts/RobotoCondensed-Regular.ttf diff --git a/gui/devices/common/res/images/progress_empty.png b/gui/devices/common/res/images/progress_empty.png Binary files differnew file mode 100644 index 000000000..b85371014 --- /dev/null +++ b/gui/devices/common/res/images/progress_empty.png diff --git a/gui/devices/common/res/images/progress_fill.png b/gui/devices/common/res/images/progress_fill.png Binary files differnew file mode 100644 index 000000000..6731dae4a --- /dev/null +++ b/gui/devices/common/res/images/progress_fill.png diff --git a/gui/devices/landscape/res/landscape.xml b/gui/devices/landscape/res/landscape.xml new file mode 100644 index 000000000..c75be3c6f --- /dev/null +++ b/gui/devices/landscape/res/landscape.xml @@ -0,0 +1,3714 @@ +<?xml version="1.0"?> + +<recovery> + <styles> + <style name="buttontext"> + <highlight color="%highlight_color%" /> + <font resource="font" color="%button_text_color%" /> + </style> + + <style name="button"> + <style name="buttontext" /> + <image resource="main_button" /> + </style> + + <style name="mediumbutton"> + <style name="buttontext" /> + <image resource="medium_button" /> + </style> + + <style name="mediumwidebutton"> + <style name="buttontext" /> + <image resource="mediumwide_button" /> + </style> + + <style name="fillbutton"> + <style name="buttontext" /> + <fill color="%button_fill_color%" /> + </style> + + <style name="rebootsystem"> + <condition var1="tw_reboot_system" var2="1" /> + <style name="button" /> + <text>Reboot System</text> + <actions> + <action function="set">tw_back=main2</action> + <action function="set">tw_action=reboot</action> + <action function="set">tw_action_param=system</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=No OS Installed! Are you</action> + <action function="set">tw_text2=sure you wish to reboot?</action> + <action function="set">tw_text3=</action> + <action function="set">tw_text4=</action> + <action function="set">tw_action_text1=Rebooting...</action> + <action function="set">tw_action_text2=</action> + <action function="set">tw_complete_text1=Rebooting...</action> + <action function="set">tw_slider_text=Swipe to Reboot</action> + <action function="page">rebootcheck</action> + </actions> + </style> + + <style name="scrolllist"> + <highlight color="%fileselector_highlight_color%" /> + <header background="%fileselector_header_background%" textcolor="%fileselector_header_textcolor%" separatorcolor="%fileselector_header_separatorcolor%" separatorheight="%fileselector_header_separatorheight%" /> + <fastscroll linecolor="%fastscroll_linecolor%" rectcolor="%fastscroll_rectcolor%" w="%fastscroll_w%" linew="%fastscroll_linew%" rectw="%fastscroll_rectw%" recth="%fastscroll_recth%" /> + <separator color="%fileselector_separatorcolor%" height="%fileselector_separatorheight%" /> + <background color="%fileselector_background%" /> + <font resource="font" spacing="%fileselector_spacing%" color="%text_color%" highlightcolor="%fileselector_highlight_font_color%" /> + </style> + + <style name="fileselector"> + <style name="scrolllist" /> + <icon folder="folder_icon" file="file_icon" /> + <sort name="tw_gui_sort_order" /> + </style> + + <style name="partitionlist"> + <style name="scrolllist" /> + <icon selected="checkbox_true" unselected="checkbox_false" /> + </style> + + <style name="text"> + <font resource="font" color="%text_color%" /> + </style> + + <style name="checkbox"> + <font resource="font" color="%text_color%" /> + <image checked="checkbox_true" unchecked="checkbox_false" /> + </style> + + <style name="slider"> + <text>Swipe to Confirm</text> + <font resource="font" color="%text_color%" /> + <placement x="%center_x%" y="%slider_y%" placement="5" /> + <resource base="slider" used="slider-used" touch="slider-touch" /> + </style> + + <style name="console"> + <color foreground="%console_foreground%" background="%console_background%" scroll="%console_scroll%" /> + <font resource="fixed" /> + <fastscroll linecolor="%fastscroll_linecolor%" rectcolor="%fastscroll_rectcolor%" w="%fastscroll_w%" linew="%fastscroll_linew%" rectw="%fastscroll_rectw%" recth="%fastscroll_recth%" /> + </style> + + <style name="input"> + <background color="%input_background_color%" /> + <cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" /> + <font resource="font" color="%text_color%" /> + </style> + + <style name="slidervalue"> + <font resource="font" color="%text_color%" /> + <colors line="%slidervalue_line_clr%" slider="%slidervalue_slider_clr%" /> + <dimensions lineh="%slidervalue_lineh%" linepadding="%slidervalue_padding%" sliderw="%slidervalue_sliderw%" sliderh="%slidervalue_sliderh%" /> + </style> + </styles> + + <pages> + <page name="main"> + <object type="action"> + <actions> + <action function="set">tw_clear_destination=main2</action> + <action function="page">clear_vars</action> + </actions> + </object> + </page> + + <page name="main2"> + <object type="template" name="header" /> + + <object type="button"> + <placement x="%col1_x%" y="%row1_y%" /> + <text>Install</text> + <actions> + <action function="queueclear"></action> + <action function="page">install</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row1_y%" /> + <text>Backup</text> + <action function="page">backup</action> + </object> + + <object type="button"> + <placement x="%col3_x%" y="%row1_y%" /> + <text>Restore</text> + <action function="page">restore</action> + </object> + + <object type="button"> + <placement x="%col4_x%" y="%row1_y%" /> + <text>Wipe</text> + <action function="page">wipe</action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Mount</text> + <action function="page">mount</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row2_y%" /> + <text>Settings</text> + <action function="page">settings</action> + </object> + + <object type="button"> + <placement x="%col3_x%" y="%row2_y%" /> + <text>Advanced</text> + <action function="page">advanced</action> + </object> + + <object type="button"> + <placement x="%col4_x%" y="%row2_y%" /> + <text>Reboot</text> + <action function="page">reboot</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="install"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Select Zip to Install</text> + </object> + + <object type="button" style="fillbutton"> + <placement x="%button_full_center_x%" y="%zipstorage_text_y%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" /> + <text>Storage: %tw_storage_display_name% (%tw_storage_free_size% MB)</text> + <actions> + <action function="set">tw_back=install</action> + <action function="page">selectstorage</action> + </actions> + </object> + + <object type="fileselector"> + <placement x="%fileselector_folder_x%" y="%fileselector_install_y%" w="%fileselector_folder_width%" h="%fileselector_install_height%" /> + <text>Folders:</text> + <filter folders="1" files="0" /> + <path name="tw_zip_location" default="/sdcard" /> + <data name="select" /> + </object> + + <object type="fileselector"> + <placement x="%fileselector_file_x%" y="%fileselector_install_y%" w="%fileselector_file_width%" h="%fileselector_install_height%" /> + <text>%tw_zip_location%</text> + <filter extn=".zip" folders="0" files="1" /> + <path name="tw_zip_location" /> + <data name="tw_filename" /> + <selection name="tw_file" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="button"> + <placement x="%filemanager_select_x%" y="%filemanager_select_y%" /> + <text>Images...</text> + <actions> + <action function="page">install_image</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_filename" op="modified" /> + <actions> + <action function="queuezip"></action> + <action function="page">flash_confirm</action> + </actions> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="flash_confirm"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>WARNING: This operation may install incompatible software and render your device unusable.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Folder:</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_zip_location%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>File to flash:</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row5_text_y%" placement="5" /> + <text>%tw_file%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row6_text_y%" placement="5" /> + <text>Press back to cancel adding this zip.</text> + </object> + + <object type="checkbox"> + <placement x="%col2_x%" y="%row7_text_y%" /> + <text>Zip file signature verification?</text> + <data variable="tw_signed_zip_verify" /> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row10_text_y%" placement="5" /> + <text>File %tw_zip_queue_count% of max of 10</text> + </object> + + <object type="button" style="mediumwidebutton"> + <condition var1="tw_zip_queue_count" op="!=" var2="10"></condition> + <placement x="%col2_x%" y="%row5_medium_y%" /> + <text>Add More Zips</text> + <action function="page">install</action> + </object> + + <object type="button" style="mediumwidebutton"> + <placement x="%col3_x%" y="%row5_medium_y%" /> + <text>Clear Queue</text> + <actions> + <action function="queueclear"></action> + <action function="page">install</action> + </actions> + </object> + + <object type="slider"> + <text>Swipe to Confirm Flash</text> + <action function="flash">flash_zip</action> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="cancelzip"></action> + <action function="page">install</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="flash_zip"> + <object type="template" name="header" /> + + <object type="template" name="flash_zip_console" /> + + <object type="text"> + <placement x="%col1_x%" y="%row16_text_y%" /> + <text>Flashing file %tw_zip_index% of %tw_zip_queue_count%</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row17_text_y%" /> + <text>%tw_filename%</text> + </object> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <action function="page">flash_done</action> + </object> + </page> + + <page name="flash_done"> + <object type="template" name="header" /> + + <object type="template" name="flash_zip_console" /> + + <object type="text"> + <condition var1="tw_operation_status" op="!=" var2="0" /> + <font resource="font" color="%text_fail_color%" /> + <placement x="%center_x%" y="%row17_text_y%" placement="5" /> + <text>Failed</text> + </object> + + <object type="text"> + <condition var1="tw_operation_status" var2="0" /> + <font resource="font" color="%text_success_color%" /> + <placement x="%center_x%" y="%row17_text_y%" placement="5" /> + <text>Successful</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%slider_y%" /> + <text>Wipe Cache/Dalvik</text> + <actions> + <action function="set">tw_back=flash_done</action> + <action function="set">tw_action=wipe</action> + <action function="set">tw_action_param=/cache</action> + <action function="set">tw_has_action2=1</action> + <action function="set">tw_action2=wipe</action> + <action function="set">tw_action2_param=dalvik</action> + <action function="set">tw_text1=Wipe Cache & Dalvik?</action> + <action function="set">tw_action_text1=Wiping Cache & Dalvik...</action> + <action function="set">tw_complete_text1=Cache & Dalvik Wipe Complete</action> + <action function="set">tw_slider_text=Swipe to Wipe</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button" style="rebootsystem"> + <placement x="%col4_x%" y="%slider_y%" /> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%slider_y%" /> + <text>Home</text> + <actions> + <action function="set">tw_clear_destination=main2</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="set">tw_clear_destination=install</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <actions> + <action function="set">tw_clear_destination=main2</action> + <action function="page">clear_vars</action> + </actions> + </object> + </page> + + <page name="install_image"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Select Image to Flash</text> + </object> + + <object type="button" style="fillbutton"> + <placement x="%button_full_center_x%" y="%zipstorage_text_y%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" /> + <text>Storage: %tw_storage_display_name% (%tw_storage_free_size% MB)</text> + <actions> + <action function="set">tw_back=install_image</action> + <action function="page">selectstorage</action> + </actions> + </object> + + <object type="fileselector"> + <placement x="%fileselector_folder_x%" y="%fileselector_install_y%" w="%fileselector_folder_width%" h="%fileselector_install_height%" /> + <text>Folders:</text> + <filter folders="1" files="0" /> + <path name="tw_zip_location" default="/sdcard" /> + <data name="select" /> + </object> + + <object type="fileselector"> + <placement x="%fileselector_file_x%" y="%fileselector_install_y%" w="%fileselector_file_width%" h="%fileselector_install_height%" /> + <text>%tw_zip_location%</text> + <filter extn=".img" folders="0" files="1" /> + <path name="tw_zip_location" /> + <data name="tw_filename" /> + <selection name="tw_file" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="button"> + <placement x="%filemanager_select_x%" y="%filemanager_select_y%" /> + <text>Zips...</text> + <actions> + <action function="page">install</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_filename" op="modified" /> + <action function="page">flashimage_confirm</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">install</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="flashimage_confirm"> + <object type="template" name="header" /> + + <object type="partitionlist"> + <placement x="%col2_x%" y="%row1_text_y%" w="%listbox_width%" h="%flash_list_height%" /> + <text>Select Partition to Flash Image:</text> + <icon selected="radio_true" unselected="radio_false" /> + <data name="tw_flash_partition" /> + <listtype name="flashimg" /> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row8_text_y%" placement="5" /> + <text>Folder:</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row9_text_y%" placement="5" /> + <text>%tw_zip_location%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row10_text_y%" placement="5" /> + <text>File to flash:</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row11_text_y%" placement="5" /> + <text>%tw_file%</text> + </object> + + <object type="slider"> + <text>Swipe to Confirm Flash</text> + <actions> + <action function="set">tw_back=flashimage_confirm</action> + <action function="set">tw_action=flashimage</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_action_text1=Flashing Image...</action> + <action function="set">tw_action_text2=</action> + <action function="set">tw_complete_text1=Image Flashed</action> + <action function="page">action_page</action> + </actions> + <action function="flashimage"></action> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="set">tw_clear_destination=install_image</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <actions> + <action function="set">tw_clear_destination=main2</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="clear_vars"> + <object type="action"> + <action function="set">tw_operation_state=0</action> + <action function="set">tw_text1=</action> + <action function="set">tw_text2=</action> + <action function="set">tw_text3=</action> + <action function="set">tw_text4=</action> + <action function="set">tw_action_text1=</action> + <action function="set">tw_action_text2=</action> + <action function="set">tw_action_param=</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_action2=</action> + <action function="set">tw_action2_param=</action> + <action function="set">tw_has_cancel=0</action> + <action function="set">tw_cancel_action=</action> + <action function="set">tw_cancel_param=</action> + <action function="set">tw_show_exclamation=0</action> + <action function="set">tw_show_reboot=0</action> + <action function="page">%tw_clear_destination%</action> + </object> + </page> + + <page name="confirm_action"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_text1%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_text2%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_text3%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>%tw_text4%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row12_text_y%" placement="5" /> + <text>Press back button to cancel.</text> + </object> + + <object type="slider"> + <text>%tw_slider_text%</text> + <action function="page">action_page</action> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="set">tw_clear_destination=%tw_back%</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="action_page"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_action_text1%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_action_text2%</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="button"> + <condition var1="tw_has_cancel" var2="1" /> + <placement x="%col_center_x%" y="%cancel_button_y%" /> + <text>Cancel</text> + <action function="%tw_cancel_action%">%tw_cancel_param%</action> + </object> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <actions> + <action function="page">action_complete</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_has_action2" var2="0" /> + <actions> + <action function="%tw_action%">%tw_action_param%</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_has_action2" var2="1" /> + <actions> + <action function="%tw_action%">%tw_action_param%</action> + <action function="%tw_action2%">%tw_action2_param%</action> + </actions> + </object> + </page> + + <page name="singleaction_page"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_action_text1%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_action_text2%</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <actions> + <action function="set">tw_page_done=1</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_has_action2" var2="0" /> + <actions> + <action function="%tw_action%">%tw_action_param%</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_has_action2" var2="1" /> + <actions> + <action function="%tw_action%">%tw_action_param%</action> + <action function="%tw_action2%">%tw_action2_param%</action> + </actions> + </object> + </page> + + <page name="action_complete"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_complete_text1%</text> + </object> + + <object type="text"> + <condition var1="tw_operation_status" op="!=" var2="0" /> + <font resource="font" color="%text_fail_color%" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Failed</text> + </object> + + <object type="text"> + <condition var1="tw_operation_status" var2="0" /> + <font resource="font" color="%text_success_color%" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Successful</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="button"> + <condition var1="tw_show_reboot" var2="0" /> + <placement x="%col_center_x%" y="%slider_y%" /> + <text>Back</text> + <actions> + <action function="set">tw_clear_destination=%tw_back%</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="button" style="rebootsystem"> + <condition var1="tw_show_reboot" var2="1" /> + <placement x="%col_center_x%" y="%slider_y%" /> + </object> + + <object type="action"> + <touch key="home" /> + <actions> + <action function="set">tw_clear_destination=main2</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="set">tw_clear_destination=%tw_back%</action> + <action function="page">clear_vars</action> + </actions> + </object> + </page> + + <page name="filecheck"> + <object type="action"> + <action function="fileexists">%tw_filecheck%</action> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" var2="0" /> + </conditions> + <actions> + <action function="set">tw_fileexists=1</action> + <action function="page">%tw_existpage%</action> + </actions> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" var2="1" /> + </conditions> + <actions> + <action function="set">tw_fileexists=0</action> + <action function="page">%tw_notexistpage%</action> + </actions> + </object> + </page> + + <page name="rebootcheck"> + <object type="action"> + <condition var1="tw_backup_system_size" op=">=" var2="%tw_min_system%" /> + <action function="reboot">%tw_action_param%</action> + </object> + + <object type="action"> + <condition var1="tw_backup_system_size" op="<" var2="%tw_min_system%" /> + <action function="page">confirm_action</action> + </object> + </page> + + <page name="reboot"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Reboot Menu</text> + </object> + + <object type="button" style="rebootsystem"> + <placement x="%col1_x%" y="%row1_y%" /> + <text>System</text> + </object> + + <object type="button"> + <condition var1="tw_reboot_poweroff" var2="1" /> + <placement x="%col2_x%" y="%row1_y%" /> + <text>Power Off</text> + <actions> + <action function="set">tw_back=reboot</action> + <action function="set">tw_action=reboot</action> + <action function="set">tw_action_param=poweroff</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=No OS Installed! Are you</action> + <action function="set">tw_text2=sure you wish to power off?</action> + <action function="set">tw_action_text1=Turning Off...</action> + <action function="set">tw_complete_text1=Turning Off...</action> + <action function="set">tw_slider_text=Swipe to Power Off</action> + <action function="page">rebootcheck</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_reboot_recovery" var2="1" /> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Recovery</text> + <actions> + <action function="set">tw_back=reboot</action> + <action function="set">tw_action=reboot</action> + <action function="set">tw_action_param=recovery</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=No OS Installed! Are you</action> + <action function="set">tw_text2=sure you wish to reboot?</action> + <action function="set">tw_action_text1=Rebooting...</action> + <action function="set">tw_complete_text1=Rebooting...</action> + <action function="set">tw_slider_text=Swipe to Reboot</action> + <action function="page">rebootcheck</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_reboot_bootloader" var2="1" /> + <placement x="%col2_x%" y="%row2_y%" /> + <text>Bootloader</text> + <actions> + <action function="set">tw_back=reboot</action> + <action function="set">tw_action=reboot</action> + <action function="set">tw_action_param=bootloader</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=No OS Installed! Are you</action> + <action function="set">tw_text2=sure you wish to reboot?</action> + <action function="set">tw_action_text1=Rebooting...</action> + <action function="set">tw_complete_text1=Rebooting...</action> + <action function="set">tw_slider_text=Swipe to Reboot</action> + <action function="page">rebootcheck</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_download_mode" var2="1" /> + <placement x="%col3_x%" y="%row2_y%" /> + <text>Download</text> + <actions> + <action function="set">tw_back=reboot</action> + <action function="set">tw_action=reboot</action> + <action function="set">tw_action_param=download</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=No OS Installed! Are you</action> + <action function="set">tw_text2=sure you wish to reboot?</action> + <action function="set">tw_action_text1=Rebooting...</action> + <action function="set">tw_complete_text1=Rebooting...</action> + <action function="set">tw_slider_text=Swipe to Reboot</action> + <action function="page">rebootcheck</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="selectstorage"> + <object type="template" name="header" /> + + <object type="partitionlist"> + <placement x="%col2_x%" y="%fileselector_install_y%" w="%fileselector_folderonly_width%" h="%fileselector_install_height%" /> + <text>Select Storage:</text> + <icon selected="radio_true" unselected="radio_false" /> + <data name="tw_storage_path" /> + <listtype name="storage" /> + </object> + + <object type="button"> + <placement x="%filemanager_select_x%" y="%row2_y%" /> + <text>OK</text> + <actions> + <action function="set">tw_clear_destination=%tw_back%</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="page">%tw_back%</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="mount"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Mount Menu</text> + </object> + + <object type="partitionlist"> + <placement x="%backup_list_x%" y="%backup_list_y%" w="%backup_list_width%" h="%mount_list_height%" /> + <text>Select Partitions to Mount:</text> + <listtype name="mount" /> + </object> + + <object type="button"> + <conditions> + <condition var1="tw_is_encrypted" var2="1" /> + <condition var1="tw_is_decrypted" var2="0" /> + </conditions> + <placement x="%col3_x%" y="row1_y" /> + <text>Decrypt Data</text> + <action function="page">decrypt</action> + </object> + + <object type="button"> + <condition var1="tw_has_usb_storage" var2="1" /> + <placement x="%col4_x%" y="%row1_y%" /> + <text>Mount USB Storage</text> + <action function="page">usb_mount</action> + </object> + + <object type="button"> + <conditions> + <condition var1="tw_has_mtp" var2="1" /> + <condition var1="tw_mtp_enabled" var2="0" /> + </conditions> + <placement x="%col3_x%" y="row1_y" /> + <text>Enable MTP</text> + <action function="startmtp"></action> + </object> + + <object type="button"> + <conditions> + <condition var1="tw_has_mtp" var2="1" /> + <condition var1="tw_mtp_enabled" var2="1" /> + </conditions> + <placement x="%col3_x%" y="row1_y" /> + <text>Disable MTP</text> + <action function="stopmtp"></action> + </object> + + <object type="button"> + <conditions> + <condition var1="tw_is_encrypted" var2="1" /> + <condition var1="tw_is_decrypted" var2="0" /> + </conditions> + <placement x="%col3_x%" y="row1_y" /> + <text>Decrypt Data</text> + <action function="page">decrypt</action> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col3_x%" y="%backup_storage_y%" w="%button_fill_main_width%" h="%button_fill_half_height%" /> + <text>Storage: %tw_storage_display_name% (%tw_storage_free_size% MB)</text> + <actions> + <action function="set">tw_back=mount</action> + <action function="page">selectstorage</action> + </actions> + </object> + + <object type="button"> + <placement x="%col3_x%" y="%row10_text_y%" /> + <font resource="font" color="%text_color%" /> + <condition var1="tw_mount_system_ro" op="=" var2="0" /> + <text>Only mount system read-only</text> + <image resource="checkbox_false" /> + <action function="mountsystemtoggle">1</action> + </object> + + <object type="button"> + <placement x="%col3_x%" y="%row10_text_y%" /> + <font resource="font" color="%text_color%" /> + <condition var1="tw_mount_system_ro" op="!=" var2="0" /> + <text>Only mount system read-only</text> + <image resource="checkbox_true" /> + <actions> + <action function="set">tw_lifetime_writes=2</action> + <action function="page">system_readonly_check</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="usb_mount"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>USB Storage Mounted -- Be sure to safely remove your device from your computer before unmounting!</text> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row1_y%" /> + <text>Unmount</text> + <action function="page">usb_umount</action> + </object> + + <object type="action"> + <action function="mount">usb</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="usb_umount"> + <object type="action"> + <action function="unmount">usb</action> + </object> + + <object type="action"> + <action function="page">mount</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="system_readonly_check"> + <object type="action"> + <action function="checkpartitionlifetimewrites">/system</action> + </object> + + <object type="action"> + <condition var1="tw_lifetime_writes" var2="1" /> + <actions> + <action function="mountsystemtoggle">0</action> + <action function="page">mount</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_lifetime_writes" var2="0" /> + <actions> + <action function="set">tw_back=mount</action> + <action function="page">system_readonly</action> + </actions> + </object> + </page> + + <page name="wipe"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Factory Reset: Wipes Data, Cache, and Dalvik</text> + </object> + + <object type="text"> + <condition var1="tw_has_data_media" var2="1" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>(not including internal storage)</text> + </object> + + <object type="text"> + <conditions> + <condition var1="tw_has_android_secure" var2="1" /> + <condition var1="fileexists" var2="/and-sec" /> + </conditions> + <placement x="%center_x%" y="%row3_text_y%" placement="1" /> + <text>Android Secure </text> + </object> + + <object type="text"> + <condition var1="tw_has_sdext_partition" var2="1" /> + <placement x="%center_x%" y="%row3_text_y%" /> + <text> SD-EXT</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>Most of the time this is the only wipe that you need.</text> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%wipe_button_y%" /> + <text>Advanced Wipe</text> + <action function="page">advancedwipe</action> + </object> + + <object type="button"> + <condition var1="tw_has_data_media" var2="1" /> + <placement x="%col3_x%" y="%wipe_button_y%" /> + <text>Format Data</text> + <actions> + <action function="page">formatdata</action> + </actions> + </object> + + <object type="button"> + <conditions> + <condition var1="tw_is_encrypted" var2="1" /> + <condition var1="tw_has_data_media" var2="0" /> + </conditions> + <placement x="%col3_x%" y="%wipe_button_y%" /> + <text>Wipe Encryption</text> + <actions> + <action function="set">tw_back=wipe</action> + <action function="set">tw_action=wipe</action> + <action function="set">tw_action_param=DATAMEDIA</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Wipe Encryption from Data?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting Data...</action> + <action function="set">tw_complete_text1=Data Format Complete</action> + <action function="set">tw_slider_text=Swipe to Format Data</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row12_text_y%" placement="5" /> + <text>Press back button to cancel.</text> + </object> + + <object type="slider"> + <text>Swipe to Factory Reset</text> + <actions> + <action function="set">tw_back=wipe</action> + <action function="set">tw_action=wipe</action> + <action function="set">tw_action_param=data</action> + <action function="set">tw_action_text1=Factory Reset...</action> + <action function="set">tw_complete_text1=Factory Reset Complete</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="advancedwipe"> + <object type="template" name="header" /> + + <object type="partitionlist"> + <placement x="%backup_list_x%" y="%backup_list_y%" w="%backup_list_width%" h="%backup_list_height%" /> + <text>Select Partitions to Wipe:</text> + <data name="tw_wipe_list" /> + <listtype name="wipe" /> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col3_x%" y="%backup_storage_y%" w="%button_fill_main_width%" h="%button_fill_half_height%" /> + <text>Repair or Change File System</text> + <actions> + <action function="checkpartitionlist"></action> + <action function="page">checkpartitionlist</action> + </actions> + </object> + + <object type="text"> + <condition var1="partitionlisterror" var2="1" /> + <font resource="font" color="%text_fail_color%"/> + <placement x="%col3_x%" y="%backup_storage_y%" /> + <text>Invalid partition selection</text> + </object> + + <object type="slider"> + <text>Swipe to Wipe</text> + <actions> + <action function="set">tw_back=advancedwipe</action> + <action function="set">tw_action=wipe</action> + <action function="set">tw_action_param=LIST</action> + <action function="set">tw_text1=Wipe Selected Partition(s)?</action> + <action function="set">tw_action_text1=Wiping Partition(s)...</action> + <action function="set">tw_complete_text1=Wipe Complete</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">wipe</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="formatdata"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Format Data will wipe all of your apps, backups, pictures,</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>videos, media, and removes encryption on internal storage.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>This cannot be undone. Press back to cancel.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>Type yes to continue.</text> + </object> + + <object type="input"> + <placement x="%input_x%" y="%row6_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_confirm_formatdata%</text> + <data name="tw_confirm_formatdata" /> + <restrict minlen="3" maxlen="3" allow="yes" /> + <action function="page">formatdata_confirm</action> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">wipe</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="formatdata_confirm"> + <object type="action"> + <condition var1="tw_confirm_formatdata" op="=" var2="yes" /> + <actions> + <action function="set">tw_back=formatdata</action> + <action function="set">tw_action=wipe</action> + <action function="set">tw_action_param=DATAMEDIA</action> + <action function="set">tw_action_text1=Formatting Data...</action> + <action function="set">tw_complete_text1=Data Format Complete</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_confirm_formatdata" op="!=" var2="yes" /> + <action function="page">formatdata</action> + </object> + </page> + + <page name="checkpartitionlist"> + <object type="action"> + <condition var1="tw_check_partition_list" op="=" var2="1" /> + <actions> + <action function="set">partitionlisterror=0</action> + <action function="getpartitiondetails"></action> + <action function="page">partitionoptions</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_check_partition_list" op="!=" var2="1" /> + <actions> + <action function="set">partitionlisterror=1</action> + <action function="set">tw_wipe_list=</action> + <action function="page">advancedwipe</action> + </actions> + </object> + </page> + + <page name="partitionoptions"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%col1_x%" y="%row1_text_y%" /> + <text>Partition Options for: %tw_partition_name%</text> + </object> + + <object type="text"> + <placement x="%col_right_x%" y="%row1_text_y%" placement="1" /> + <text>Mount Point: %tw_partition_mount_point%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Current file system: %tw_partition_file_system%</text> + </object> + + <object type="text"> + <condition var1="tw_partition_is_present" op="!=" var2="0" /> + <placement x="%col2_x%" y="%row3_text_y%" /> + <text>Present: Yes</text> + </object> + + <object type="text"> + <condition var1="tw_partition_is_present" op="=" var2="0" /> + <placement x="%col2_x%" y="%row3_text_y%" /> + <text>Present: No</text> + </object> + + <object type="text"> + <condition var1="tw_partition_removable" op="!=" var2="0" /> + <placement x="%col3_x%" y="%row3_text_y%" /> + <text>Removable: Yes</text> + </object> + + <object type="text"> + <condition var1="tw_partition_removable" op="=" var2="0" /> + <placement x="%col3_x%" y="%row3_text_y%" /> + <text>Removable: No</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row4_text_y%" /> + <text>Size: %tw_partition_size%MB</text> + </object> + + <object type="text"> + <placement x="%col2_x%" y="%row4_text_y%" /> + <text>Used: %tw_partition_used%MB</text> + </object> + + <object type="text"> + <placement x="%col3_x%" y="%row4_text_y%" /> + <text>Free: %tw_partition_free%MB</text> + </object> + + <object type="text"> + <placement x="%col4_x%" y="%row4_text_y%" /> + <text>Backup Size: %tw_partition_backup_size%MB</text> + </object> + + <object type="button"> + <condition var1="tw_partition_can_resize" op="=" var2="1" /> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Resize</text> + <actions> + <action function="set">tw_back=partitionoptions</action> + <action function="set">tw_action=resize</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_has_action2=1</action> + <action function="set">tw_action2=getpartitiondetails</action> + <action function="set">tw_text1=Resize %tw_partition_name%?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Resizing...</action> + <action function="set">tw_complete_text1=Resize Complete</action> + <action function="set">tw_slider_text=Swipe to Resize</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_can_repair" op="=" var2="1" /> + <placement x="%col2_x%" y="%row2_y%" /> + <text>Repair</text> + <actions> + <action function="set">tw_back=partitionoptions</action> + <action function="set">tw_action=repair</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Repair %tw_partition_name%?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Repairing...</action> + <action function="set">tw_complete_text1=Repair Complete</action> + <action function="set">tw_slider_text=Swipe to Repair</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <placement x="%col3_x%" y="%row2_y%" /> + <text>Change File System</text> + <action function="page">selectfilesystem</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advancedwipe</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="refreshfilesystem"> + <object type="action"> + <condition var1="tw_check_partition_list" op="=" var2="1" /> + <actions> + <action function="set">partitionlisterror=0</action> + <action function="getpartitiondetails"></action> + <action function="page">selectfilesystem</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_check_partition_list" op="!=" var2="1" /> + <actions> + <action function="set">partitionlisterror=1</action> + <action function="set">tw_wipe_list=</action> + <action function="page">advancedwipe</action> + </actions> + </object> + </page> + + <page name="selectfilesystem"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%col1_x%" y="%row1_text_y%" /> + <text>Change file system for: %tw_partition_name%</text> + </object> + + <object type="text"> + <placement x="%col_right_x%" y="%row1_text_y%" placement="1" /> + <text>Mount Point: %tw_partition_mount_point%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Current file system: %tw_partition_file_system%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Some ROMs or kernels may not support some file systems. Proceed with caution!</text> + </object> + + <object type="button"> + <condition var1="tw_partition_ext" op="=" var2="1" /> + <placement x="%col1_x%" y="%row1_y%" /> + <text>EXT2</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=ext2</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to EXT2?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_ext" op="=" var2="1" /> + <placement x="%col2_x%" y="%row1_y%" /> + <text>EXT3</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=ext3</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to EXT3?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_ext" op="=" var2="1" /> + <placement x="%col3_x%" y="%row1_y%" /> + <text>EXT4</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=ext4</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to EXT4?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_f2fs" op="=" var2="1" /> + <placement x="%col4_x%" y="%row1_y%" /> + <text>F2FS</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=f2fs</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to F2FS?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_vfat" op="=" var2="1" /> + <placement x="%col2_x%" y="%row2_y%" /> + <text>FAT</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=vfat</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to FAT?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_exfat" op="=" var2="1" /> + <placement x="%col3_x%" y="%row2_y%" /> + <text>exFAT</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=exfat</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to exFAT?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">partitionoptions</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="backup"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Back Up Device</text> + </object> + + <object type="partitionlist"> + <placement x="%backup_list_x%" y="%backup_list_y%" w="%backup_list_width%" h="%backup_list_height%" /> + <text>Select Partitions to Back Up:</text> + <data name="tw_backup_list" /> + <listtype name="backup" /> + </object> + + <object type="text"> + <placement x="%col_right_x%" y="%row2_text_y%" placement="1" /> + <text>Backup Name: %tw_backup_name%</text> + </object> + + <object type="button"> + <placement x="%col3_x%" y="%row1_y%" /> + <text>Refresh Sizes</text> + <actions> + <action function="refreshsizes"></action> + <action function="page">backup</action> + </actions> + </object> + + <object type="button"> + <placement x="%col4_x%" y="%row1_y%" /> + <text>Set Backup Name</text> + <actions> + <action function="set">tw_fileexists=0</action> + <action function="page">backupname1</action> + </actions> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col3_x%" y="%backup_storage_y%" w="%button_fill_main_width%" h="%button_fill_half_height%" /> + <text>Storage: %tw_storage_display_name% (%tw_storage_free_size% MB)</text> + <actions> + <action function="set">tw_back=backup</action> + <action function="page">selectstorage</action> + </actions> + </object> + + <object type="button" style="fillbutton"> + <conditions> + <condition var1="tw_include_encrypted_backup" var2="1" /> + <condition var1="tw_encrypt_backup" var2="0" /> + </conditions> + <placement x="%col3_x%" y="%backup_encrypt_y%" w="%button_fill_main_width%" h="%button_fill_half_height%" /> + <text>No Encryption</text> + <actions> + <action function="page">backupencryption</action> + </actions> + </object> + + <object type="button" style="fillbutton"> + <conditions> + <condition var1="tw_include_encrypted_backup" var2="1" /> + <condition var1="tw_encrypt_backup" var2="1" /> + </conditions> + <placement x="%col3_x%" y="%backup_encrypt_y%" w="%button_fill_main_width%" h="%button_fill_half_height%" /> + <text>Using Encryption</text> + <actions> + <action function="page">backupencryption</action> + </actions> + </object> + + <object type="checkbox"> + <placement x="%col3_x%" y="%nandcheck_row6%" /> + <text>Enable Compression (Requires more time)</text> + <data variable="tw_use_compression" /> + </object> + + <object type="checkbox"> + <placement x="%col3_x%" y="%nandcheck_row7%" /> + <text>Skip MD5 generation on backups</text> + <data variable="tw_skip_md5_generate" /> + </object> + + <object type="checkbox"> + <placement x="%col3_x%" y="%nandcheck_row8%" /> + <font resource="font" color="%text_color%" /> + <text>Disable Free Space Check.</text> + <data variable="tw_disable_free_space" /> + <image checked="checkbox_true" unchecked="checkbox_false" /> + </object> + + <object type="slider"> + <text>Swipe to Back Up</text> + <actions> + <action function="set">tw_operation_state=0</action> + <action function="page">backup_run</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="backupname1"> + <object type="action"> + <condition var1="tw_backup_name" op="=" var2="(Auto Generate)" /> + <action function="generatebackupname"></action> + </object> + + <object type="action"> + <action function="page">backupname2</action> + </object> + </page> + + <page name="backupname2"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Please Enter a Backup Name</text> + </object> + + <object type="input"> + <placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_backup_name%</text> + <data name="tw_backup_name" /> + <restrict minlen="1" maxlen="64" allow=" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_.{}[]" /> + <actions> + <action function="set">tw_filecheck=%tw_backups_folder%/%tw_backup_name%</action> + <action function="set">tw_existpage=backupname2</action> + <action function="set">tw_notexistpage=backup</action> + <action function="page">filecheck</action> + </actions> + </object> + + <object type="text"> + <condition var1="tw_fileexists" var2="1" /> + <placement x="%center_x%" y="%row5_text_y%" placement="5" /> + <font resource="font" color="%text_fail_color%"/> + <text>A backup with that name already exists!</text> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%cancel_button_y%" /> + <text>Append Date</text> + <action function="appenddatetobackupname"></action> + </object> + + <object type="button"> + <placement x="%col3_x%" y="%cancel_button_y%" /> + <text>Cancel / Clear</text> + <actions> + <action function="set">tw_backup_name=(Auto Generate)</action> + <action function="page">backup</action> + </actions> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <actions> + <action function="set">tw_backup_name=(Auto Generate)</action> + <action function="page">main</action> + </actions> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="set">tw_backup_name=(Auto Generate)</action> + <action function="page">backup</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="backupencryption"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Encrypt your backup? Please enter a password:</text> + </object> + + <object type="input"> + <placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_backup_encrypt_display%</text> + <data name="tw_backup_password" mask="*" maskvariable="tw_backup_encrypt_display" /> + <restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" /> + <action function="page">backupencryption2</action> + </object> + + <object type="text"> + <condition var1="tw_password_not_match" var2="1" /> + <font resource="font" color="%text_fail_color%"/> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>Passwords Do Not Match</text> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%cancel_button_y%" /> + <text>Cancel</text> + <actions> + <action function="set">tw_encrypt_backup=0</action> + <action function="set">tw_backup_password=</action> + <action function="set">tw_backup_password2=</action> + <action function="set">tw_backup_encrypt_display=</action> + <action function="set">tw_backup_encrypt_display2=</action> + <action function="page">backup</action> + </actions> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">backup</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="backupencryption2"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Encrypt your backup? Please Enter Password Again:</text> + </object> + + <object type="input"> + <placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_backup_encrypt_display2%</text> + <data name="tw_backup_password2" mask="*" maskvariable="tw_backup_encrypt_display2" /> + <restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" /> + <actions> + <action function="page">checkbackuppassword</action> + </actions> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%cancel_button_y%" /> + <text>Cancel</text> + <actions> + <action function="set">tw_encrypt_backup=0</action> + <action function="set">tw_backup_password=</action> + <action function="set">tw_backup_password2=</action> + <action function="set">tw_backup_encrypt_display=</action> + <action function="set">tw_backup_encrypt_display2=</action> + <action function="page">backup</action> + </actions> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">backup</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="checkbackuppassword"> + <object type="action"> + <condition var1="tw_backup_password2" var2="tw_backup_password" /> + <actions> + <action function="set">tw_encrypt_backup=1</action> + <action function="page">backup</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_backup_password2" op="!=" var2="tw_backup_password" /> + <actions> + <action function="set">tw_encrypt_backup=0</action> + <action function="set">tw_password_not_match=1</action> + <action function="set">tw_backup_password=</action> + <action function="set">tw_backup_password2=</action> + <action function="set">tw_backup_encrypt_display=</action> + <action function="set">tw_backup_encrypt_display2=</action> + <action function="page">backupencryption</action> + </actions> + </object> + </page> + + <page name="backup_run"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_operation% %tw_partition%</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row2_text_y%" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text"> + <placement x="%col_right_x%" y="%row2_text_y%" placement="1" /> + <text>%tw_size_progress%</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="button" style="mediumbutton"> + <placement x="%filemanager_select_x%" y="%filemanager_select_y%" /> + <text>Cancel</text> + <actions> + <action function="cancelbackup"></action> + </actions> + </object> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <action function="nandroid">backup</action> + </object> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_cancel_backup" var2="0" /> + <actions> + <action function="set">tw_back=backup</action> + <action function="set">tw_complete_text1=Backup Complete</action> + <action function="set">tw_show_reboot=1</action> + <action function="page">action_complete</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_cancel_backup" var2="1" /> + <actions> + <action function="set">tw_back=backup</action> + <action function="set">tw_complete_text1=Backup Cancelled</action> + <action function="set">tw_show_reboot=1</action> + <action function="page">action_complete</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="restore"> + <object type="template" name="header" /> + + <object type="button" style="fillbutton"> + <placement x="%col2_x%" y="%zipstorage_text_y%" w="%fileselector_folderonly_width%" h="%button_fill_quarter_height%" /> + <text>Storage: %tw_storage_display_name% (%tw_storage_free_size% MB)</text> + <actions> + <action function="set">tw_back=restore</action> + <action function="page">selectstorage</action> + </actions> + </object> + + <object type="fileselector"> + <placement x="%col2_x%" y="%fileselector_install_y%" w="%fileselector_folderonly_width%" h="%fileselector_install_height%" /> + <text>Select Package to Restore:</text> + <filter folders="1" files="0" nav="0" /> + <path name="tw_backups_folder" /> + <data name="tw_restore" default="" /> + <selection name="tw_restore_name" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="action"> + <condition var1="tw_restore" op="modified" /> + <actions> + <action function="readBackup"></action> + <action function="page">restore_read</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="restore_read"> + <object type="action"> + <condition var1="tw_restore_encrypted" var2="1" /> + <actions> + <action function="set">tw_password_fail=0</action> + <action function="page">restore_decrypt</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_restore_encrypted" var2="0" /> + <actions> + <action function="page">restore_select</action> + </actions> + </object> + </page> + + <page name="restore_decrypt"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Backup encrypted. Please enter your password:</text> + </object> + + <object type="input"> + <placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_restore_display%</text> + <data name="tw_restore_password" mask="*" maskvariable="tw_restore_display" /> + <restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" /> + <actions> + <action function="page">try_restore_decrypt</action> + </actions> + </object> + + <object type="text"> + <condition var1="tw_password_fail" var2="1" /> + <font resource="font" color="%text_fail_color%" /> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>Password Failed, Please Try Again</text> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%cancel_button_y%" /> + <text>Cancel</text> + <actions> + <action function="set">tw_page_done=1</action> + <action function="page">restore</action> + </actions> + </object> + + <object type="button"> + <placement x="%col3_x%" y="%cancel_button_y%" /> + <text>Delete</text> + <actions> + <action function="set">tw_back=restore</action> + <action function="set">tw_action=cmd</action> + <action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf "%tw_restore_name%"</action> + <action function="set">tw_text1=Delete Backup? %tw_restore_name%</action> + <action function="set">tw_text2=This cannot be undone!</action> + <action function="set">tw_action_text1=Deleting Backup...</action> + <action function="set">tw_complete_text1=Backup Delete Complete</action> + <action function="set">tw_slider_text=Swipe to Delete</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">restore</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="try_restore_decrypt"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Trying Decryption with Your Password</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <action function="decrypt_backup"></action> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" op="!=" var2="0" /> + </conditions> + <actions> + <action function="set">tw_password_fail=1</action> + <action function="page">restore_decrypt</action> + </actions> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" op="=" var2="0" /> + </conditions> + <actions> + <action function="set">tw_page_done=1</action> + <action function="page">restore_select</action> + </actions> + </object> + </page> + + <page name="restore_select"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Package to Restore: %tw_restore_name%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Package Date: %tw_restore_file_date%</text> + </object> + + <object type="partitionlist"> + <placement x="%backup_list_x%" y="%restore_list_y%" w="%backup_list_width%" h="%restore_list_height%" /> + <text>Select Partitions to Restore:</text> + <data name="tw_restore_list" selectedlist="tw_restore_selected" /> + <listtype name="restore" /> + </object> + + <object type="checkbox"> + <placement x="%col3_x%" y="%nandcheck_row6%" /> + <text>Enable MD5 checking of backup files</text> + <data variable="tw_skip_md5_check" /> + </object> + + <object type="button"> + <placement x="%col4_x%" y="%row1_y%" /> + <text>Rename Backup</text> + <actions> + <action function="set">tw_backup_rename=</action> + <action function="set">tw_fileexists=0</action> + <action function="page">renamebackup</action> + </actions> + </object> + + <object type="button"> + <placement x="%col3_x%" y="%row1_y%" /> + <text>Delete Backup</text> + <actions> + <action function="set">tw_back=restore</action> + <action function="set">tw_action=cmd</action> + <action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf "%tw_restore_name%"</action> + <action function="set">tw_text1=Delete Backup? %tw_restore_name%</action> + <action function="set">tw_text2=This cannot be undone!</action> + <action function="set">tw_action_text1=Deleting Backup...</action> + <action function="set">tw_complete_text1=Backup Delete Complete</action> + <action function="set">tw_slider_text=Swipe to Delete</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="slider"> + <text>Swipe to Restore</text> + <action function="page">restore_run</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">restore</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="renamebackup"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Please Enter a New Backup Name</text> + </object> + + <object type="input"> + <placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_backup_rename%</text> + <data name="tw_backup_rename" /> + <restrict minlen="1" maxlen="64" allow=" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_.{}[]" /> + <actions> + <action function="set">tw_back=restore</action> + <action function="set">tw_action=cmd</action> + <action function="set">tw_action_param=cd %tw_backups_folder% && mv "%tw_restore_name%" "%tw_backup_rename%"</action> + <action function="set">tw_text1=Rename Backup?</action> + <action function="set">tw_text2=This cannot be undone!</action> + <action function="set">tw_action_text1=Renaming Backup...</action> + <action function="set">tw_complete_text1=Backup Rename Complete</action> + <action function="set">tw_slider_text=Swipe to Rename</action> + <action function="set">tw_filecheck=%tw_backups_folder%/%tw_backup_rename%</action> + <action function="set">tw_existpage=renamebackup</action> + <action function="set">tw_notexistpage=confirm_action</action> + <action function="page">filecheck</action> + </actions> + </object> + + <object type="text"> + <condition var1="tw_fileexists" var2="1" /> + <placement x="%center_x%" y="%row5_text_y%" placement="5" /> + <font resource="font" color="%text_fail_color%" /> + <text>A backup with that name already exists!</text> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%cancel_button_y%" /> + <text>Cancel</text> + <action function="page">restore_select</action> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">restore_select</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="restore_run"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_operation% %tw_partition%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <actions> + <action function="set">tw_back=restore_select</action> + <action function="set">tw_complete_text1=Restore Complete</action> + <action function="set">tw_show_reboot=1</action> + <action function="page">action_complete</action> + </actions> + </object> + + <object type="action"> + <action function="nandroid">restore</action> + </object> + </page> + + <page name="settings"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Settings</text> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row2_text_y%" /> + <text>Zip file signature verification?</text> + <data variable="tw_signed_zip_verify" />> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row3_text_y%" /> + <text>Use rm -rf instead of formatting?</text> + <data variable="tw_rm_rf" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row4_text_y%" /> + <text>Skip MD5 generation on backups</text> + <data variable="tw_skip_md5_generate" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row5_text_y%" /> + <text>Enable MD5 checking of backup files</text> + <data variable="tw_skip_md5_check" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row6_text_y%" /> + <text>Use 24-hour clock</text> + <data variable="tw_military_time" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row7_text_y%" /> + <text>Simulate most actions for theme testing</text> + <data variable="tw_simulate_actions" /> + </object> + + <object type="checkbox"> + <condition var1="tw_simulate_actions" var2="1" /> + <placement x="%col1_x%" y="%row8_text_y%" /> + <text>Simulate failure for actions</text> + <data variable="tw_simulate_fail" /> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Time Zone</text> + <action function="page">timezone</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row2_y%" /> + <text>Restore Defaults</text> + <action function="restoredefaultsettings"></action> + </object> + + <object type="button"> + <placement x="%col3_x%" y="%row2_y%" /> + <text>Vibration Duration</text> + <action function="page">Vibrate</action> + </object> + + <object type="button"> + <placement x="%col4_x%" y="%row2_y%" /> + <text>Screen</text> + <action function="page">screen</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="timezone"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Select Time Zone</text> + </object> + + <object type="listbox" style="scrolllist"> + <placement x="%listbox_x%" y="%listbox_y%" w="%listbox_width%" h="%listbox_tz_height%" /> + <text>Select Time Zone:</text> + <icon selected="radio_true" unselected="radio_false" /> + <data name="tw_time_zone_guisel" /> + <listitem name="(UTC -11) Samoa, Midway Island">BST11;BDT</listitem> + <listitem name="(UTC -10) Hawaii">HST10;HDT</listitem> + <listitem name="(UTC -9) Alaska">AST9;ADT</listitem> + <listitem name="(UTC -8) Pacific Time">PST8;PDT,M3.2.0,M11.1.0</listitem> + <listitem name="(UTC -7) Mountain Time">MST7;MDT,M3.2.0,M11.1.0</listitem> + <listitem name="(UTC -6) Central Time">CST6;CDT,M3.2.0,M11.1.0</listitem> + <listitem name="(UTC -5) Eastern Time">EST5;EDT,M3.2.0,M11.1.0</listitem> + <listitem name="(UTC -4) Atlantic Time">AST4;ADT</listitem> + <listitem name="(UTC -3) Brazil, Buenos Aires">GRNLNDST3;GRNLNDDT</listitem> + <listitem name="(UTC -2) Mid-Atlantic">FALKST2;FALKDT</listitem> + <listitem name="(UTC -1) Azores, Cape Verde">AZOREST1;AZOREDT</listitem> + <listitem name="(UTC 0) London, Dublin, Lisbon">GMT0;BST,M3.5.0,M10.5.0</listitem> + <listitem name="(UTC +1) Berlin, Brussels, Paris">CET-1;CEST,M3.5.0,M10.5.0</listitem> + <listitem name="(UTC +2) Athens, Istanbul, South Africa">WET-2;WET,M3.5.0,M10.5.0</listitem> + <listitem name="(UTC +3) Moscow, Baghdad">SAUST-3;SAUDT</listitem> + <listitem name="(UTC +4) Abu Dhabi, Tbilisi, Muscat">WST-4;WDT</listitem> + <listitem name="(UTC +5) Yekaterinburg, Islamabad">PAKST-5;PAKDT</listitem> + <listitem name="(UTC +6) Almaty, Dhaka, Colombo">TASHST-6;TASHDT</listitem> + <listitem name="(UTC +7) Bangkok, Hanoi, Jakarta">THAIST-7;THAIDT</listitem> + <listitem name="(UTC +8) Beijing, Singapore, Hong Kong">TAIST-8;TAIDT</listitem> + <listitem name="(UTC +9) Tokyo, Seoul, Yakutsk">JST-9;JSTDT</listitem> + <listitem name="(UTC +10) Eastern Australia, Guam">EET-10;EETDT</listitem> + <listitem name="(UTC +11) Vladivostok, Solomon Islands">MET-11;METDT</listitem> + <listitem name="(UTC +12) Auckland, Wellington, Fiji">NZST-12;NZDT</listitem> + </object> + + <object type="checkbox"> + <placement x="%col1_medium_x%" y="%row11_text_y%" /> + <text>Do you use daylight savings time (DST)?</text> + <data variable="tw_time_zone_guidst" /> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row13_text_y%" placement="5" /> + <text>Offset (usually 0): %tw_time_zone_guioffset%</text> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%col1_medium_x%" y="%row_offsetmedium_y%" /> + <text>0</text> + <action function="set">tw_time_zone_guioffset=0</action> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%col2_medium_x%" y="%row_offsetmedium_y%" /> + <text>15</text> + <action function="set">tw_time_zone_guioffset=15</action> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%col3_medium_x%" y="%row_offsetmedium_y%" /> + <text>30</text> + <action function="set">tw_time_zone_guioffset=30</action> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%col4_medium_x%" y="%row_offsetmedium_y%" /> + <text>45</text> + <action function="set">tw_time_zone_guioffset=45</action> + </object> + + <object type="button"> + <placement x="%col4_x%" y="%row2_y%" /> + <text>Set Time Zone</text> + <action function="setguitimezone"></action> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row17_text_y%" placement="5" /> + <text>Current Time Zone: %tw_time_zone%</text> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">settings</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="screen"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Screen Settings</text> + </object> + + <object type="button"> + <placement x="%slidervalue_x%" y="%row3_text_y%" /> + <condition var1="tw_screen_timeout_secs" op="=" var2="0" /> + <condition var1="tw_no_screen_timeout" op="!=" var2="1" /> + <text>Enable screen timeout.</text> + <image resource="checkbox_false" /> + <action function="set">tw_screen_timeout_secs=60</action> + </object> + + <object type="button"> + <placement x="%slidervalue_x%" y="%row3_text_y%" /> + <condition var1="tw_screen_timeout_secs" op="!=" var2="0" /> + <condition var1="tw_no_screen_timeout" op="!=" var2="1" /> + <text>Enable screen timeout.</text> + <image resource="checkbox_true" /> + <action function="set">tw_screen_timeout_secs=0</action> + </object> + + <object type="slidervalue"> + <conditions> + <condition var1="tw_screen_timeout_secs" op="!=" var2="0" /> + <condition var1="tw_no_screen_timeout" op="!=" var2="1" /> + </conditions> + <placement x="slidervalue_x" y="%row5_text_y%" w="%slidervalue_w%" /> + <text>Screen timeout in seconds:</text> + <data variable="tw_screen_timeout_secs" min="15" max="300" /> + </object> + + <object type="slidervalue"> + <condition var1="tw_has_brightnesss_file" var2="1" /> + <placement x="slidervalue_x" y="%row12_text_y%" w="%slidervalue_w%" /> + <text>Brightness: %tw_brightness_pct%%</text> + <data variable="tw_brightness_pct" min="10" max="100" /> + <actions> + <action function="set">tw_brightness=%tw_brightness_max%</action> + <action function="compute">tw_brightness*%tw_brightness_pct%</action> + <action function="compute">tw_brightness/100</action> + <action function="setbrightness">%tw_brightness%</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">settings</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="Vibrate"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Vibration Settings :</text> + </object> + + <object type="slidervalue"> + <placement x="slidervalue_x" y="%row3_text_y%" w="%slidervalue_w%" /> + <text>Button Vibration:</text> + <data variable="tw_button_vibrate" min="0" max="300" /> + <colors line="%slidervalue_line_clr%" slider="%slidervalue_slider_clr%" /> + </object> + + <object type="slidervalue"> + <placement x="slidervalue_x" y="%row7_text_y%" w="%slidervalue_w%" /> + <text>Keyboard Vibration:</text> + <data variable="tw_keyboard_vibrate" min="0" max="300" /> + <colors line="%slidervalue_line_clr%" slider="%slidervalue_slider_clr%" /> + </object> + + <object type="slidervalue"> + <placement x="slidervalue_x" y="%row11_text_y%" w="%slidervalue_w%" /> + <text>Action Vibration:</text> + <data variable="tw_action_vibrate" min="0" max="500" /> + <colors line="%slidervalue_line_clr%" slider="%slidervalue_slider_clr%" /> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">settings</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="advanced"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Advanced</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row1_y%" /> + <text>Copy Log to SD</text> + <actions> + <action function="set">tw_back=advanced</action> + <action function="set">tw_action=copylog</action> + <action function="set">tw_text1=Copy Log to SD Card?</action> + <action function="set">tw_action_text1=Copying Log to SD Card...</action> + <action function="set">tw_complete_text1=Log Copy Complete</action> + <action function="set">tw_slider_text=Swipe to Confirm</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row1_y%" /> + <text>Fix Permissions</text> + <action function="page">fixperms</action> + </object> + + <object type="button"> + <placement x="%col3_x%" y="%row1_y%" /> + <text>Terminal Command</text> + <action function="page">terminalfolder</action> + </object> + + <object type="button"> + <placement x="%col4_x%" y="%row1_y%" /> + <text>ADB Sideload</text> + <action function="page">sideload</action> + </object> + + <object type="button"> + <condition var1="tw_allow_partition_sdcard" var2="1" /> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Partition SD Card</text> + <action function="page">partsdcard</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row2_y%" /> + <text>File Manager</text> + <action function="page">filemanagerlist</action> + </object> + + <object type="button"> + <placement x="%col3_x%" y="%row2_y%" /> + <text>Reload Theme</text> + <action function="reload"></action> + </object> + + <object type="button"> + <condition var1="tw_show_dumlock" var2="1" /> + <placement x="%col4_x%" y="%row2_y%" /> + <text>HTC Dumlock</text> + <action function="page">htcdumlock</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="partsdcard"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Partition SD Card</text> + </object> + + <object type="button"> + <placement x="%col1_sdext_x%" y="%row1_sdext_y%" /> + <text></text> + <image resource="minus_button" /> + <action function="addsubtract">tw_sdext_size-128</action> + </object> + + <object type="button"> + <placement x="%col2_sdext_x%" y="%row1_sdext_y%" /> + <text></text> + <image resource="plus_button" /> + <action function="addsubtract">tw_sdext_size+128</action> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row_extsize_y%" placement="5" /> + <text>EXT Size: %tw_sdext_size%</text> + </object> + + <object type="button"> + <placement x="%col1_sdext_x%" y="%row2_sdext_y%" /> + <text></text> + <image resource="minus_button" /> + <action function="addsubtract">tw_swap_size-32</action> + </object> + + <object type="button"> + <placement x="%col2_sdext_x%" y="%row2_sdext_y%" /> + <text></text> + <image resource="plus_button" /> + <action function="addsubtract">tw_swap_size+32</action> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row_swapsize_y%" placement="5" /> + <text>Swap Size: %tw_swap_size%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row8_text_y%" placement="5" /> + <text>File system: %tw_sdpart_file_system%</text> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%col2_medium_x%" y="%row4_medium_y%" /> + <text>EXT3</text> + <action function="set">tw_sdpart_file_system=ext3</action> + </object> + + <object type="button" style="mediumbutton"> + <condition var1="tw_sdext_disable_ext4" var2="0" /> + <placement x="%col3_medium_x%" y="%row4_medium_y%" /> + <text>EXT4</text> + <action function="set">tw_sdpart_file_system=ext4</action> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row12_text_y%" placement="5" /> + <text>You will lose all files on your SD card!</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row13_text_y%" placement="5" /> + <text>This action cannot be undone!</text> + </object> + + <object type="slider"> + <text>Swipe to Confirm Partition</text> + <actions> + <action function="set">tw_back=partsdcard</action> + <action function="set">tw_action=partitionsd</action> + <action function="set">tw_has_action2=1</action> + <action function="set">tw_action2=set</action> + <action function="set">tw_action2_param=tw_zip_location=/sdcard</action> + <action function="set">tw_action_text1=Partitioning SD Card...</action> + <action function="set">tw_action_text2=This will take a few minutes.</action> + <action function="set">tw_complete_text1=Partitioning Complete</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + + <object type="template" name="footer" /> + </page> + + + <page name="htcdumlock"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>HTC Dumlock</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row1_y%" /> + <text>Restore Original Boot</text> + <actions> + <action function="set">tw_back=htcdumlock</action> + <action function="set">tw_action=htcdumlockrestoreboot</action> + <action function="set">tw_text1=Restore original boot image?</action> + <action function="set">tw_action_text1=Restoring Original Boot...</action> + <action function="set">tw_complete_text1=Restore Original Boot Complete</action> + <action function="set">tw_slider_text=Swipe to Confirm</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row1_y%" /> + <text>Reflash Recovery->Boot</text> + <actions> + <action function="set">tw_back=htcdumlock</action> + <action function="set">tw_action=htcdumlockreflashrecovery</action> + <action function="set">tw_text1=Reflash recovery to boot?</action> + <action function="set">tw_action_text1=Flashing recovery to boot...</action> + <action function="set">tw_complete_text1=Recovery Flash to Boot Complete</action> + <action function="set">tw_slider_text=Swipe to Confirm</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Install HTC Dumlock</text> + <actions> + <action function="set">tw_back=htcdumlock</action> + <action function="set">tw_action=installhtcdumlock</action> + <action function="set">tw_text1=Install HTC dumlock files to ROM?</action> + <action function="set">tw_action_text1=Installing HTC Dumlock...</action> + <action function="set">tw_complete_text1=HTC Dumlock Install Complete</action> + <action function="set">tw_slider_text=Swipe to Confirm</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="lock"> + <background color="#000000A0" /> + + <object type="image"> + <image resource="unlock-icon" /> + <placement x="%center_x%" y="%lock_y%" placement="4" /> + </object> + + <object type="slider"> + <text>Swipe to Unlock</text> + <action function="overlay"></action> + </object> + </page> + + + <page name="filemanagerlist"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5"/> + <text>File Manager: Select a File or Folder</text> + </object> + + <object type="fileselector"> + <placement x="%fileselector_folder_x%" y="%fileselector_install_y%" w="%fileselector_folder_width%" h="%fileselector_install_height%" /> + <text>Folders:</text> + <filter folders="1" files="0" /> + <path name="tw_file_location1" default="/sdcard" /> + <data name="select" /> + <selection name="tw_selection1" /> + </object> + + <object type="fileselector"> + <placement x="%fileselector_file_x%" y="%fileselector_install_y%" w="%fileselector_file_width%" h="%fileselector_install_height%" /> + <text>%tw_file_location1%</text> + <filter folders="0" files="1" /> + <path name="tw_file_location1" default="/" /> + <data name="tw_filename1" /> + <selection name="tw_selection1" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="action"> + <actions> + <action function="set">tw_fm_type=File</action> + <action function="set">tw_fm_isfolder=0</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + + <object type="action"> + <condition var1="tw_filename1" op="modified" /> + <actions> + <action function="page">filemanageroptions</action> + </actions> + </object> + + <object type="button"> + <placement x="%filemanager_select_x%" y="%filemanager_select_y%" /> + <text>Select Folder</text> + <actions> + <action function="set">tw_filename1=tw_file_location1</action> + <action function="set">tw_fm_isfolder=1</action> + <action function="set">tw_fm_type=Folder</action> + <action function="page">filemanageroptions</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="filemanageroptions"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5"/> + <text>%tw_fm_type% Selected:</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5"/> + <text>%tw_filename1%</text> + </object> + + <object type="button"> + <condition var1="tw_fm_isfolder" var2="0" /> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Copy File</text> + <actions> + <action function="set">tw_filemanager_command=cp</action> + <action function="set">tw_fm_text1=Copying</action> + <action function="page">choosedestinationfolder</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_fm_isfolder" var2="1" /> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Copy Folder</text> + <actions> + <action function="set">tw_filemanager_command=cd "%tw_file_location1%" && cd .. && cp -R</action> + <action function="set">tw_fm_text1=Copying</action> + <action function="page">choosedestinationfolder</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row2_y%" /> + <text>Move</text> + <actions> + <action function="set">tw_filemanager_command=mv</action> + <action function="set">tw_fm_text1=Moving</action> + <action function="page">choosedestinationfolder</action> + </actions> + </object> + + <object type="button"> + <placement x="%col3_x%" y="%row2_y%" /> + <text>chmod 755</text> + <actions> + <action function="set">tw_filemanager_command=chmod 755</action> + <action function="set">tw_fm_text1=chmod 755</action> + <action function="set">tw_fm_text2=</action> + <action function="set">tw_fm_text3=</action> + <action function="set">tw_include_text3=0</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + + <object type="button"> + <placement x="%col4_x%" y="%row2_y%" /> + <text>chmod</text> + <actions> + <action function="set">tw_filemanager_rename=0000</action> + <action function="set">tw_fm_text2=</action> + <action function="set">tw_fm_text3=</action> + <action function="set">tw_include_text3=0</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerchmod</action> + </actions> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row1_y%" /> + <text>Delete</text> + <actions> + <action function="set">tw_filemanager_command=rm -rf</action> + <action function="set">tw_fm_text1=Deleting</action> + <action function="set">tw_fm_text2=</action> + <action function="set">tw_fm_text3=</action> + <action function="set">tw_include_text3=0</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_fm_isfolder" var2="0" /> + <placement x="%col4_x%" y="%row1_y%" /> + <text>Rename File</text> + <actions> + <action function="set">tw_filemanager_rename=tw_selection1</action> + <action function="set">tw_fm_text1=Renaming</action> + <action function="set">tw_filemanager_command=mv</action> + <action function="page">filemanagerrenamefile</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_fm_isfolder" var2="1" /> + <placement x="%col4_x%" y="%row1_y%" /> + <text>Rename Folder</text> + <actions> + <action function="set">tw_filemanager_rename=tw_selection1</action> + <action function="set">tw_fm_text1=Renaming</action> + <action function="set">tw_filemanager_command=cd "%tw_file_location1%" && cd .. && mv</action> + <action function="page">filemanagerrenamefolder</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">filemanagerlist</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="choosedestinationfolder"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5"/> + <text>Browse to Destination Folder & Press Select</text> + </object> + + <object type="fileselector"> + <placement x="%col2_x%" y="%fileselector_install_y%" w="%fileselector_folderonly_width%" h="%fileselector_install_height%" /> + <text>%tw_file_location2%</text> + <background color="%fileselector_background%" /> + <filter folders="1" files="0" /> + <path name="tw_file_location2" default="/sdcard" /> + <data name="tw_filename2" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">filemanageroptions</action> + </object> + + <object type="button"> + <placement x="%filemanager_select_x%" y="%filemanager_select_y%" /> + <text>Select Folder</text> + <actions> + <action function="set">tw_fm_text2=to</action> + <action function="set">tw_fm_text3=%tw_file_location2%</action> + <action function="set">tw_include_text3=1</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="filemanagerrenamefile"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <font resource="font" color="%text_color%" /> + <text>Please Enter a New %tw_fm_type% Name</text> + </object> + + <object type="input"> + <placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_filemanager_rename%</text> + <data name="tw_filemanager_rename" /> + <restrict minlen="1" maxlen="128" /> + <actions> + <action function="set">tw_fm_text2=to</action> + <action function="set">tw_fm_text3="%tw_file_location1%/%tw_filemanager_rename%"</action> + <action function="set">tw_include_text3=1</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%cancel_button_y%" /> + <text>Cancel</text> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="filemanagerrenamefolder"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Please Enter a New %tw_fm_type% Name</text> + </object> + + <object type="input"> + <placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_filemanager_rename%</text> + <data name="tw_filemanager_rename" /> + <restrict minlen="1" maxlen="128" /> + <actions> + <action function="set">tw_fm_text2=to</action> + <action function="set">tw_fm_text3=%tw_filemanager_rename%</action> + <action function="set">tw_include_text3=1</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%cancel_button_y%" /> + <text>Cancel</text> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="filemanagerchmod"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Please Enter New Permissions</text> + </object> + + <object type="input"> + <placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_filemanager_rename%</text> + <data name="tw_filemanager_rename" /> + <restrict minlen="3" maxlen="4" allow="0123456789" /> + <actions> + <action function="set">tw_filemanager_command=chmod %tw_filemanager_rename%</action> + <action function="set">tw_fm_text1=chmod %tw_filemanager_rename%</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%cancel_button_y%" /> + <text>Cancel</text> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="filemanagerconfirm"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5"/> + <text>%tw_fm_text1%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5"/> + <text>%tw_filename1%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5"/> + <text>%tw_fm_text2%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row4_text_y%" placement="5"/> + <text>%tw_fm_text3%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row10_text_y%" placement="5"/> + <text>Press back button to cancel.</text> + </object> + + <object type="slider"> + <action function="page">filemanageracction</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">%tw_back%</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="filemanageracction"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_fm_text1%</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" var2="0" /> + </conditions> + <actions> + <action function="set">tw_back=filemanagerlist</action> + <action function="set">tw_complete_text1=File Operation Complete</action> + <action function="page">action_complete</action> + </actions> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" op="!=" var2="0" /> + </conditions> + <actions> + <action function="set">tw_complete_text1=File Operation Complete</action> + <action function="page">action_complete</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_include_text3" var2="0" /> + <actions> + <action function="cmd">%tw_filemanager_command% "%tw_filename1%"</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_include_text3" var2="1" /> + <actions> + <action function="cmd">%tw_filemanager_command% "%tw_filename1%" "%tw_fm_text3%"</action> + </actions> + </object> + </page> + + <page name="decrypt"> + <object type="template" name="header" /> + + <object type="action"> + <condition var1="tw_crypto_pwtype" var2="2" /> + <action function="page">decrypt_pattern</action> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Please Enter Your Password</text> + </object> + + <object type="input"> + <placement x="%input_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_crypto_display%</text> + <data name="tw_crypto_password" mask="*" maskvariable="tw_crypto_display" /> + <restrict minlen="1" maxlen="254" /> + <actions> + <action function="page">trydecrypt</action> + </actions> + </object> + + <object type="text"> + <condition var1="tw_password_fail" var2="1" /> + <font resource="font" color="%text_fail_color%" /> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>Password Failed, Please Try Again</text> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%cancel_button_y%" /> + <text>Cancel</text> + <actions> + <action function="set">tw_page_done=1</action> + <action function="page">main</action> + </actions> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="template" name="footer" /> + </page> + + <page name="decrypt_pattern"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Please Enter Your Pattern</text> + </object> + + <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" /> + <text>Pattern Failed, Please Try Again</text> + </object> + + <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%" /> + <line color="%pattern_line_color%" width="%pattern_line_width%" /> + <data name="tw_crypto_password"/> + <action function="page">trydecrypt</action> + </object> + + <object type="button"> + <placement x="%col4_x%" y="%cancel_button_y%" /> + <text>Cancel</text> + <actions> + <action function="set">tw_page_done=1</action> + <action function="page">main</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="trydecrypt"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Trying Decryption with Your Password</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <action function="decrypt"></action> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" op="!=" var2="0" /> + </conditions> + <actions> + <action function="set">tw_password_fail=1</action> + <action function="page">decrypt</action> + </actions> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" op="=" var2="0" /> + </conditions> + <actions> + <action function="set">tw_page_done=1</action> + <action function="page">main</action> + </actions> + </object> + </page> + + <page name="terminalfolder"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5"/> + <text>Browse to Starting Folder</text> + </object> + + <object type="fileselector"> + <placement x="%col2_x%" y="%fileselector_install_y%" w="%fileselector_folderonly_width%" h="%fileselector_install_height%" /> + <text>%tw_terminal_location%</text> + <filter folders="1" files="0" /> + <path name="tw_terminal_location" default="/" /> + <data name="tw_terminal" /> + <selection name="tw_terminal_selection" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + + <object type="button"> + <placement x="%filemanager_select_x%" y="%filemanager_select_y%" /> + <text>Select Folder</text> + <actions> + <action function="page">terminalcommand</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="terminalcommand"> + <background color="#000000FF" /> + + <object type="console"> + <placement x="%console_x%" y="%terminal_console_y%" w="%console_width%" h="%terminal_console_height%" /> + </object> + + <object type="text"> + <placement x="%input_x%" y="%terminal_text_y%" placement="0" /> + <text>Starting Path: %tw_terminal_location%</text> + </object> + + <object type="input"> + <condition var1="tw_terminal_state" var2="0" /> + <placement x="%input_x%" y="%terminal_text_y%" w="%terminal_input_width%" h="%input_height%" placement="0" /> + <text>%tw_terminal_command%</text> + <font resource="fixed" color="%text_color%" /> + <data name="tw_terminal_command" /> + <restrict minlen="1" /> + <action function="terminalcommand">%tw_terminal_command%</action> + </object> + + <object type="button" style="mediumbutton"> + <condition var1="tw_terminal_state" var2="1" /> + <placement x="%filemanager_select_x%" y="%terminal_button_y%" /> + <text>KILL</text> + <action function="killterminal"></action> + </object> + + <object type="button"> + <placement x="%home_button_x%" y="%terminal_button_y%" /> + <text></text> + <image resource="home_icon" /> + <condition var1="tw_busy" var2="0" /> + <action function="key">home</action> + </object> + + <object type="button"> + <placement x="%back_button_x%" y="%terminal_button_y%" /> + <text></text> + <image resource="back_icon" /> + <condition var1="tw_busy" var2="0" /> + <action function="key">back</action> + </object> + + <object type="action"> + <touch key="power" /> + <action function="overlay">lock</action> + </object> + + <object type="action"> + <touch key="power+voldown" /> + <action function="screenshot" /> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">terminalfolder</action> + </object> + </page> + + <page name="sideload"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5"/> + <text>ADB Sideload</text> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row3_text_y%" /> + <text>Wipe Dalvik Cache.</text> + <data variable="tw_wipe_dalvik" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row4_text_y%" /> + <text>Wipe Cache.</text> + <data variable="tw_wipe_cache" /> + </object> + + <object type="slider"> + <text>Swipe to Start Sideload</text> + <actions> + <action function="set">tw_back=advanced</action> + <action function="set">tw_action=adbsideload</action> + <action function="set">tw_action_text1=ADB Sideload</action> + <action function="set">tw_action_text2=Usage: adb sideload filename.zip</action> + <action function="set">tw_complete_text1=ADB Sideload Complete</action> + <action function="set">tw_has_cancel=1</action> + <action function="set">tw_show_reboot=1</action> + <action function="set">tw_cancel_action=adbsideloadcancel</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="fixperms"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5"/> + <text>Fix Permissions</text> + </object> + + <object type="text"> + <placement x="%col2_x%" y="%row2_text_y%" /> + <text>Note: Fixing permissions is rarely needed.</text> + </object> + + <object type="checkbox"> + <placement x="%col2_x%" y="%row3_text_y%" /> + <text>Also fix SELinux contexts</text> + <data variable="tw_fixperms_restorecon" /> + </object> + + <object type="text"> + <placement x="%col2_x%" y="%row4_text_y%" /> + <text>Fixing SELinux contexts may cause your device to not boot properly.</text> + </object> + + <object type="slider"> + <text>Swipe to Fix Permissions</text> + <actions> + <action function="set">tw_back=advanced</action> + <action function="set">tw_action=fixpermissions</action> + <action function="set">tw_action_text1=Fixing Permissions...</action> + <action function="set">tw_complete_text1=Fix Permissions Complete</action> + <action function="set">tw_slider_text=Swipe to Confirm</action> + <action function="set">tw_show_reboot=1</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="installsu"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5"/> + <text>Install SuperSU?</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5"/> + <text>Your device does not appear to be rooted.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5"/> + <text>Install SuperSU now? This will root your device.</text> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row2_medium_y%" /> + <text>Do Not Install</text> + <action function="set">tw_page_done=1</action> + </object> + + <object type="slider"> + <text>Swipe to Install</text> + <actions> + <action function="set">tw_action=installsu</action> + <action function="set">tw_action_text1=Installing SuperSU</action> + <action function="set">tw_action_text2=</action> + <action function="page">singleaction_page</action> + </actions> + </object> + </page> + + <page name="system_readonly"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Keep System Read Only?</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>TWRP can leave your system partition unmodified to make it easier for you to take official updates.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>TWRP will be unable to prevent the stock ROM from replacing TWRP and will not offer to root your device.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>Installing zips or performing adb operations may still modify the system partition.</text> + </object> + + <object type="checkbox"> + <condition var1="tw_is_encrypted" var2="0" /> + <placement x="%col1_x%" y="%row5_text_y%" /> + <text>Never show this screen during boot again</text> + <data variable="tw_never_show_system_ro_page" /> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row7_text_y%" /> + <text>Keep Read Only</text> + <actions> + <action function="mountsystemtoggle">1</action> + <action function="set">tw_page_done=1</action> + <action function="page">%tw_back%</action> + </actions> + </object> + + <object type="slider"> + <text>Swipe to Allow Modifications</text> + <actions> + <action function="mountsystemtoggle">0</action> + <action function="set">tw_page_done=1</action> + <action function="page">%tw_back%</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + </pages> +</recovery> diff --git a/gui/devices/portrait/res/portrait.xml b/gui/devices/portrait/res/portrait.xml new file mode 100644 index 000000000..969044c19 --- /dev/null +++ b/gui/devices/portrait/res/portrait.xml @@ -0,0 +1,3740 @@ +<?xml version="1.0"?> + +<recovery> + <styles> + <style name="buttontext"> + <highlight color="%highlight_color%" /> + <font resource="font" color="%button_text_color%" /> + </style> + + <style name="button"> + <style name="buttontext" /> + <image resource="main_button" /> + </style> + + <style name="mediumbutton"> + <style name="buttontext" /> + <image resource="medium_button" /> + </style> + + <style name="fillbutton"> + <style name="buttontext" /> + <fill color="%button_fill_color%" /> + </style> + + <style name="rebootsystem"> + <condition var1="tw_reboot_system" var2="1" /> + <style name="button" /> + <text>Reboot System</text> + <actions> + <action function="set">tw_back=main2</action> + <action function="set">tw_action=reboot</action> + <action function="set">tw_action_param=system</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=No OS Installed! Are you</action> + <action function="set">tw_text2=sure you wish to reboot?</action> + <action function="set">tw_text3=</action> + <action function="set">tw_text4=</action> + <action function="set">tw_action_text1=Rebooting...</action> + <action function="set">tw_action_text2=</action> + <action function="set">tw_complete_text1=Rebooting...</action> + <action function="set">tw_slider_text=Swipe to Reboot</action> + <action function="page">rebootcheck</action> + </actions> + </style> + + <style name="scrolllist"> + <highlight color="%fileselector_highlight_color%" /> + <header background="%fileselector_header_background%" textcolor="%fileselector_header_textcolor%" separatorcolor="%fileselector_header_separatorcolor%" separatorheight="%fileselector_header_separatorheight%" /> + <fastscroll linecolor="%fastscroll_linecolor%" rectcolor="%fastscroll_rectcolor%" w="%fastscroll_w%" linew="%fastscroll_linew%" rectw="%fastscroll_rectw%" recth="%fastscroll_recth%" /> + <separator color="%fileselector_separatorcolor%" height="%fileselector_separatorheight%" /> + <background color="%fileselector_background%" /> + <font resource="filelist" spacing="%fileselector_spacing%" color="%text_color%" highlightcolor="%fileselector_highlight_font_color%" /> + </style> + + <style name="fileselector"> + <style name="scrolllist" /> + <icon folder="folder_icon" file="file_icon" /> + <sort name="tw_gui_sort_order" /> + </style> + + <style name="partitionlist"> + <style name="scrolllist" /> + <icon selected="checkbox_true" unselected="checkbox_false" /> + </style> + + <style name="text"> + <font resource="font" color="%text_color%" /> + </style> + + <style name="checkbox"> + <font resource="font" color="%text_color%" /> + <image checked="checkbox_true" unchecked="checkbox_false" /> + </style> + + <style name="slider"> + <text>Swipe to Confirm</text> + <font resource="font" color="%text_color%" /> + <placement x="%center_x%" y="%slider_y%" placement="5" /> + <resource base="slider" used="slider-used" touch="slider-touch" /> + </style> + + <style name="console"> + <color foreground="%console_foreground%" background="%console_background%" scroll="%console_scroll%" /> + <font resource="fixed" /> + <fastscroll linecolor="%fastscroll_linecolor%" rectcolor="%fastscroll_rectcolor%" w="%fastscroll_w%" linew="%fastscroll_linew%" rectw="%fastscroll_rectw%" recth="%fastscroll_recth%" /> + </style> + + <style name="input"> + <background color="%input_background_color%" /> + <cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" /> + <font resource="font" color="%text_color%" /> + </style> + + <style name="slidervalue"> + <font resource="font" color="%text_color%" /> + <colors line="%slidervalue_line_clr%" slider="%slidervalue_slider_clr%" /> + <dimensions lineh="%slidervalue_lineh%" linepadding="%slidervalue_padding%" sliderw="%slidervalue_sliderw%" sliderh="%slidervalue_sliderh%" /> + </style> + </styles> + + <pages> + <page name="main"> + <object type="action"> + <actions> + <action function="set">tw_clear_destination=main2</action> + <action function="page">clear_vars</action> + </actions> + </object> + </page> + + <page name="main2"> + <object type="template" name="header" /> + + <object type="button"> + <placement x="%col1_x%" y="%row1_y%" /> + <text>Install</text> + <actions> + <action function="queueclear"></action> + <action function="page">install</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row1_y%" /> + <text>Wipe</text> + <action function="page">wipe</action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Backup</text> + <action function="page">backup</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row2_y%" /> + <text>Restore</text> + <action function="page">restore</action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row3_y%" /> + <text>Mount</text> + <action function="page">mount</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row3_y%" /> + <text>Settings</text> + <action function="page">settings</action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row4_y%" /> + <text>Advanced</text> + <action function="page">advanced</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row4_y%" /> + <text>Reboot</text> + <action function="page">reboot</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="install"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Select Zip to Install</text> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col1_x%" y="%row1_text_y%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" /> + <text>Storage: %tw_storage_display_name% (%tw_storage_free_size% MB)</text> + <actions> + <action function="set">tw_back=install</action> + <action function="page">selectstorage</action> + </actions> + </object> + + <object type="fileselector"> + <placement x="%fileselector_x%" y="%row3_text_y%" w="%fileselector_width%" h="%fileselector_install_height%" /> + <text>%tw_zip_location%</text> + <filter extn=".zip" folders="1" files="1" /> + <path name="tw_zip_location" default="/sdcard" /> + <data name="tw_filename" /> + <selection name="tw_file" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="button" style="mediumbutton"> + <placement x="%filemanager_select_x%" y="%filemanager_select_y%" /> + <text>Images...</text> + <actions> + <action function="page">install_image</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_filename" op="modified" /> + <actions> + <action function="queuezip"></action> + <action function="page">flash_confirm</action> + </actions> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="flash_confirm"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>This operation may install incompatible</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>software and render your device unusable.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>Folder:</text> + </object> + + <object type="text"> + <font resource="mediumfont" color="%text_color%"/> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>%tw_zip_location%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row5_text_y%" placement="5" /> + <text>File to flash:</text> + </object> + + <object type="text"> + <font resource="mediumfont" color="%text_color%"/> + <placement x="%center_x%" y="%row6_text_y%" placement="5" /> + <text>%tw_file%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row7_text_y%" placement="5" /> + <text>Press back to cancel adding this zip.</text> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row8_text_y%" /> + <text>Zip file signature verification.</text> + <data variable="tw_signed_zip_verify" /> + </object> + + <object type="checkbox"> + <condition var1="tw_has_injecttwrp" var2="1" /> + <placement x="%col1_x%" y="%row10_text_y%" /> + <text>Inject TWRP after install.</text> + <data variable="tw_inject_after_zip" /> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row11_text_y%" placement="5" /> + <text>File %tw_zip_queue_count% of max of 10</text> + </object> + + <object type="slider"> + <text>Swipe to Confirm Flash</text> + <action function="flash">flash_zip</action> + </object> + + <object type="button"> + <condition var1="tw_zip_queue_count" op="!=" var2="10"></condition> + <placement x="%col1_x%" y="%row_queue_y%" /> + <text>Add More Zips</text> + <action function="page">install</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row_queue_y%" /> + <text>Clear Zip Queue</text> + <actions> + <action function="queueclear"></action> + <action function="page">install</action> + </actions> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="cancelzip"></action> + <action function="page">install</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="flash_zip"> + <object type="template" name="header" /> + + <object type="console"> + <placement x="%console_x%" y="%row1_y%" w="%console_width%" h="%console_install_height%" /> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row17_text_y%" placement="5" /> + <text>Flashing file %tw_zip_index% of %tw_zip_queue_count%</text> + </object> + + <object type="text"> + <font resource="mediumfont" color="%text_color%"/> + <placement x="%center_x%" y="%row18_text_y%" placement="5" /> + <text>%tw_filename%</text> + </object> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <action function="page">flash_done</action> + </object> + </page> + + <page name="flash_done"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Zip Install Complete</text> + </object> + + <object type="console"> + <placement x="%console_x%" y="%row1_y%" w="%console_width%" h="%console_installdone_height%" /> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row4_y%" /> + <text>Wipe cache/dalvik</text> + <actions> + <action function="set">tw_back=flash_done</action> + <action function="set">tw_action=wipe</action> + <action function="set">tw_action_param=/cache</action> + <action function="set">tw_has_action2=1</action> + <action function="set">tw_action2=wipe</action> + <action function="set">tw_action2_param=dalvik</action> + <action function="set">tw_text1=Wipe Cache & Dalvik?</action> + <action function="set">tw_action_text1=Wiping Cache & Dalvik...</action> + <action function="set">tw_complete_text1=Cache & Dalvik Wipe Complete</action> + <action function="set">tw_slider_text=Swipe to Wipe</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <style name="rebootsystem" /> + <placement x="%col2_x%" y="%row4_y%" /> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row3_y%" /> + <text>Home</text> + <actions> + <action function="set">tw_clear_destination=main2</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="text"> + <condition var1="tw_operation_status" op="!=" var2="0" /> + <font resource="font" color="%text_fail_color%"/> + <placement x="%center_x%" y="%zip_status_y%" placement="5" /> + <text>Failed</text> + </object> + + <object type="text"> + <condition var1="tw_operation_status" var2="0" /> + <font resource="font" color="%text_success_color%"/> + <placement x="%center_x%" y="%zip_status_y%" placement="5" /> + <text>Successful</text> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="set">tw_clear_destination=install</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <actions> + <action function="set">tw_clear_destination=main2</action> + <action function="page">clear_vars</action> + </actions> + </object> + </page> + + <page name="install_image"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Select Image to Install</text> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col1_x%" y="%row1_text_y%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" /> + <text>Storage: %tw_storage_display_name% (%tw_storage_free_size% MB)</text> + <actions> + <action function="set">tw_back=install_image</action> + <action function="page">selectstorage</action> + </actions> + </object> + + <object type="fileselector"> + <placement x="%fileselector_x%" y="%row3_text_y%" w="%fileselector_width%" h="%fileselector_install_height%" /> + <text>%tw_zip_location%</text> + <filter extn=".img" folders="1" files="1" /> + <path name="tw_zip_location" default="/sdcard" /> + <data name="tw_filename" /> + <selection name="tw_file" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="button" style="mediumbutton"> + <placement x="%filemanager_select_x%" y="%filemanager_select_y%" /> + <text>Zips...</text> + <actions> + <action function="page">install</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_filename" op="modified" /> + <action function="page">flashimage_confirm</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">install</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="flashimage_confirm"> + <object type="template" name="header" /> + + <object type="partitionlist"> + <placement x="%listbox_x%" y="%row1_header_y%" w="%listbox_width%" h="%flash_list_height%" /> + <text>Select Partition to Flash Image:</text> + <icon selected="radio_true" unselected="radio_false" /> + <data name="tw_flash_partition" /> + <listtype name="flashimg" /> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row8_text_y%" placement="5" /> + <text>Folder:</text> + </object> + + <object type="text"> + <font resource="mediumfont" color="%text_color%"/> + <placement x="%center_x%" y="%row9_text_y%" placement="5" /> + <text>%tw_zip_location%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row10_text_y%" placement="5" /> + <text>File to flash:</text> + </object> + + <object type="text"> + <font resource="mediumfont" color="%text_color%"/> + <placement x="%center_x%" y="%row11_text_y%" placement="5" /> + <text>%tw_file%</text> + </object> + + <object type="slider"> + <text>Swipe to Confirm Flash</text> + <actions> + <action function="set">tw_back=flashimage_confirm</action> + <action function="set">tw_action=flashimage</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_action_text1=Flashing Image...</action> + <action function="set">tw_action_text2=</action> + <action function="set">tw_complete_text1=Image Flashed</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="set">tw_clear_destination=install_image</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <actions> + <action function="set">tw_clear_destination=main2</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="clear_vars"> + <object type="action"> + <action function="set">tw_operation_state=0</action> + <action function="set">tw_text1=</action> + <action function="set">tw_text2=</action> + <action function="set">tw_text3=</action> + <action function="set">tw_text4=</action> + <action function="set">tw_action_text1=</action> + <action function="set">tw_action_text2=</action> + <action function="set">tw_action_param=</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_action2=</action> + <action function="set">tw_action2_param=</action> + <action function="set">tw_has_cancel=0</action> + <action function="set">tw_cancel_action=</action> + <action function="set">tw_cancel_param=</action> + <action function="set">tw_show_exclamation=0</action> + <action function="set">tw_show_reboot=0</action> + <action function="page">%tw_clear_destination%</action> + </object> + </page> + + <page name="confirm_action"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_text1%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_text2%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_text3%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>%tw_text4%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row15_text_y%" placement="5" /> + <text>Press back button to cancel.</text> + </object> + + <object type="slider"> + <text>%tw_slider_text%</text> + <action function="page">action_page</action> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="set">tw_clear_destination=%tw_back%</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="action_page"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_action_text1%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_action_text2%</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="button" style="mediumbutton"> + <condition var1="tw_has_cancel" var2="1" /> + <placement x="%col_center_medium_x%" y="%row4_y%" /> + <text>Cancel</text> + <action function="%tw_cancel_action%">%tw_cancel_param%</action> + </object> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <actions> + <action function="page">action_complete</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_has_action2" var2="0" /> + <actions> + <action function="%tw_action%">%tw_action_param%</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_has_action2" var2="1" /> + <actions> + <action function="%tw_action%">%tw_action_param%</action> + <action function="%tw_action2%">%tw_action2_param%</action> + </actions> + </object> + </page> + + <page name="singleaction_page"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_action_text1%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_action_text2%</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <actions> + <action function="set">tw_page_done=1</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_has_action2" var2="0" /> + <actions> + <action function="%tw_action%">%tw_action_param%</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_has_action2" var2="1" /> + <actions> + <action function="%tw_action%">%tw_action_param%</action> + <action function="%tw_action2%">%tw_action2_param%</action> + </actions> + </object> + </page> + + <page name="action_complete"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_complete_text1%</text> + </object> + + <object type="text"> + <condition var1="tw_operation_status" op="!=" var2="0" /> + <font resource="font" color="%text_fail_color%"/> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Failed</text> + </object> + + <object type="text"> + <condition var1="tw_operation_status" var2="0" /> + <font resource="font" color="%text_success_color%"/> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Successful</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="button"> + <condition var1="tw_show_reboot" var2="0" /> + <placement x="%col_center_x%" y="%row4_y%" /> + <text>Back</text> + <actions> + <action function="set">tw_clear_destination=%tw_back%</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="button" style="rebootsystem"> + <condition var1="tw_show_reboot" var2="1" /> + <placement x="%col_center_x%" y="%row4_y%" /> + </object> + + <object type="action"> + <touch key="home" /> + <actions> + <action function="set">tw_clear_destination=main2</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="set">tw_clear_destination=%tw_back%</action> + <action function="page">clear_vars</action> + </actions> + </object> + </page> + + <page name="filecheck"> + <object type="action"> + <action function="fileexists">%tw_filecheck%</action> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" var2="0" /> + </conditions> + <actions> + <action function="set">tw_fileexists=1</action> + <action function="page">%tw_existpage%</action> + </actions> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" var2="1" /> + </conditions> + <actions> + <action function="set">tw_fileexists=0</action> + <action function="page">%tw_notexistpage%</action> + </actions> + </object> + </page> + + <page name="rebootcheck"> + <object type="action"> + <condition var1="tw_backup_system_size" op=">=" var2="%tw_min_system%" /> + <action function="reboot">%tw_action_param%</action> + </object> + + <object type="action"> + <condition var1="tw_backup_system_size" op="<" var2="%tw_min_system%" /> + <action function="page">confirm_action</action> + </object> + </page> + + <page name="wipe"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Factory Reset</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Wipes Data, Cache, and Dalvik</text> + </object> + + <object type="text"> + <condition var1="tw_has_data_media" var2="1" /> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>(not including internal storage)</text> + </object> + + <object type="text"> + <conditions> + <condition var1="tw_has_android_secure" var2="1" /> + <condition var1="fileexists" var2="/and-sec" /> + </conditions> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>Android Secure</text> + </object> + + <object type="text"> + <condition var1="tw_has_sdext_partition" var2="1" /> + <placement x="%center_x%" y="%row5_text_y%" placement="5" /> + <text>SD-EXT</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row6_text_y%" placement="5" /> + <text>Most of the time this is</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row7_text_y%" placement="5" /> + <text>the only wipe that you need.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row16_text_y%" placement="5" /> + <text>Press back button to cancel.</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%wipe_button_y%" /> + <text>Advanced Wipe</text> + <actions> + <action function="set">partitionlisterror=0</action> + <action function="page">advancedwipe</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_has_data_media" var2="1" /> + <placement x="%col2_x%" y="%wipe_button_y%" /> + <text>Format Data</text> + <actions> + <action function="page">formatdata</action> + </actions> + </object> + + <object type="button"> + <conditions> + <condition var1="tw_is_encrypted" var2="1" /> + <condition var1="tw_has_data_media" var2="0" /> + </conditions> + <placement x="%col2_x%" y="%wipe_button_y%" /> + <text>Wipe Encryption</text> + <actions> + <action function="set">tw_back=wipe</action> + <action function="set">tw_action=wipe</action> + <action function="set">tw_action_param=DATAMEDIA</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Wipe Encryption from Data?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting Data...</action> + <action function="set">tw_complete_text1=Data Format Complete</action> + <action function="set">tw_slider_text=Swipe to Format Data</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="slider"> + <text>Swipe to Factory Reset</text> + <actions> + <action function="set">tw_back=wipe</action> + <action function="set">tw_action=wipe</action> + <action function="set">tw_action_param=data</action> + <action function="set">tw_action_text1=Factory Reset...</action> + <action function="set">tw_complete_text1=Factory Reset Complete</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="advancedwipe"> + <object type="template" name="header" /> + + <object type="action"> + <action function="set">tw_wipe_list=</action> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Wipe Menu</text> + </object> + + <object type="partitionlist"> + <placement x="%listbox_x%" y="%row1_header_y%" w="%listbox_width%" h="%wipe_list_height%" /> + <text>Select Partitions to Wipe:</text> + <data name="tw_wipe_list" /> + <listtype name="wipe" /> + </object> + + <object type="slider"> + <text>Swipe to Wipe</text> + <actions> + <action function="set">tw_back=advancedwipe</action> + <action function="set">tw_action=wipe</action> + <action function="set">tw_action_param=LIST</action> + <action function="set">tw_text1=Wipe Selected Partition(s)?</action> + <action function="set">tw_action_text1=Wiping Partition(s)...</action> + <action function="set">tw_complete_text1=Wipe Complete</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col1_x%" y="%wipe_button_row1%" w="%button_fill_full_width%" h="%button_fill_half_height%" /> + <text>Repair or Change File System</text> + <actions> + <action function="checkpartitionlist"></action> + <action function="page">checkpartitionlist</action> + </actions> + </object> + + <object type="text"> + <font resource="font" color="%text_fail_color%"/> + <condition var1="partitionlisterror" var2="1" /> + <placement x="%center_x%" y="%wipe_button_row1%" placement="5" /> + <text>Invalid partition selection</text> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">wipe</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="formatdata"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Format Data will wipe all of your apps,</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>backups, pictures, videos, media, and</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>removes encryption on internal storage.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>This cannot be undone. Press back to cancel.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>Type yes to continue.</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row6_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_confirm_formatdata%</text> + <data name="tw_confirm_formatdata" /> + <restrict minlen="3" maxlen="3" allow="yes" /> + <action function="page">formatdata_confirm</action> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">wipe</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="formatdata_confirm"> + <object type="action"> + <condition var1="tw_confirm_formatdata" op="=" var2="yes" /> + <actions> + <action function="set">tw_back=formatdata</action> + <action function="set">tw_action=wipe</action> + <action function="set">tw_action_param=DATAMEDIA</action> + <action function="set">tw_action_text1=Formatting Data...</action> + <action function="set">tw_complete_text1=Data Format Complete</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_confirm_formatdata" op="!=" var2="yes" /> + <action function="page">formatdata</action> + </object> + </page> + + <page name="checkpartitionlist"> + <object type="action"> + <condition var1="tw_check_partition_list" op="=" var2="1" /> + <actions> + <action function="set">partitionlisterror=0</action> + <action function="getpartitiondetails"></action> + <action function="page">partitionoptions</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_check_partition_list" op="!=" var2="1" /> + <actions> + <action function="set">partitionlisterror=1</action> + <action function="set">tw_wipe_list=</action> + <action function="page">advancedwipe</action> + </actions> + </object> + </page> + + <page name="partitionoptions"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Partition Options for: %tw_partition_name%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Mount Point: %tw_partition_mount_point%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Current file system: %tw_partition_file_system%</text> + </object> + + <object type="text"> + <condition var1="tw_partition_is_present" op="!=" var2="0" /> + <placement x="%col1_x%" y="%row3_text_y%" /> + <text>Present: Yes</text> + </object> + + <object type="text"> + <condition var1="tw_partition_is_present" op="=" var2="0" /> + <placement x="%col1_x%" y="%row3_text_y%" /> + <text>Present: No</text> + </object> + + <object type="text"> + <condition var1="tw_partition_removable" op="!=" var2="0" /> + <placement x="%col2_x%" y="%row3_text_y%" /> + <text>Removable: Yes</text> + </object> + + <object type="text"> + <condition var1="tw_partition_removable" op="=" var2="0" /> + <placement x="%col2_x%" y="%row3_text_y%" /> + <text>Removable: No</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row4_text_y%" /> + <text>Size: %tw_partition_size%MB</text> + </object> + + <object type="text"> + <placement x="%col2_x%" y="%row4_text_y%" /> + <text>Used: %tw_partition_used%MB</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row5_text_y%" /> + <text>Free: %tw_partition_free%MB</text> + </object> + + <object type="text"> + <placement x="%col2_x%" y="%row5_text_y%" /> + <text>Backup Size: %tw_partition_backup_size%MB</text> + </object> + + <object type="button"> + <condition var1="tw_partition_can_resize" op="=" var2="1" /> + <placement x="%col1_x%" y="%row3_y%" /> + <text>Resize</text> + <actions> + <action function="set">tw_back=partitionoptions</action> + <action function="set">tw_action=resize</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_has_action2=1</action> + <action function="set">tw_action2=getpartitiondetails</action> + <action function="set">tw_text1=Resize %tw_partition_name%?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Resizing...</action> + <action function="set">tw_complete_text1=Resize Complete</action> + <action function="set">tw_slider_text=Swipe to Resize</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_can_repair" op="=" var2="1" /> + <placement x="%col1_x%" y="%row4_y%" /> + <text>Repair</text> + <actions> + <action function="set">tw_back=partitionoptions</action> + <action function="set">tw_action=repair</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Repair %tw_partition_name%?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Repairing...</action> + <action function="set">tw_complete_text1=Repair Complete</action> + <action function="set">tw_slider_text=Swipe to Repair</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row4_y%" /> + <text>Change File System</text> + <action function="page">selectfilesystem</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advancedwipe</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="refreshfilesystem"> + <object type="action"> + <condition var1="tw_check_partition_list" op="=" var2="1" /> + <actions> + <action function="set">partitionlisterror=0</action> + <action function="getpartitiondetails"></action> + <action function="page">selectfilesystem</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_check_partition_list" op="!=" var2="1" /> + <actions> + <action function="set">partitionlisterror=1</action> + <action function="set">tw_wipe_list=</action> + <action function="page">advancedwipe</action> + </actions> + </object> + </page> + + <page name="selectfilesystem"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Change file system for: %tw_partition_name%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Mount Point: %tw_partition_mount_point%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Current file system: %tw_partition_file_system%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>Some ROMs or kernels may not support some</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>file systems. Proceed with caution!</text> + </object> + + <object type="button"> + <condition var1="tw_partition_ext" op="=" var2="1" /> + <placement x="%col1_x%" y="%row2_y%" /> + <text>EXT2</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=ext2</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to EXT2?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_ext" op="=" var2="1" /> + <placement x="%col2_x%" y="%row2_y%" /> + <text>EXT3</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=ext3</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to EXT3?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_ext" op="=" var2="1" /> + <placement x="%col1_x%" y="%row3_y%" /> + <text>EXT4</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=ext4</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to EXT4?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_f2fs" op="=" var2="1" /> + <placement x="%col2_x%" y="%row3_y%" /> + <text>F2FS</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=f2fs</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to F2FS?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_vfat" op="=" var2="1" /> + <placement x="%col1_x%" y="%row4_y%" /> + <text>FAT</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=vfat</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to FAT?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_exfat" op="=" var2="1" /> + <placement x="%col2_x%" y="%row4_y%" /> + <text>exFAT</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=exfat</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to exFAT?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">partitionoptions</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="backup"> + <object type="template" name="header" /> + + <object type="button" style="fillbutton"> + <placement x="%col1_x%" y="%row1_header_y%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" /> + <text>Backup Name: %tw_backup_name%</text> + <actions> + <action function="set">tw_fileexists=0</action> + <action function="page">backupname1</action> + </actions> + </object> + + <object type="partitionlist"> + <placement x="%listbox_x%" y="%row2_text_y%" w="%listbox_width%" h="%backup_list_height%" /> + <text>Select Partitions to Back Up:</text> + <data name="tw_backup_list" /> + <listtype name="backup" /> + </object> + + <object type="button" style="fillbutton"> + <conditions> + <condition var1="tw_include_encrypted_backup" var2="1" /> + <condition var1="tw_encrypt_backup" var2="0" /> + </conditions> + <placement x="%col1_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" /> + <text>No Encryption</text> + <actions> + <action function="page">backupencryption</action> + </actions> + </object> + + <object type="button" style="fillbutton"> + <conditions> + <condition var1="tw_include_encrypted_backup" var2="1" /> + <condition var1="tw_encrypt_backup" var2="1" /> + </conditions> + <placement x="%col1_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" /> + <text>Using Encryption</text> + <actions> + <action function="set">tw_password_not_match=0</action> + <action function="page">backupencryption</action> + </actions> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col2_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" /> + <text>Refresh Sizes</text> + <actions> + <action function="refreshsizes"></action> + <action function="page">backup</action> + </actions> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col1_x%" y="%backup_button_row2%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" /> + <text>Storage: %tw_storage_display_name% (%tw_storage_free_size% MB)</text> + <actions> + <action function="set">tw_back=backup</action> + <action function="page">selectstorage</action> + </actions> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row15_text_y%" /> + <text>Enable compression.</text> + <data variable="tw_use_compression" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row16_text_y%" /> + <text>Skip MD5 generation during backup.</text> + <data variable="tw_skip_md5_generate" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row17_text_y%" /> + <font resource="font" color="%text_color%" /> + <text>Disable Free Space Check.</text> + <data variable="tw_disable_free_space" /> + <image checked="checkbox_true" unchecked="checkbox_false" /> + </object> + + <object type="slider"> + <text>Swipe to Back Up</text> + <action function="page">backup_run</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="backupname1"> + <object type="action"> + <condition var1="tw_backup_name" op="=" var2="(Auto Generate)" /> + <action function="generatebackupname"></action> + </object> + + <object type="action"> + <action function="page">backupname2</action> + </object> + </page> + + <page name="backupname2"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Please Enter a Backup Name</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_backup_name%</text> + <data name="tw_backup_name" /> + <restrict minlen="1" maxlen="64" allow=" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_.{}[]" /> + <actions> + <action function="set">tw_filecheck=%tw_backups_folder%/%tw_backup_name%</action> + <action function="set">tw_existpage=backupname2</action> + <action function="set">tw_notexistpage=backup</action> + <action function="page">filecheck</action> + </actions> + </object> + + <object type="text"> + <condition var1="tw_fileexists" var2="1" /> + <placement x="%center_x%" y="%row5_text_y%" placement="5" /> + <font resource="font" color="%text_fail_color%"/> + <text>A backup with that name already exists!</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Append Date</text> + <action function="appenddatetobackupname"></action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row2_y%" /> + <text>Cancel</text> + <actions> + <action function="set">tw_backup_name=(Auto Generate)</action> + <action function="page">backup</action> + </actions> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <actions> + <action function="set">tw_backup_name=(Auto Generate)</action> + <action function="page">main</action> + </actions> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="set">tw_backup_name=(Auto Generate)</action> + <action function="page">backup</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="backupencryption"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Encrypt your backup?</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Please Enter A Password:</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_backup_encrypt_display%</text> + <data name="tw_backup_password" mask="*" maskvariable="tw_backup_encrypt_display" /> + <restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" /> + <action function="page">backupencryption2</action> + </object> + + <object type="text"> + <condition var1="tw_password_not_match" var2="1" /> + <font resource="font" color="%text_fail_color%"/> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>Passwords Do Not Match</text> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row2_y%" /> + <text>Cancel</text> + <actions> + <action function="set">tw_encrypt_backup=0</action> + <action function="set">tw_backup_password=</action> + <action function="set">tw_backup_password2=</action> + <action function="set">tw_backup_encrypt_display=</action> + <action function="set">tw_backup_encrypt_display2=</action> + <action function="page">backup</action> + </actions> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">backup</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="backupencryption2"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Encrypt your backup?</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Please Enter Password Again:</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_backup_encrypt_display2%</text> + <data name="tw_backup_password2" mask="*" maskvariable="tw_backup_encrypt_display2" /> + <restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" /> + <actions> + <action function="page">checkbackuppassword</action> + </actions> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row2_y%" /> + <text>Cancel</text> + <actions> + <action function="set">tw_encrypt_backup=0</action> + <action function="set">tw_backup_password=</action> + <action function="set">tw_backup_password2=</action> + <action function="set">tw_backup_encrypt_display=</action> + <action function="set">tw_backup_encrypt_display2=</action> + <action function="page">backup</action> + </actions> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">backup</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="checkbackuppassword"> + <object type="action"> + <condition var1="tw_backup_password2" var2="tw_backup_password" /> + <actions> + <action function="set">tw_encrypt_backup=1</action> + <action function="page">backup</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_backup_password2" op="!=" var2="tw_backup_password" /> + <actions> + <action function="set">tw_encrypt_backup=0</action> + <action function="set">tw_password_not_match=1</action> + <action function="set">tw_backup_password=</action> + <action function="set">tw_backup_password2=</action> + <action function="set">tw_backup_encrypt_display=</action> + <action function="set">tw_backup_encrypt_display2=</action> + <action function="page">backupencryption</action> + </actions> + </object> + </page> + + <page name="backup_run"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_operation% %tw_partition%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="button" style="mediumbutton"> + <placement x="%col_center_medium_x%" y="%row4_y%" /> + <text>Cancel</text> + <actions> + <action function="cancelbackup"></action> + </actions> + </object> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <action function="nandroid">backup</action> + </object> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_cancel_backup" var2="0" /> + <actions> + <action function="set">tw_back=backup</action> + <action function="set">tw_complete_text1=Backup Complete</action> + <action function="set">tw_show_reboot=1</action> + <action function="page">action_complete</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_cancel_backup" var2="1" /> + <actions> + <action function="set">tw_back=backup</action> + <action function="set">tw_complete_text1=Backup Cancelled</action> + <action function="set">tw_show_reboot=1</action> + <action function="page">action_complete</action> + </actions> + </object> + </page> + + <page name="restore"> + <object type="template" name="header" /> + + <object type="button" style="fillbutton"> + <placement x="%col1_x%" y="%row1_header_y%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" /> + <text>Storage: %tw_storage_display_name% (%tw_storage_free_size% MB)</text> + <actions> + <action function="set">tw_back=restore</action> + <action function="page">selectstorage</action> + </actions> + </object> + + <object type="fileselector"> + <placement x="%fileselector_x%" y="%row2_text_y%" w="%fileselector_width%" h="%fileselector_install_height%" /> + <text>Select Package to Restore:</text> + <filter folders="1" files="0" nav="0" /> + <path name="tw_backups_folder" /> + <data name="tw_restore" default="" /> + <selection name="tw_restore_name" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="action"> + <condition var1="tw_restore" op="modified" /> + <actions> + <action function="readBackup"></action> + <action function="page">restore_read</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="restore_read"> + <object type="action"> + <condition var1="tw_restore_encrypted" var2="1" /> + <actions> + <action function="set">tw_password_fail=0</action> + <action function="page">restore_decrypt</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_restore_encrypted" var2="0" /> + <actions> + <action function="page">restore_select</action> + </actions> + </object> + </page> + + <page name="restore_decrypt"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Backup Encrypted</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Please Enter Your Password:</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_restore_display%</text> + <data name="tw_restore_password" mask="*" maskvariable="tw_restore_display" /> + <restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" /> + <actions> + <action function="page">try_restore_decrypt</action> + </actions> + </object> + + <object type="text"> + <condition var1="tw_password_fail" var2="1" /> + <font resource="font" color="%text_fail_color%"/> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>Password Failed, Please Try Again</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Cancel</text> + <actions> + <action function="set">tw_page_done=1</action> + <action function="page">restore</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row2_y%" /> + <text>Delete</text> + <actions> + <action function="set">tw_back=restore</action> + <action function="set">tw_action=cmd</action> + <action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf "%tw_restore_name%"</action> + <action function="set">tw_text1=Delete Backup? %tw_restore_name%</action> + <action function="set">tw_text2=This cannot be undone!</action> + <action function="set">tw_action_text1=Deleting Backup...</action> + <action function="set">tw_complete_text1=Backup Delete Complete</action> + <action function="set">tw_slider_text=Swipe to Delete</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">restore</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="try_restore_decrypt"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Trying Decryption with Your Password</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <action function="decrypt_backup"></action> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" op="!=" var2="0" /> + </conditions> + <actions> + <action function="set">tw_password_fail=1</action> + <action function="page">restore_decrypt</action> + </actions> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" op="=" var2="0" /> + </conditions> + <actions> + <action function="set">tw_page_done=1</action> + <action function="page">restore_select</action> + </actions> + </object> + </page> + + <page name="restore_select"> + <object type="template" name="header" /> + + <object type="partitionlist"> + <placement x="%listbox_x%" y="%row1_header_y%" w="%listbox_width%" h="%backup_list_height%" /> + <text>Restoring: %tw_restore_name%</text> + <data name="tw_restore_list" selectedlist="tw_restore_selected" /> + <listtype name="restore" /> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col1_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" /> + <text>Rename Backup</text> + <actions> + <action function="set">tw_backup_rename=</action> + <action function="set">tw_fileexists=0</action> + <action function="page">renamebackup</action> + </actions> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col2_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" /> + <text>Delete Backup</text> + <actions> + <action function="set">tw_back=restore</action> + <action function="set">tw_action=cmd</action> + <action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf "%tw_restore_name%"</action> + <action function="set">tw_text1=Delete Backup? %tw_restore_name%</action> + <action function="set">tw_text2=This cannot be undone!</action> + <action function="set">tw_action_text1=Deleting Backup...</action> + <action function="set">tw_complete_text1=Backup Delete Complete</action> + <action function="set">tw_slider_text=Swipe to Delete</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row15_text_y%" /> + <text>Enable MD5 verification of backup files.</text> + <data variable="tw_skip_md5_check" /> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row16_text_y%" placement="5" /> + <text>Package Date: %tw_restore_file_date%</text> + </object> + + <object type="slider"> + <text>Swipe to Restore</text> + <action function="page">restore_run</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">restore</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="renamebackup"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Please Enter a New Backup Name</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_backup_rename%</text> + <data name="tw_backup_rename" /> + <restrict minlen="1" maxlen="64" allow=" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_.{}[]" /> + <actions> + <action function="set">tw_back=restore</action> + <action function="set">tw_action=cmd</action> + <action function="set">tw_action_param=cd %tw_backups_folder% && mv "%tw_restore_name%" "%tw_backup_rename%"</action> + <action function="set">tw_text1=Rename Backup?</action> + <action function="set">tw_text2=This cannot be undone!</action> + <action function="set">tw_action_text1=Renaming Backup...</action> + <action function="set">tw_complete_text1=Backup Rename Complete</action> + <action function="set">tw_slider_text=Swipe to Rename</action> + <action function="set">tw_filecheck=%tw_backups_folder%/%tw_backup_rename%</action> + <action function="set">tw_existpage=renamebackup</action> + <action function="set">tw_notexistpage=confirm_action</action> + <action function="page">filecheck</action> + </actions> + </object> + + <object type="text"> + <condition var1="tw_fileexists" var2="1" /> + <placement x="%center_x%" y="%row5_text_y%" placement="5" /> + <font resource="font" color="%text_fail_color%"/> + <text>A backup with that name already exists!</text> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row2_y%" /> + <text>Cancel</text> + <action function="page">restore_select</action> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">restore_select</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="restore_run"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_operation% %tw_partition%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <actions> + <action function="set">tw_back=restore_select</action> + <action function="set">tw_complete_text1=Restore Complete</action> + <action function="set">tw_show_reboot=1</action> + <action function="page">action_complete</action> + </actions> + </object> + + <object type="action"> + <action function="nandroid">restore</action> + </object> + </page> + + <page name="selectstorage"> + <object type="template" name="header" /> + + <object type="partitionlist"> + <placement x="%listbox_x%" y="%row1_header_y%" w="%listbox_width%" h="%storage_list_height%" /> + <text>Select Storage:</text> + <icon selected="radio_true" unselected="radio_false" /> + <data name="tw_storage_path" /> + <listtype name="storage" /> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row4_y%" /> + <text>OK</text> + <actions> + <action function="set">tw_clear_destination=%tw_back%</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="page">%tw_back%</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="mount"> + <object type="template" name="header" /> + + <object type="partitionlist"> + <placement x="%listbox_x%" y="%row1_header_y%" w="%listbox_width%" h="%mount_list_height%" /> + <text>Select Partitions to Mount:</text> + <listtype name="mount" /> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col1_x%" y="%mount_storage_row%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" /> + <text>Storage: %tw_storage_display_name% (%tw_storage_free_size% MB)</text> + <actions> + <action function="set">tw_back=mount</action> + <action function="page">selectstorage</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_has_usb_storage" var2="1" /> + <placement x="%col1_x%" y="row4_y" /> + <text>Mount USB Storage</text> + <action function="page">usb_mount</action> + </object> + + <object type="button"> + <conditions> + <condition var1="tw_has_mtp" var2="1" /> + <condition var1="tw_mtp_enabled" var2="0" /> + </conditions> + <placement x="%col2_x%" y="row4_y" /> + <text>Enable MTP</text> + <action function="startmtp"></action> + </object> + + <object type="button"> + <conditions> + <condition var1="tw_has_mtp" var2="1" /> + <condition var1="tw_mtp_enabled" var2="1" /> + </conditions> + <placement x="%col2_x%" y="row4_y" /> + <text>Disable MTP</text> + <action function="stopmtp"></action> + </object> + + <object type="button"> + <conditions> + <condition var1="tw_is_encrypted" var2="1" /> + <condition var1="tw_is_decrypted" var2="0" /> + </conditions> + <placement x="%col2_x%" y="row4_y" /> + <text>Decrypt Data</text> + <action function="page">decrypt</action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%system_ro_y%" /> + <font resource="font" color="%text_color%" /> + <condition var1="tw_mount_system_ro" op="=" var2="0" /> + <text>Only mount system read-only</text> + <image resource="checkbox_false" /> + <action function="mountsystemtoggle">1</action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%system_ro_y%" /> + <font resource="font" color="%text_color%" /> + <condition var1="tw_mount_system_ro" op="!=" var2="0" /> + <text>Only mount system read-only</text> + <image resource="checkbox_true" /> + <actions> + <action function="set">tw_lifetime_writes=2</action> + <action function="page">system_readonly_check</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="usb_mount"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>USB Storage Mounted</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row1_text_y%" /> + <text>Be sure to safely remove your device</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row2_text_y%" /> + <text>from your computer before unmounting!</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row3_y%" /> + <text>Unmount</text> + <action function="page">usb_umount</action> + </object> + + <object type="action"> + <action function="mount">usb</action> + <action function="set">tw_busy=1</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="usb_umount"> + <object type="action"> + <action function="unmount">usb</action> + </object> + + <object type="action"> + <action function="page">mount</action> + <action function="set">tw_busy=0</action> + </object> + </page> + + <page name="system_readonly_check"> + <object type="action"> + <action function="checkpartitionlifetimewrites">/system</action> + </object> + + <object type="action"> + <condition var1="tw_lifetime_writes" var2="1" /> + <actions> + <action function="mountsystemtoggle">0</action> + <action function="page">mount</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_lifetime_writes" var2="0" /> + <actions> + <action function="set">tw_back=mount</action> + <action function="page">system_readonly</action> + </actions> + </object> + </page> + + <page name="reboot"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Reboot Menu</text> + </object> + + <object type="button" style="rebootsystem"> + <condition var1="tw_reboot_system" var2="1" /> + <placement x="%col1_x%" y="%row1_y%" /> + <text>System</text> + </object> + + <object type="button"> + <condition var1="tw_reboot_poweroff" var2="1" /> + <placement x="%col2_x%" y="%row1_y%" /> + <text>Power Off</text> + <actions> + <action function="set">tw_back=reboot</action> + <action function="set">tw_action=reboot</action> + <action function="set">tw_action_param=poweroff</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=No OS Installed! Are you</action> + <action function="set">tw_text2=sure you wish to power off?</action> + <action function="set">tw_action_text1=Turning Off...</action> + <action function="set">tw_complete_text1=Turning Off...</action> + <action function="set">tw_slider_text=Swipe to Power Off</action> + <action function="page">rebootcheck</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_reboot_recovery" var2="1" /> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Recovery</text> + <actions> + <action function="set">tw_back=reboot</action> + <action function="set">tw_action=reboot</action> + <action function="set">tw_action_param=recovery</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=No OS Installed! Are you</action> + <action function="set">tw_text2=sure you wish to reboot?</action> + <action function="set">tw_action_text1=Rebooting...</action> + <action function="set">tw_complete_text1=Rebooting...</action> + <action function="set">tw_slider_text=Swipe to Reboot</action> + <action function="page">rebootcheck</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_reboot_bootloader" var2="1" /> + <placement x="%col2_x%" y="%row2_y%" /> + <text>Bootloader</text> + <actions> + <action function="set">tw_back=reboot</action> + <action function="set">tw_action=reboot</action> + <action function="set">tw_action_param=bootloader</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=No OS Installed! Are you</action> + <action function="set">tw_text2=sure you wish to reboot?</action> + <action function="set">tw_action_text1=Rebooting...</action> + <action function="set">tw_complete_text1=Rebooting...</action> + <action function="set">tw_slider_text=Swipe to Reboot</action> + <action function="page">rebootcheck</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_download_mode" var2="1" /> + <placement x="%col1_x%" y="%row3_y%" /> + <text>Download</text> + <actions> + <action function="set">tw_back=reboot</action> + <action function="set">tw_action=reboot</action> + <action function="set">tw_action_param=download</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=No OS Installed! Are you</action> + <action function="set">tw_text2=sure you wish to reboot?</action> + <action function="set">tw_action_text1=Rebooting...</action> + <action function="set">tw_complete_text1=Rebooting...</action> + <action function="set">tw_slider_text=Swipe to Reboot</action> + <action function="page">rebootcheck</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="settings"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Settings</text> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row1_text_y%" /> + <text>Zip file signature verification.</text> + <data variable="tw_signed_zip_verify" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row2_text_y%" /> + <text>Use rm -rf instead of formatting.</text> + <data variable="tw_rm_rf" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row3_text_y%" /> + <text>Skip MD5 generation during backup.</text> + <data variable="tw_skip_md5_generate" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row4_text_y%" /> + <text>Enable MD5 verification of backup files.</text> + <data variable="tw_skip_md5_check" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row5_text_y%" /> + <text>Use 24-hour clock.</text> + <data variable="tw_military_time" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row6_text_y%" /> + <text>Simulate actions for theme testing.</text> + <data variable="tw_simulate_actions" /> + </object> + + <object type="checkbox"> + <condition var1="tw_simulate_actions" var2="1" /> + <placement x="%col1_x%" y="%row7_text_y%" /> + <text>Simulate failure for actions.</text> + <data variable="tw_simulate_fail" /> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row3_y%" /> + <text>Time Zone</text> + <action function="page">timezone</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row3_y%" /> + <text>Screen</text> + <action function="page">screen</action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row4_y%" /> + <text>Restore Defaults</text> + <action function="restoredefaultsettings"></action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row4_y%" /> + <text>Vibration Duration</text> + <action function="page">Vibrate</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="timezone"> + <object type="template" name="header" /> + + <object type="listbox" style="scrolllist"> + <placement x="%listbox_x%" y="%row1_header_y%" w="%listbox_width%" h="%listbox_tz_height%" /> + <text>Select Time Zone:</text> + <icon selected="radio_true" unselected="radio_false" /> + <data name="tw_time_zone_guisel" /> + <listitem name="(UTC -11) Samoa, Midway Island">BST11;BDT</listitem> + <listitem name="(UTC -10) Hawaii">HST10;HDT</listitem> + <listitem name="(UTC -9) Alaska">AST9;ADT</listitem> + <listitem name="(UTC -8) Pacific Time">PST8;PDT,M3.2.0,M11.1.0</listitem> + <listitem name="(UTC -7) Mountain Time">MST7;MDT,M3.2.0,M11.1.0</listitem> + <listitem name="(UTC -6) Central Time">CST6;CDT,M3.2.0,M11.1.0</listitem> + <listitem name="(UTC -5) Eastern Time">EST5;EDT,M3.2.0,M11.1.0</listitem> + <listitem name="(UTC -4) Atlantic Time">AST4;ADT</listitem> + <listitem name="(UTC -3) Brazil, Buenos Aires">GRNLNDST3;GRNLNDDT</listitem> + <listitem name="(UTC -2) Mid-Atlantic">FALKST2;FALKDT</listitem> + <listitem name="(UTC -1) Azores, Cape Verde">AZOREST1;AZOREDT</listitem> + <listitem name="(UTC 0) London, Dublin, Lisbon">GMT0;BST,M3.5.0,M10.5.0</listitem> + <listitem name="(UTC +1) Berlin, Brussels, Paris">CET-1;CEST,M3.5.0,M10.5.0</listitem> + <listitem name="(UTC +2) Athens, Istanbul, South Africa">WET-2;WET,M3.5.0,M10.5.0</listitem> + <listitem name="(UTC +3) Moscow, Baghdad">SAUST-3;SAUDT</listitem> + <listitem name="(UTC +4) Abu Dhabi, Tbilisi, Muscat">WST-4;WDT</listitem> + <listitem name="(UTC +5) Yekaterinburg, Islamabad">PAKST-5;PAKDT</listitem> + <listitem name="(UTC +6) Almaty, Dhaka, Colombo">TASHST-6;TASHDT</listitem> + <listitem name="(UTC +7) Bangkok, Hanoi, Jakarta">THAIST-7;THAIDT</listitem> + <listitem name="(UTC +8) Beijing, Singapore, Hong Kong">TAIST-8;TAIDT</listitem> + <listitem name="(UTC +9) Tokyo, Seoul, Yakutsk">JST-9;JSTDT</listitem> + <listitem name="(UTC +10) Eastern Australia, Guam">EET-10;EETDT</listitem> + <listitem name="(UTC +11) Vladivostok, Solomon Islands">MET-11;METDT</listitem> + <listitem name="(UTC +12) Auckland, Wellington, Fiji">NZST-12;NZDT</listitem> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row_dst_text_y%" /> + <text>Do you use daylight savings time (DST)?</text> + <data variable="tw_time_zone_guidst" /> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row_offset_text_y%" placement="5" /> + <text>Offset (usually 0): %tw_time_zone_guioffset%</text> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%col1_medium_x%" y="%row_offset_medium_y%" /> + <text>None</text> + <action function="set">tw_time_zone_guioffset=0</action> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%col2_medium_x%" y="%row_offset_medium_y%" /> + <text>15</text> + <action function="set">tw_time_zone_guioffset=15</action> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%col3_medium_x%" y="%row_offset_medium_y%" /> + <text>30</text> + <action function="set">tw_time_zone_guioffset=30</action> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%col4_medium_x%" y="%row_offset_medium_y%" /> + <text>45</text> + <action function="set">tw_time_zone_guioffset=45</action> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%tz_set_y%" /> + <text>Set Time Zone</text> + <action function="setguitimezone"></action> + </object> + + <object type="text"> + <placement x="%center_x%" y="%tz_current_y%" placement="5" /> + <text>Current Time Zone: %tw_time_zone%</text> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">settings</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="screen"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Screen Settings</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row2_text_y%" /> + <font resource="font" color="%text_color%" /> + <condition var1="tw_screen_timeout_secs" op="=" var2="0" /> + <condition var1="tw_no_screen_timeout" op="!=" var2="1" /> + <text>Enable screen timeout.</text> + <image resource="checkbox_false" /> + <action function="set">tw_screen_timeout_secs=60</action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row2_text_y%" /> + <font resource="font" color="%text_color%" /> + <condition var1="tw_screen_timeout_secs" op="!=" var2="0" /> + <condition var1="tw_no_screen_timeout" op="!=" var2="1" /> + <text>Enable screen timeout.</text> + <image resource="checkbox_true" /> + <action function="set">tw_screen_timeout_secs=0</action> + </object> + + <object type="slidervalue"> + <conditions> + <condition var1="tw_screen_timeout_secs" op="!=" var2="0" /> + <condition var1="tw_no_screen_timeout" op="!=" var2="1" /> + </conditions> + <placement x="col1_x" y="%row4_text_y%" w="%slidervalue_w%" /> + <text>Screen timeout in seconds:</text> + <data variable="tw_screen_timeout_secs" min="15" max="300" /> + </object> + + <object type="slidervalue"> + <condition var1="tw_has_brightnesss_file" var2="1" /> + <placement x="col1_x" y="%row12_text_y%" w="%slidervalue_w%" /> + <text>Brightness: %tw_brightness_pct%%</text> + <data variable="tw_brightness_pct" min="10" max="100" /> + <actions> + <action function="set">tw_brightness=%tw_brightness_max%</action> + <action function="compute">tw_brightness*%tw_brightness_pct%</action> + <action function="compute">tw_brightness/100</action> + <action function="setbrightness">%tw_brightness%</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">settings</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="Vibrate"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Vibration Settings :</text> + </object> + + <object type="slidervalue"> + <placement x="col1_x" y="%row4_text_y%" w="%slidervalue_w%" /> + <text>Button Vibration:</text> + <data variable="tw_button_vibrate" min="0" max="300" /> + </object> + + <object type="slidervalue"> + <placement x="col1_x" y="%row8_text_y%" w="%slidervalue_w%" /> + <text>Keyboard Vibration:</text> + <data variable="tw_keyboard_vibrate" min="0" max="300" /> + </object> + + <object type="slidervalue"> + <placement x="col1_x" y="%row12_text_y%" w="%slidervalue_w%" /> + <text>Action Vibration:</text> + <data variable="tw_action_vibrate" min="0" max="500" /> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">settings</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="advanced"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Advanced</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row1_y%" /> + <text>Copy Log to SD</text> + <actions> + <action function="set">tw_back=advanced</action> + <action function="set">tw_action=copylog</action> + <action function="set">tw_text1=Copy Log to SD Card?</action> + <action function="set">tw_action_text1=Copying Log to SD Card...</action> + <action function="set">tw_complete_text1=Log Copy Complete</action> + <action function="set">tw_slider_text=Swipe to Confirm</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row1_y%" /> + <text>Fix Permissions</text> + <action function="page">fixperms</action> + </object> + + <object type="button"> + <condition var1="tw_allow_partition_sdcard" var2="1" /> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Partition SD Card</text> + <action function="page">partsdcard</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row2_y%" /> + <text>File Manager</text> + <action function="page">filemanagerlist</action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row3_y%" /> + <text>Terminal Command</text> + <action function="page">terminalfolder</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row3_y%" /> + <text>Reload Theme</text> + <action function="reload"></action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row4_y%" /> + <text>ADB Sideload</text> + <action function="page">sideload</action> + </object> + + <object type="button"> + <condition var1="tw_show_dumlock" var2="1" /> + <placement x="%col2_x%" y="%row4_y%" /> + <text>HTC Dumlock</text> + <action function="page">htcdumlock</action> + </object> + + <object type="button"> + <condition var1="tw_has_injecttwrp" var2="1" /> + <placement x="%col2_x%" y="%row4_y%" /> + <text>Re-Inject TWRP</text> + <actions> + <action function="set">tw_back=advanced</action> + <action function="set">tw_action=reinjecttwrp</action> + <action function="set">tw_text1=Re-Inject TWRP?</action> + <action function="set">tw_action_text1=Re-Injecting TWRP...</action> + <action function="set">tw_complete_text1=TWRP Injection Complete</action> + <action function="set">tw_slider_text=Swipe to Confirm</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="partsdcard"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Partition SD Card</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row1_y%" /> + <text></text> + <image resource="minus_button" /> + <action function="addsubtract">tw_sdext_size-128</action> + </object> + + <object type="button"> + <placement x="%sd_plus_x%" y="%row1_y%" /> + <text></text> + <image resource="plus_button" /> + <action function="addsubtract">tw_sdext_size+128</action> + </object> + + <object type="text"> + <placement x="%sdext_text_x%" y="%sdext_text_y%" /> + <text>EXT Size: %tw_sdext_size%</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%sdswap_button_y%" /> + <text></text> + <image resource="minus_button" /> + <action function="addsubtract">tw_swap_size-32</action> + </object> + + <object type="button"> + <placement x="%sd_plus_x%" y="%sdswap_button_y%" /> + <text></text> + <image resource="plus_button" /> + <action function="addsubtract">tw_swap_size+32</action> + </object> + + <object type="text"> + <placement x="%sdswap_text_x%" y="%sdswap_text_y%" /> + <text>Swap Size: %tw_swap_size%</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%sdfilesystem_text_y%" /> + <text>File system: %tw_sdpart_file_system%</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%sdfilesystem_button_y%" /> + <text>EXT3</text> + <action function="set">tw_sdpart_file_system=ext3</action> + </object> + + <object type="button"> + <condition var1="tw_sdext_disable_ext4" var2="0" /> + <placement x="%col2_x%" y="%sdfilesystem_button_y%" /> + <text>EXT4</text> + <action function="set">tw_sdpart_file_system=ext4</action> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row12_text_y%" /> + <text>You will lose all files on your SD card!</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row13_text_y%" /> + <text>This action cannot be undone!</text> + </object> + + <object type="slider"> + <text>Swipe to Partition</text> + <action function="page">partsdcardaction</action> + <actions> + <action function="set">tw_back=partsdcard</action> + <action function="set">tw_action=partitionsd</action> + <action function="set">tw_has_action2=1</action> + <action function="set">tw_action2=set</action> + <action function="set">tw_action2_param=tw_zip_location=/sdcard</action> + <action function="set">tw_action_text1=Partitioning SD Card...</action> + <action function="set">tw_action_text2=This will take a few minutes.</action> + <action function="set">tw_complete_text1=Partitioning Complete</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="htcdumlock"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>HTC Dumlock</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row1_y%" /> + <text>Restore Original Boot</text> + <actions> + <action function="set">tw_back=htcdumlock</action> + <action function="set">tw_action=htcdumlockrestoreboot</action> + <action function="set">tw_text1=Restore original boot image?</action> + <action function="set">tw_action_text1=Restoring Original Boot...</action> + <action function="set">tw_complete_text1=Restore Original Boot Complete</action> + <action function="set">tw_slider_text=Swipe to Confirm</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row1_y%" /> + <text>Reflash Recovery</text> + <actions> + <action function="set">tw_back=htcdumlock</action> + <action function="set">tw_action=htcdumlockreflashrecovery</action> + <action function="set">tw_text1=Reflash recovery to boot?</action> + <action function="set">tw_action_text1=Flashing recovery to boot...</action> + <action function="set">tw_complete_text1=Recovery Flash to Boot Complete</action> + <action function="set">tw_slider_text=Swipe to Confirm</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Install HTC Dumlock</text> + <actions> + <action function="set">tw_back=htcdumlock</action> + <action function="set">tw_action=installhtcdumlock</action> + <action function="set">tw_text1=Install HTC dumlock files to ROM?</action> + <action function="set">tw_action_text1=Installing HTC Dumlock...</action> + <action function="set">tw_complete_text1=HTC Dumlock Install Complete</action> + <action function="set">tw_slider_text=Swipe to Confirm</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="lock"> + <background color="#000000A0" /> + + <object type="image"> + <image resource="unlock-icon" /> + <placement x="%center_x%" y="%lock_y%" placement="4" /> + </object> + + <object type="slider"> + <text>Swipe to Unlock</text> + <action function="overlay"></action> + </object> + </page> + + <page name="filemanagerlist"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>File Manager: Select a File or Folder</text> + </object> + + <object type="fileselector"> + <placement x="%fileselector_x%" y="%row1_y%" w="%fileselector_width%" h="%fileselector_install_height%" /> + <text>%tw_file_location1%</text> + <filter folders="1" files="1" /> + <path name="tw_file_location1" default="/" /> + <data name="tw_filename1" /> + <selection name="tw_selection1" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="action"> + <actions> + <action function="set">tw_fm_type=File</action> + <action function="set">tw_fm_isfolder=0</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + + <object type="action"> + <condition var1="tw_filename1" op="modified" /> + <actions> + <action function="page">filemanageroptions</action> + </actions> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%filemanager_select_x%" y="%filemanager_select_y%" /> + <text>Select</text> + <actions> + <action function="set">tw_filename1=tw_file_location1</action> + <action function="set">tw_fm_isfolder=1</action> + <action function="set">tw_fm_type=Folder</action> + <action function="page">filemanageroptions</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="filemanageroptions"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5"/> + <text>%tw_fm_type% Selected:</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5"/> + <text>%tw_filename1%</text> + </object> + + <object type="button"> + <condition var1="tw_fm_isfolder" var2="0" /> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Copy File</text> + <actions> + <action function="set">tw_filemanager_command=cp</action> + <action function="set">tw_fm_text1=Copying</action> + <action function="page">choosedestinationfolder</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_fm_isfolder" var2="1" /> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Copy Folder</text> + <actions> + <action function="set">tw_filemanager_command=cd "%tw_file_location1%" && cd .. && cp -R</action> + <action function="set">tw_fm_text1=Copying</action> + <action function="page">choosedestinationfolder</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row2_y%" /> + <text>Move</text> + <actions> + <action function="set">tw_filemanager_command=mv</action> + <action function="set">tw_fm_text1=Moving</action> + <action function="page">choosedestinationfolder</action> + </actions> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row3_y%" /> + <text>chmod 755</text> + <actions> + <action function="set">tw_filemanager_command=chmod 755</action> + <action function="set">tw_fm_text1=chmod 755</action> + <action function="set">tw_fm_text2=</action> + <action function="set">tw_fm_text3=</action> + <action function="set">tw_include_text3=0</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row3_y%" /> + <text>chmod</text> + <actions> + <action function="set">tw_filemanager_rename=0000</action> + <action function="set">tw_fm_text2=</action> + <action function="set">tw_fm_text3=</action> + <action function="set">tw_include_text3=0</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerchmod</action> + </actions> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row4_y%" /> + <text>Delete</text> + <actions> + <action function="set">tw_filemanager_command=rm -rf</action> + <action function="set">tw_fm_text1=Deleting</action> + <action function="set">tw_fm_text2=</action> + <action function="set">tw_fm_text3=</action> + <action function="set">tw_include_text3=0</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_fm_isfolder" var2="0" /> + <placement x="%col2_x%" y="%row4_y%" /> + <text>Rename File</text> + <actions> + <action function="set">tw_filemanager_rename=tw_selection1</action> + <action function="set">tw_fm_text1=Renaming</action> + <action function="set">tw_filemanager_command=mv</action> + <action function="page">filemanagerrenamefile</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_fm_isfolder" var2="1" /> + <placement x="%col2_x%" y="%row4_y%" /> + <text>Rename Folder</text> + <actions> + <action function="set">tw_filemanager_rename=tw_selection1</action> + <action function="set">tw_fm_text1=Renaming</action> + <action function="set">tw_filemanager_command=cd "%tw_file_location1%" && cd .. && mv</action> + <action function="page">filemanagerrenamefolder</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">filemanagerlist</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="choosedestinationfolder"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5"/> + <text>Browse to Destination Folder & Press Select</text> + </object> + + <object type="fileselector"> + <placement x="%fileselector_x%" y="%row1_y%" w="%fileselector_width%" h="%fileselector_install_height%" /> + <text>%tw_file_location2%</text> + <filter folders="1" files="0" /> + <path name="tw_file_location2" default="/" /> + <data name="tw_filename2" /> + <selection name="tw_selection2" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">filemanageroptions</action> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%filemanager_select_x%" y="%filemanager_select_y%" /> + <text>Select</text> + <actions> + <action function="set">tw_fm_text2=to</action> + <action function="set">tw_fm_text3=%tw_file_location2%</action> + <action function="set">tw_include_text3=1</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="filemanagerrenamefile"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Please Enter a New %tw_fm_type% Name</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_filemanager_rename%</text> + <data name="tw_filemanager_rename" /> + <restrict minlen="1" maxlen="128" /> + <actions> + <action function="set">tw_fm_text2=to</action> + <action function="set">tw_fm_text3="%tw_file_location1%/%tw_filemanager_rename%"</action> + <action function="set">tw_include_text3=1</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row2_y%" /> + <text>Cancel</text> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="filemanagerrenamefolder"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Please Enter a New %tw_fm_type% Name</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_filemanager_rename%</text> + <data name="tw_filemanager_rename" /> + <restrict minlen="1" maxlen="128" /> + <actions> + <action function="set">tw_fm_text2=to</action> + <action function="set">tw_fm_text3=%tw_filemanager_rename%</action> + <action function="set">tw_include_text3=1</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row2_y%" /> + <text>Cancel</text> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="filemanagerchmod"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Please Enter New Permissions</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_filemanager_rename%</text> + <data name="tw_filemanager_rename" /> + <restrict minlen="3" maxlen="4" allow="0123456789" /> + <actions> + <action function="set">tw_filemanager_command=chmod %tw_filemanager_rename%</action> + <action function="set">tw_fm_text1=chmod %tw_filemanager_rename%</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row2_y%" /> + <text>Cancel</text> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="filemanagerconfirm"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5"/> + <text>%tw_fm_text1%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5"/> + <text>%tw_filename1%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5"/> + <text>%tw_fm_text2%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row4_text_y%" placement="5"/> + <text>%tw_fm_text3%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row10_text_y%" placement="5"/> + <text>Press back button to cancel.</text> + </object> + + <object type="slider"> + <action function="page">filemanageracction</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">%tw_back%</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="filemanageracction"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_fm_text1%</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" var2="0" /> + </conditions> + <actions> + <action function="set">tw_back=filemanagerlist</action> + <action function="set">tw_complete_text1=File Operation Complete</action> + <action function="page">action_complete</action> + </actions> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" op="!=" var2="0" /> + </conditions> + <actions> + <action function="set">tw_complete_text1=File Operation Complete</action> + <action function="page">action_complete</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_include_text3" var2="0" /> + <actions> + <action function="cmd">%tw_filemanager_command% "%tw_filename1%"</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_include_text3" var2="1" /> + <actions> + <action function="cmd">%tw_filemanager_command% "%tw_filename1%" "%tw_fm_text3%"</action> + </actions> + </object> + </page> + + <page name="decrypt"> + <object type="template" name="header" /> + + <object type="action"> + <condition var1="tw_crypto_pwtype" var2="2" /> + <action function="page">decrypt_pattern</action> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Please Enter Your Password</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_crypto_display%</text> + <data name="tw_crypto_password" mask="*" maskvariable="tw_crypto_display" /> + <restrict minlen="1" maxlen="254" /> + <actions> + <action function="page">trydecrypt</action> + </actions> + </object> + + <object type="text"> + <condition var1="tw_password_fail" var2="1" /> + <font resource="font" color="%text_fail_color%"/> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>Password Failed, Please Try Again</text> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row2_y%" /> + <text>Cancel</text> + <actions> + <action function="set">tw_page_done=1</action> + <action function="page">main</action> + </actions> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="template" name="footer" /> + </page> + + <page name="decrypt_pattern"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Please Enter Your Pattern</text> + </object> + + <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" /> + <text>Pattern Failed, Please Try Again</text> + </object> + + <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%" /> + <line color="%pattern_line_color%" width="%pattern_line_width%" /> + <data name="tw_crypto_password"/> + <action function="page">trydecrypt</action> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row4_y%" /> + <text>Cancel</text> + <actions> + <action function="set">tw_page_done=1</action> + <action function="page">main</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="trydecrypt"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Trying Decryption with Your Password</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <action function="decrypt"></action> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" op="!=" var2="0" /> + </conditions> + <actions> + <action function="set">tw_password_fail=1</action> + <action function="page">decrypt</action> + </actions> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" op="=" var2="0" /> + </conditions> + <actions> + <action function="set">tw_page_done=1</action> + <action function="page">main</action> + </actions> + </object> + </page> + + <page name="terminalfolder"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5"/> + <text>Browse to Starting Folder</text> + </object> + + <object type="fileselector"> + <placement x="%fileselector_x%" y="%row1_y%" w="%fileselector_width%" h="%fileselector_install_height%" /> + <text>%tw_terminal_location%</text> + <filter folders="1" files="0" /> + <path name="tw_terminal_location" default="/" /> + <data name="tw_terminal" /> + <selection name="tw_terminal_selection" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%filemanager_select_x%" y="%filemanager_select_y%" /> + <text>Select</text> + <actions> + <action function="page">terminalcommand</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="terminalcommand"> + <object type="template" name="header" /> + + <object type="console"> + <placement x="%console_x%" y="0" w="%console_width%" h="%terminal_console_height%" /> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%terminal_text_y%" placement="0" /> + <text>Starting Path: %tw_terminal_location%</text> + </object> + + <object type="input"> + <condition var1="tw_terminal_state" var2="0" /> + <placement x="%col1_x%" y="%terminal_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_terminal_command%</text> + <font resource="fixed" color="%text_color%" /> + <data name="tw_terminal_command" /> + <restrict minlen="1" /> + <action function="terminalcommand">%tw_terminal_command%</action> + </object> + + <object type="button" style="mediumbutton"> + <condition var1="tw_terminal_state" var2="1" /> + <placement x="%filemanager_select_x%" y="%terminal_button_y%" /> + <text>KILL</text> + <action function="killterminal"></action> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">terminalfolder</action> + </object> + </page> + + <page name="sideload"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5"/> + <text>ADB Sideload</text> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row2_text_y%" /> + <text>Wipe Dalvik Cache.</text> + <data variable="tw_wipe_dalvik" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row3_text_y%" /> + <text>Wipe Cache.</text> + <data variable="tw_wipe_cache" /> + </object> + + <object type="slider"> + <text>Swipe to Start Sideload</text> + <actions> + <action function="set">tw_back=advanced</action> + <action function="set">tw_action=adbsideload</action> + <action function="set">tw_action_text1=ADB Sideload</action> + <action function="set">tw_action_text2=Usage: adb sideload filename.zip</action> + <action function="set">tw_complete_text1=ADB Sideload Complete</action> + <action function="set">tw_has_cancel=1</action> + <action function="set">tw_show_reboot=1</action> + <action function="set">tw_cancel_action=adbsideloadcancel</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="fixperms"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5"/> + <text>Fix Permissions</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row2_text_y%" /> + <text>Note: Fixing permissions is rarely needed.</text> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row3_text_y%" /> + <text>Also fix SELinux contexts</text> + <data variable="tw_fixperms_restorecon" /> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row4_text_y%" /> + <text>Fixing SELinux contexts may cause</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row5_text_y%" /> + <text>your device to not boot properly.</text> + </object> + + <object type="slider"> + <text>Swipe to Fix Permissions</text> + <actions> + <action function="set">tw_back=advanced</action> + <action function="set">tw_action=fixpermissions</action> + <action function="set">tw_action_text1=Fixing Permissions...</action> + <action function="set">tw_complete_text1=Fix Permissions Complete</action> + <action function="set">tw_slider_text=Swipe to Confirm</action> + <action function="set">tw_show_reboot=1</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="installsu"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5"/> + <text>Install SuperSU?</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5"/> + <text>Your device does not appear to be rooted.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5"/> + <text>Install SuperSU now?</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row4_text_y%" placement="5"/> + <text>This will root your device.</text> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row3_y%" /> + <text>Do Not Install</text> + <action function="set">tw_page_done=1</action> + </object> + + <object type="slider"> + <text>Swipe to Install</text> + <actions> + <action function="set">tw_action=installsu</action> + <action function="set">tw_action_text1=Installing SuperSU</action> + <action function="set">tw_action_text2=</action> + <action function="page">singleaction_page</action> + </actions> + </object> + </page> + + <page name="system_readonly"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Keep System Read Only?</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>TWRP can leave your system partition unmodified</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>to make it easier for you to take official updates.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>TWRP will be unable to prevent the stock ROM from</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row5_text_y%" placement="5" /> + <text>replacing TWRP and will not offer to root your device.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row6_text_y%" placement="5" /> + <text>Installing zips or performing adb operations may still</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row7_text_y%" placement="5" /> + <text>modify the system partition.</text> + </object> + + <object type="checkbox"> + <condition var1="tw_is_encrypted" var2="0" /> + <placement x="%col1_x%" y="%row8_text_y%" /> + <text>Never show this screen during boot again</text> + <data variable="tw_never_show_system_ro_page" /> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row10_text_y%" /> + <text>Keep Read Only</text> + <actions> + <action function="mountsystemtoggle">1</action> + <action function="set">tw_page_done=1</action> + <action function="page">%tw_back%</action> + </actions> + </object> + + <object type="slider"> + <text>Swipe to Allow Modifications</text> + <actions> + <action function="mountsystemtoggle">0</action> + <action function="set">tw_page_done=1</action> + <action function="page">%tw_back%</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + </pages> +</recovery> diff --git a/gui/devices/resources/fonts/Roboto-Condensed-10.dat b/gui/devices/resources/fonts/Roboto-Condensed-10.dat Binary files differnew file mode 100644 index 000000000..02e869b78 --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Condensed-10.dat diff --git a/gui/devices/resources/fonts/Roboto-Condensed-12.dat b/gui/devices/resources/fonts/Roboto-Condensed-12.dat Binary files differnew file mode 100644 index 000000000..b48c4f213 --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Condensed-12.dat diff --git a/gui/devices/resources/fonts/Roboto-Condensed-14.dat b/gui/devices/resources/fonts/Roboto-Condensed-14.dat Binary files differnew file mode 100644 index 000000000..f7b174cb1 --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Condensed-14.dat diff --git a/gui/devices/resources/fonts/Roboto-Condensed-16.dat b/gui/devices/resources/fonts/Roboto-Condensed-16.dat Binary files differnew file mode 100644 index 000000000..19c11470d --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Condensed-16.dat diff --git a/gui/devices/resources/fonts/Roboto-Condensed-20.dat b/gui/devices/resources/fonts/Roboto-Condensed-20.dat Binary files differnew file mode 100644 index 000000000..531d5fdaf --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Condensed-20.dat diff --git a/gui/devices/resources/fonts/Roboto-Condensed-25.dat b/gui/devices/resources/fonts/Roboto-Condensed-25.dat Binary files differnew file mode 100644 index 000000000..7cee713e7 --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Condensed-25.dat diff --git a/gui/devices/resources/fonts/Roboto-Condensed-30.dat b/gui/devices/resources/fonts/Roboto-Condensed-30.dat Binary files differnew file mode 100644 index 000000000..621b33214 --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Condensed-30.dat diff --git a/gui/devices/resources/fonts/Roboto-Condensed-40.dat b/gui/devices/resources/fonts/Roboto-Condensed-40.dat Binary files differnew file mode 100644 index 000000000..ff23add82 --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Condensed-40.dat diff --git a/gui/devices/resources/fonts/Roboto-Condensed-50.dat b/gui/devices/resources/fonts/Roboto-Condensed-50.dat Binary files differnew file mode 100644 index 000000000..ae9c0f64d --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Condensed-50.dat diff --git a/gui/devices/resources/fonts/Roboto-Condensed-60.dat b/gui/devices/resources/fonts/Roboto-Condensed-60.dat Binary files differnew file mode 100644 index 000000000..22f9accd1 --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Condensed-60.dat diff --git a/gui/devices/resources/fonts/Roboto-Regular-10.dat b/gui/devices/resources/fonts/Roboto-Regular-10.dat Binary files differnew file mode 100644 index 000000000..b1faa7d1c --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Regular-10.dat diff --git a/gui/devices/resources/fonts/Roboto-Regular-12.dat b/gui/devices/resources/fonts/Roboto-Regular-12.dat Binary files differnew file mode 100644 index 000000000..1c9f058c3 --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Regular-12.dat diff --git a/gui/devices/resources/fonts/Roboto-Regular-14.dat b/gui/devices/resources/fonts/Roboto-Regular-14.dat Binary files differnew file mode 100644 index 000000000..5a6fff8b9 --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Regular-14.dat diff --git a/gui/devices/resources/fonts/Roboto-Regular-16.dat b/gui/devices/resources/fonts/Roboto-Regular-16.dat Binary files differnew file mode 100644 index 000000000..9f6d90005 --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Regular-16.dat diff --git a/gui/devices/resources/fonts/Roboto-Regular-20.dat b/gui/devices/resources/fonts/Roboto-Regular-20.dat Binary files differnew file mode 100644 index 000000000..6588b41e7 --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Regular-20.dat diff --git a/gui/devices/resources/fonts/Roboto-Regular-25.dat b/gui/devices/resources/fonts/Roboto-Regular-25.dat Binary files differnew file mode 100644 index 000000000..392cce97d --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Regular-25.dat diff --git a/gui/devices/resources/fonts/Roboto-Regular-30.dat b/gui/devices/resources/fonts/Roboto-Regular-30.dat Binary files differnew file mode 100644 index 000000000..9f8082ccc --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Regular-30.dat diff --git a/gui/devices/resources/fonts/Roboto-Regular-40.dat b/gui/devices/resources/fonts/Roboto-Regular-40.dat Binary files differnew file mode 100644 index 000000000..637d9fe5b --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Regular-40.dat diff --git a/gui/devices/resources/fonts/Roboto-Regular-50.dat b/gui/devices/resources/fonts/Roboto-Regular-50.dat Binary files differnew file mode 100644 index 000000000..aecce38f0 --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Regular-50.dat diff --git a/gui/devices/resources/fonts/Roboto-Regular-60.dat b/gui/devices/resources/fonts/Roboto-Regular-60.dat Binary files differnew file mode 100644 index 000000000..5840beda2 --- /dev/null +++ b/gui/devices/resources/fonts/Roboto-Regular-60.dat diff --git a/gui/devices/watch/res/watch.xml b/gui/devices/watch/res/watch.xml new file mode 100644 index 000000000..28198fb2d --- /dev/null +++ b/gui/devices/watch/res/watch.xml @@ -0,0 +1,3727 @@ +<?xml version="1.0"?> + +<recovery> + <styles> + <style name="buttontext"> + <highlight color="%highlight_color%" /> + <font resource="font" color="%button_text_color%" /> + </style> + + <style name="button"> + <style name="buttontext" /> + <image resource="main_button" /> + </style> + + <style name="mediumbutton"> + <style name="buttontext" /> + <image resource="medium_button" /> + </style> + + <style name="fillbutton"> + <style name="buttontext" /> + <fill color="%button_fill_color%" /> + </style> + + <style name="rebootsystem"> + <condition var1="tw_reboot_system" var2="1" /> + <style name="button" /> + <text>Reboot System</text> + <actions> + <action function="set">tw_back=main2</action> + <action function="set">tw_action=reboot</action> + <action function="set">tw_action_param=system</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=No OS Installed! Are you</action> + <action function="set">tw_text2=sure you wish to reboot?</action> + <action function="set">tw_text3=</action> + <action function="set">tw_text4=</action> + <action function="set">tw_action_text1=Rebooting...</action> + <action function="set">tw_action_text2=</action> + <action function="set">tw_complete_text1=Rebooting...</action> + <action function="set">tw_slider_text=Swipe to Reboot</action> + <action function="page">rebootcheck</action> + </actions> + </style> + + <style name="scrolllist"> + <highlight color="%fileselector_highlight_color%" /> + <header background="%fileselector_header_background%" textcolor="%fileselector_header_textcolor%" separatorcolor="%fileselector_header_separatorcolor%" separatorheight="%fileselector_header_separatorheight%" /> + <fastscroll linecolor="%fastscroll_linecolor%" rectcolor="%fastscroll_rectcolor%" w="%fastscroll_w%" linew="%fastscroll_linew%" rectw="%fastscroll_rectw%" recth="%fastscroll_recth%" /> + <separator color="%fileselector_separatorcolor%" height="%fileselector_separatorheight%" /> + <background color="%fileselector_background%" /> + <font resource="filelist" spacing="%fileselector_spacing%" color="%text_color%" highlightcolor="%fileselector_highlight_font_color%" /> + </style> + + <style name="fileselector"> + <style name="scrolllist" /> + <icon folder="folder_icon" file="file_icon" /> + <sort name="tw_gui_sort_order" /> + </style> + + <style name="partitionlist"> + <style name="scrolllist" /> + <icon selected="checkbox_true" unselected="checkbox_false" /> + </style> + + <style name="text"> + <font resource="font" color="%text_color%" /> + </style> + + <style name="checkbox"> + <font resource="font" color="%text_color%" /> + <image checked="checkbox_true" unchecked="checkbox_false" /> + </style> + + <style name="slider"> + <text>Swipe to Confirm</text> + <font resource="font" color="%text_color%" /> + <placement x="%center_x%" y="%slider_y%" placement="5" /> + <resource base="slider" used="slider-used" touch="slider-touch" /> + </style> + + <style name="console"> + <color foreground="%console_foreground%" background="%console_background%" scroll="%console_scroll%" /> + <font resource="fixed" /> + <fastscroll linecolor="%fastscroll_linecolor%" rectcolor="%fastscroll_rectcolor%" w="%fastscroll_w%" linew="%fastscroll_linew%" rectw="%fastscroll_rectw%" recth="%fastscroll_recth%" /> + </style> + + <style name="input"> + <background color="%input_background_color%" /> + <cursor color="%input_cursor_color%" hasfocus="1" width="%input_cursor_width%" /> + <font resource="font" color="%text_color%" /> + </style> + + <style name="slidervalue"> + <font resource="font" color="%text_color%" /> + <colors line="%slidervalue_line_clr%" slider="%slidervalue_slider_clr%" /> + <dimensions lineh="%slidervalue_lineh%" linepadding="%slidervalue_padding%" sliderw="%slidervalue_sliderw%" sliderh="%slidervalue_sliderh%" /> + </style> + </styles> + + <pages> + <page name="main"> + <object type="action"> + <actions> + <action function="set">tw_clear_destination=main2</action> + <action function="page">clear_vars</action> + </actions> + </object> + </page> + + <page name="main2"> + <object type="template" name="twrpheader" /> + + <object type="template" name="header" /> + + <object type="button"> + <placement x="%col1_x%" y="%row1_home_y%" /> + <text>Install</text> + <action function="page">install_select</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row1_home_y%" /> + <text>Wipe</text> + <action function="page">wipe</action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row2_home_y%" /> + <text>Backup</text> + <action function="page">backup</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row2_home_y%" /> + <text>Restore</text> + <action function="page">restore</action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row3_home_y%" /> + <text>Mount</text> + <action function="page">mount</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row3_home_y%" /> + <text>Settings</text> + <action function="page">settings</action> + </object> + + + <object type="button"> + <placement x="%col1_x%" y="%row4_home_y%" /> + <text>Advanced</text> + <action function="page">advanced</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row4_home_y%" /> + <text>Reboot</text> + <action function="page">reboot</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="install_select"> + <object type="template" name="twrpheader" /> + + <object type="template" name="header" /> + + <object type="button"> + <placement x="%col1_x%" y="%row1_home_y%" /> + <text>Install Zips</text> + <actions> + <action function="queueclear"></action> + <action function="page">install</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row1_home_y%" /> + <text>Install Images</text> + <action function="page">install_image</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="install"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Select Zip to Install</text> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col1_x%" y="%row1_text_y%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" /> + <text>Storage: %tw_storage_display_name% (%tw_storage_free_size% MB)</text> + <actions> + <action function="set">tw_back=install</action> + <action function="page">selectstorage</action> + </actions> + </object> + + <object type="fileselector"> + <placement x="%fileselector_x%" y="%fileselector_y%" w="%fileselector_width%" h="%fileselector_install_height%" /> + <text>%tw_zip_location%</text> + <filter extn=".zip" folders="1" files="1" /> + <path name="tw_zip_location" default="/sdcard" /> + <data name="tw_filename" /> + <selection name="tw_file" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="action"> + <condition var1="tw_filename" op="modified" /> + <actions> + <action function="queuezip"></action> + <action function="page">flash_confirm</action> + </actions> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">install_select</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="flash_confirm"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>This operation may install incompatible</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>software and render your device unusable.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Folder and File:</text> + </object> + + <object type="text"> + <font resource="mediumfont" color="%text_color%" /> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_zip_location%</text> + </object> + + <object type="text"> + <font resource="mediumfont" color="%text_color%" /> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>%tw_file%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row5_text_y%" placement="5" /> + <text>Press back to cancel adding this zip.</text> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row6_text_y%" /> + <text>Zip file signature verification.</text> + <data variable="tw_signed_zip_verify" /> + </object> + + <object type="checkbox"> + <condition var1="tw_has_injecttwrp" var2="1" /> + <placement x="%col1_x%" y="%row7_text_y%" /> + <text>Inject TWRP after install.</text> + <data variable="tw_inject_after_zip" /> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row11_text_y%" placement="5" /> + <text>File %tw_zip_queue_count% of max of 10</text> + </object> + + <object type="slider"> + <text>Swipe to Confirm Flash</text> + <action function="flash">flash_zip</action> + </object> + + <object type="button"> + <condition var1="tw_zip_queue_count" op="!=" var2="10"></condition> + <placement x="%col1_x%" y="%row_queue_y%" /> + <text>Add More Zips</text> + <action function="page">install</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row_queue_y%" /> + <text>Clear Zip Queue</text> + <actions> + <action function="queueclear"></action> + <action function="page">install</action> + </actions> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="cancelzip"></action> + <action function="page">install</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + </page> + + <page name="flash_zip"> + <object type="template" name="header" /> + + <object type="console"> + <placement x="%console_x%" y="%row1_y%" w="%console_width%" h="%console_install_height%" /> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row10_text_y%" placement="5" /> + <text>Flashing file %tw_zip_index% of %tw_zip_queue_count%</text> + </object> + + <object type="text"> + <font resource="mediumfont" color="%text_color%"/> + <placement x="%center_x%" y="%row11_text_y%" placement="5" /> + <text>%tw_filename%</text> + </object> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <action function="page">flash_done</action> + </object> + </page> + + <page name="flash_done"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Zip Install Complete</text> + </object> + + <object type="console"> + <placement x="%console_x%" y="%row1_y%" w="%console_width%" h="%console_installdone_height%" /> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row4_y%" /> + <text>Wipe cache/dalvik</text> + <actions> + <action function="set">tw_back=flash_done</action> + <action function="set">tw_action=wipe</action> + <action function="set">tw_action_param=/cache</action> + <action function="set">tw_has_action2=1</action> + <action function="set">tw_action2=wipe</action> + <action function="set">tw_action2_param=dalvik</action> + <action function="set">tw_text1=Wipe Cache & Dalvik?</action> + <action function="set">tw_action_text1=Wiping Cache & Dalvik...</action> + <action function="set">tw_complete_text1=Cache & Dalvik Wipe Complete</action> + <action function="set">tw_slider_text=Swipe to Wipe</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button" style="rebootsystem"> + <placement x="%col2_x%" y="%row4_y%" /> + </object> + + <object type="text"> + <condition var1="tw_operation_status" op="!=" var2="0" /> + <font resource="font" color="%text_fail_color%" /> + <placement x="%center_x%" y="%zip_status_y%" placement="5" /> + <text>Failed</text> + </object> + + <object type="text"> + <condition var1="tw_operation_status" var2="0" /> + <font resource="font" color="%text_success_color%" /> + <placement x="%center_x%" y="%zip_status_y%" placement="5" /> + <text>Successful</text> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="set">tw_clear_destination=install</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <actions> + <action function="set">tw_clear_destination=main2</action> + <action function="page">clear_vars</action> + </actions> + </object> + </page> + + <page name="install_image"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Select Image to Install</text> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col1_x%" y="%row1_text_y%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" /> + <text>Storage: %tw_storage_display_name% (%tw_storage_free_size% MB)</text> + <actions> + <action function="set">tw_back=install_image</action> + <action function="page">selectstorage</action> + </actions> + </object> + + <object type="fileselector"> + <placement x="%fileselector_x%" y="%row3_text_y%" w="%fileselector_width%" h="%fileselector_install_height%" /> + <text>%tw_zip_location%</text> + <filter extn=".img" folders="1" files="1" /> + <path name="tw_zip_location" default="/sdcard" /> + <data name="tw_filename" /> + <selection name="tw_file" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="action"> + <condition var1="tw_filename" op="modified" /> + <action function="page">flashimage_confirm</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">install_select</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="flashimage_confirm"> + <object type="template" name="header" /> + + <object type="partitionlist"> + <placement x="%listbox_x%" y="%row1_header_y%" w="%listbox_width%" h="%flash_list_height%" /> + <text>Select Partition to Flash Image:</text> + <icon selected="radio_true" unselected="radio_false" /> + <data name="tw_flash_partition" /> + <listtype name="flashimg" /> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row8_text_y%" placement="5" /> + <text>Folder:</text> + </object> + + <object type="text"> + <font resource="mediumfont" color="%text_color%" /> + <placement x="%center_x%" y="%row9_text_y%" placement="5" /> + <text>%tw_zip_location%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row10_text_y%" placement="5" /> + <text>File to flash:</text> + </object> + + <object type="text" > + <font resource="mediumfont" color="%text_color%" /> + <placement x="%center_x%" y="%row11_text_y%" placement="5" /> + <text>%tw_file%</text> + </object> + + <object type="slider"> + <text>Swipe to Confirm Flash</text> + <actions> + <action function="set">tw_back=flashimage_confirm</action> + <action function="set">tw_action=flashimage</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_action_text1=Flashing Image...</action> + <action function="set">tw_action_text2=</action> + <action function="set">tw_complete_text1=Image Flashed</action> + <action function="page">action_page</action> + </actions> + <action function="flashimage"></action> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="set">tw_clear_destination=install_image</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <actions> + <action function="set">tw_clear_destination=main2</action> + <action function="page">clear_vars</action> + </actions> + </object> + </page> + + <page name="clear_vars"> + <object type="action"> + <action function="set">tw_operation_state=0</action> + <action function="set">tw_text1=</action> + <action function="set">tw_text2=</action> + <action function="set">tw_text3=</action> + <action function="set">tw_text4=</action> + <action function="set">tw_action_text1=</action> + <action function="set">tw_action_text2=</action> + <action function="set">tw_action_param=</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_action2=</action> + <action function="set">tw_action2_param=</action> + <action function="set">tw_has_cancel=0</action> + <action function="set">tw_cancel_action=</action> + <action function="set">tw_cancel_param=</action> + <action function="set">tw_show_exclamation=0</action> + <action function="set">tw_show_reboot=0</action> + <action function="page">%tw_clear_destination%</action> + </object> + </page> + + <page name="confirm_action"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_text1%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_text2%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_text3%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>%tw_text4%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row15_text_y%" placement="5" /> + <text>Press back button to cancel.</text> + </object> + + <object type="slider"> + <text>%tw_slider_text%</text> + <action function="page">action_page</action> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="set">tw_clear_destination=%tw_back%</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + </page> + + <page name="action_page"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_action_text1%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_action_text2%</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="button" style="mediumbutton"> + <condition var1="tw_has_cancel" var2="1" /> + <placement x="%col_center_medium_x%" y="%row4_y%" /> + <text>Cancel</text> + <action function="%tw_cancel_action%">%tw_cancel_param%</action> + </object> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <actions> + <action function="page">action_complete</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_has_action2" var2="0" /> + <actions> + <action function="%tw_action%">%tw_action_param%</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_has_action2" var2="1" /> + <actions> + <action function="%tw_action%">%tw_action_param%</action> + <action function="%tw_action2%">%tw_action2_param%</action> + </actions> + </object> + </page> + + <page name="singleaction_page"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_action_text1%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_action_text2%</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <actions> + <action function="set">tw_page_done=1</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_has_action2" var2="0" /> + <actions> + <action function="%tw_action%">%tw_action_param%</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_has_action2" var2="1" /> + <actions> + <action function="%tw_action%">%tw_action_param%</action> + <action function="%tw_action2%">%tw_action2_param%</action> + </actions> + </object> + </page> + + <page name="action_complete"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_complete_text1%</text> + </object> + + <object type="text"> + <condition var1="tw_operation_status" op="!=" var2="0" /> + <font resource="font" color="%text_fail_color%" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Failed</text> + </object> + + <object type="text"> + <condition var1="tw_operation_status" var2="0" /> + <font resource="font" color="%text_success_color%" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Successful</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="action"> + <touch key="home" /> + <actions> + <action function="set">tw_clear_destination=main2</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="set">tw_clear_destination=%tw_back%</action> + <action function="page">clear_vars</action> + </actions> + </object> + </page> + + <page name="filecheck"> + <object type="action"> + <action function="fileexists">%tw_filecheck%</action> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" var2="0" /> + </conditions> + <actions> + <action function="set">tw_fileexists=1</action> + <action function="page">%tw_existpage%</action> + </actions> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" var2="1" /> + </conditions> + <actions> + <action function="set">tw_fileexists=0</action> + <action function="page">%tw_notexistpage%</action> + </actions> + </object> + </page> + + <page name="rebootcheck"> + <object type="action"> + <condition var1="tw_backup_system_size" op=">=" var2="%tw_min_system%" /> + <action function="reboot">%tw_action_param%</action> + </object> + + <object type="action"> + <condition var1="tw_backup_system_size" op="<" var2="%tw_min_system%" /> + <action function="page">confirm_action</action> + </object> + </page> + + <page name="wipe"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Factory Reset</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Wipes Data, Cache, and Dalvik</text> + </object> + + <object type="text"> + <condition var1="tw_has_data_media" var2="1" /> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>(not including internal storage)</text> + </object> + + <object type="text"> + <conditions> + <condition var1="tw_has_android_secure" var2="1" /> + <condition var1="fileexists" var2="/and-sec" /> + </conditions> + <placement x="%col2_x%" y="%row4_text_y%" placement="1" /> + <text>Android Secure </text> + </object> + + <object type="text"> + <condition var1="tw_has_sdext_partition" var2="1" /> + <placement x="%col2_x%" y="%row4_text_y%" /> + <text> SD-EXT</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row5_text_y%" placement="5" /> + <text>Most of the time this is</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row6_text_y%" placement="5" /> + <text>the only wipe that you need.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row16_text_y%" placement="5" /> + <text>Press back button to cancel.</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%wipe_button_y%" /> + <text>Advanced Wipe</text> + <actions> + <action function="set">partitionlisterror=0</action> + <action function="page">advancedwipe</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_has_data_media" var2="1" /> + <placement x="%col2_x%" y="%wipe_button_y%" /> + <text>Format Data</text> + <actions> + <action function="page">formatdata</action> + </actions> + </object> + + <object type="button"> + <conditions> + <condition var1="tw_is_encrypted" var2="1" /> + <condition var1="tw_has_data_media" var2="0" /> + </conditions> + <placement x="%col2_x%" y="%wipe_button_y%" /> + <text>Wipe Encryption</text> + <actions> + <action function="set">tw_back=wipe</action> + <action function="set">tw_action=wipe</action> + <action function="set">tw_action_param=DATAMEDIA</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Wipe Encryption from Data?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting Data...</action> + <action function="set">tw_complete_text1=Data Format Complete</action> + <action function="set">tw_slider_text=Swipe to Format Data</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="slider"> + <text>Swipe to Factory Reset</text> + <actions> + <action function="set">tw_back=wipe</action> + <action function="set">tw_action=wipe</action> + <action function="set">tw_action_param=data</action> + <action function="set">tw_action_text1=Factory Reset...</action> + <action function="set">tw_complete_text1=Factory Reset Complete</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + </page> + + <page name="advancedwipe"> + <object type="template" name="header" /> + + <object type="action"> + <action function="set">tw_wipe_list=</action> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Wipe Menu</text> + </object> + + <object type="partitionlist"> + <placement x="%listbox_x%" y="%row1_header_y%" w="%listbox_width%" h="%wipe_list_height%" /> + <text>Select Partitions to Wipe:</text> + <data name="tw_wipe_list" /> + <listtype name="wipe" /> + </object> + + <object type="slider"> + <text>Swipe to Wipe</text> + <actions> + <action function="set">tw_back=advancedwipe</action> + <action function="set">tw_action=wipe</action> + <action function="set">tw_action_param=LIST</action> + <action function="set">tw_text1=Wipe Selected Partition(s)?</action> + <action function="set">tw_action_text1=Wiping Partition(s)...</action> + <action function="set">tw_complete_text1=Wipe Complete</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col1_x%" y="%wipe_button_row1%" w="%button_fill_full_width%" h="%button_fill_half_height%" /> + <text>Repair or Change File System</text> + <actions> + <action function="checkpartitionlist"></action> + <action function="page">checkpartitionlist</action> + </actions> + </object> + + <object type="text"> + <condition var1="partitionlisterror" var2="1" /> + <font resource="font" color="%text_fail_color%" /> + <placement x="%center_x%" y="%invalid_partition_y%" placement="5" /> + <text>Invalid partition selection</text> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">wipe</action> + </object> + </page> + + <page name="formatdata"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Format Data will wipe all of your apps,</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>backups, pictures, videos, media, and</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>removes encryption on internal storage.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>This cannot be undone. Press back to cancel.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>Type yes to continue.</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row6_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_confirm_formatdata%</text> + <data name="tw_confirm_formatdata" /> + <restrict minlen="3" maxlen="3" allow="yes" /> + <action function="page">formatdata_confirm</action> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">wipe</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="formatdata_confirm"> + <object type="action"> + <condition var1="tw_confirm_formatdata" op="=" var2="yes" /> + <actions> + <action function="set">tw_back=formatdata</action> + <action function="set">tw_action=wipe</action> + <action function="set">tw_action_param=DATAMEDIA</action> + <action function="set">tw_action_text1=Formatting Data...</action> + <action function="set">tw_complete_text1=Data Format Complete</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_confirm_formatdata" op="!=" var2="yes" /> + <action function="page">formatdata</action> + </object> + </page> + + <page name="checkpartitionlist"> + <object type="action"> + <condition var1="tw_check_partition_list" op="=" var2="1" /> + <actions> + <action function="set">partitionlisterror=0</action> + <action function="getpartitiondetails"></action> + <action function="page">partitionoptions</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_check_partition_list" op="!=" var2="1" /> + <actions> + <action function="set">partitionlisterror=1</action> + <action function="set">tw_wipe_list=</action> + <action function="page">advancedwipe</action> + </actions> + </object> + </page> + + <page name="partitionoptions"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Partition Options for: %tw_partition_name%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Mount Point: %tw_partition_mount_point%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Current file system: %tw_partition_file_system%</text> + </object> + + <object type="text"> + <condition var1="tw_partition_is_present" op="!=" var2="0" /> + <placement x="%col1_x%" y="%row3_text_y%" /> + <text>Present: Yes</text> + </object> + + <object type="text"> + <condition var1="tw_partition_is_present" op="=" var2="0" /> + <placement x="%col1_x%" y="%row3_text_y%" /> + <text>Present: No</text> + </object> + + <object type="text"> + <condition var1="tw_partition_removable" op="!=" var2="0" /> + <placement x="%col2_x%" y="%row3_text_y%" /> + <text>Removable: Yes</text> + </object> + + <object type="text"> + <condition var1="tw_partition_removable" op="=" var2="0" /> + <placement x="%col2_x%" y="%row3_text_y%" /> + <text>Removable: No</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row4_text_y%" /> + <text>Size: %tw_partition_size%MB</text> + </object> + + <object type="text"> + <placement x="%col2_x%" y="%row4_text_y%" /> + <text>Used: %tw_partition_used%MB</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row5_text_y%" /> + <text>Free: %tw_partition_free%MB</text> + </object> + + <object type="text"> + <placement x="%col2_x%" y="%row5_text_y%" /> + <text>Backup Size: %tw_partition_backup_size%MB</text> + </object> + + <object type="button"> + <condition var1="tw_partition_can_resize" op="=" var2="1" /> + <placement x="%col1_x%" y="%row3_y%" /> + <text>Resize</text> + <actions> + <action function="set">tw_back=partitionoptions</action> + <action function="set">tw_action=resize</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_has_action2=1</action> + <action function="set">tw_action2=getpartitiondetails</action> + <action function="set">tw_text1=Resize %tw_partition_name%?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Resizing...</action> + <action function="set">tw_complete_text1=Resize Complete</action> + <action function="set">tw_slider_text=Swipe to Resize</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_can_repair" op="=" var2="1" /> + <placement x="%col1_x%" y="%row4_y%" /> + <text>Repair</text> + <actions> + <action function="set">tw_back=partitionoptions</action> + <action function="set">tw_action=repair</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Repair %tw_partition_name%?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Repairing...</action> + <action function="set">tw_complete_text1=Repair Complete</action> + <action function="set">tw_slider_text=Swipe to Repair</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row4_y%" /> + <text>Change File Sys</text> + <action function="page">selectfilesystem</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advancedwipe</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="refreshfilesystem"> + <object type="action"> + <condition var1="tw_check_partition_list" op="=" var2="1" /> + <actions> + <action function="set">partitionlisterror=0</action> + <action function="getpartitiondetails"></action> + <action function="page">selectfilesystem</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_check_partition_list" op="!=" var2="1" /> + <actions> + <action function="set">partitionlisterror=1</action> + <action function="set">tw_wipe_list=</action> + <action function="page">advancedwipe</action> + </actions> + </object> + </page> + + <page name="selectfilesystem"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Change file system for: %tw_partition_name%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Mount Point: %tw_partition_mount_point%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Current file system: %tw_partition_file_system%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>Proceed with caution!</text> + </object> + + <object type="button"> + <condition var1="tw_partition_ext" op="=" var2="1" /> + <placement x="%col1_x%" y="%row2_y%" /> + <text>EXT2</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=ext2</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to EXT2?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_ext" op="=" var2="1" /> + <placement x="%col2_x%" y="%row2_y%" /> + <text>EXT3</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=ext3</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to EXT3?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_ext" op="=" var2="1" /> + <placement x="%col1_x%" y="%row3_y%" /> + <text>EXT4</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=ext4</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to EXT4?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_f2fs" op="=" var2="1" /> + <placement x="%col2_x%" y="%row3_y%" /> + <text>F2FS</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=f2fs</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to F2FS?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_vfat" op="=" var2="1" /> + <placement x="%col1_x%" y="%row4_y%" /> + <text>FAT</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=vfat</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to FAT?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_partition_exfat" op="=" var2="1" /> + <placement x="%col2_x%" y="%row4_y%" /> + <text>exFAT</text> + <actions> + <action function="set">tw_back=refreshfilesystem</action> + <action function="set">tw_action=changefilesystem</action> + <action function="set">tw_action_param=%tw_partition_mount_point%</action> + <action function="set">tw_action_new_file_system=exfat</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=Change %tw_partition_name% to exFAT?</action> + <action function="set">tw_text2=</action> + <action function="set">tw_action_text1=Formatting...</action> + <action function="set">tw_complete_text1=Format Complete</action> + <action function="set">tw_slider_text=Swipe to Change</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">partitionoptions</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="backup"> + <object type="template" name="header" /> + + <object type="button" style="fillbutton"> + <placement x="%col1_x%" y="%row1_header_y%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" /> + <text>Backup Name: %tw_backup_name%</text> + <actions> + <action function="set">tw_fileexists=0</action> + <action function="page">backupname1</action> + </actions> + </object> + + <object type="partitionlist"> + <placement x="%listbox_x%" y="%backup_list_y%" w="%listbox_width%" h="%backup_list_height%" /> + <text>Select Partitions to Back Up:</text> + <data name="tw_backup_list" /> + <listtype name="backup" /> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col2_x%" y="%backup_button_row1%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" /> + <text>More...</text> + <action function="page">backupoptions</action> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col1_x%" y="%backup_button_row2%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" /> + <text>Storage: %tw_storage_display_name% (%tw_storage_free_size% MB)</text> + <actions> + <action function="set">tw_back=backup</action> + <action function="page">selectstorage</action> + </actions> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%backup_button_row1%" /> + <text>Compression</text> + <data variable="tw_use_compression" /> + </object> + + <object type="slider"> + <text>Swipe to Back Up</text> + <action function="page">backup_run</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + </page> + + <page name="backupoptions"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>More Backup Options</text> + </object> + + <object type="button" style="fillbutton"> + <conditions> + <condition var1="tw_include_encrypted_backup" var2="1" /> + <condition var1="tw_encrypt_backup" var2="0" /> + </conditions> + <placement x="%col1_x%" y="%row6_text_y%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" /> + <text>No Encryption</text> + <actions> + <action function="page">backupencryption</action> + </actions> + </object> + + <object type="button" style="fillbutton"> + <conditions> + <condition var1="tw_include_encrypted_backup" var2="1" /> + <condition var1="tw_encrypt_backup" var2="1" /> + </conditions> + <placement x="%col1_x%" y="%row6_text_y%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" /> + <text>Using Encryption</text> + <actions> + <action function="set">tw_password_not_match=0</action> + <action function="page">backupencryption</action> + </actions> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col2_x%" y="%row6_text_y%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" /> + <text>Refresh Sizes</text> + <actions> + <action function="refreshsizes"></action> + <action function="page">backupoptions</action> + </actions> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col1_x%" y="%backup_button_row2%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" /> + <text>Storage: %tw_storage_display_name% (%tw_storage_free_size% MB)</text> + <actions> + <action function="set">tw_back=backupotions</action> + <action function="page">selectstorage</action> + </actions> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row2_text_y%" /> + <text>Enable compression.</text> + <data variable="tw_use_compression" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row3_text_y%" /> + <text>Skip MD5 generation during backup.</text> + <data variable="tw_skip_md5_generate" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row4_text_y%" /> + <font resource="font" color="%text_color%" /> + <text>Disable Free Space Check.</text> + <data variable="tw_disable_free_space" /> + <image checked="checkbox_true" unchecked="checkbox_false" /> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">backup</action> + </object> + </page> + + <page name="backupname1"> + <object type="action"> + <condition var1="tw_backup_name" op="=" var2="(Auto Generate)" /> + <action function="generatebackupname"></action> + </object> + + <object type="action"> + <action function="page">backupname2</action> + </object> + </page> + + <page name="backupname2"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Please Enter a Backup Name</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_backup_name%</text> + <data name="tw_backup_name" /> + <restrict minlen="1" maxlen="64" allow=" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_.{}[]" /> + <actions> + <action function="set">tw_filecheck=%tw_backups_folder%/%tw_backup_name%</action> + <action function="set">tw_existpage=backupname2</action> + <action function="set">tw_notexistpage=backup</action> + <action function="page">filecheck</action> + </actions> + </object> + + <object type="text"> + <condition var1="tw_fileexists" var2="1" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <font resource="font" color="%text_fail_color%" /> + <text>A backup with that name already exists!</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Append Date</text> + <action function="appenddatetobackupname"></action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row2_y%" /> + <text>Cancel</text> + <actions> + <action function="set">tw_backup_name=(Auto Generate)</action> + <action function="page">backup</action> + </actions> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <actions> + <action function="set">tw_backup_name=(Auto Generate)</action> + <action function="page">main</action> + </actions> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="set">tw_backup_name=(Auto Generate)</action> + <action function="page">backup</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="backupencryption"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Encrypt your backup?</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Please Enter A Password:</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_backup_encrypt_display%</text> + <data name="tw_backup_password" mask="*" maskvariable="tw_backup_encrypt_display" /> + <restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" /> + <action function="page">backupencryption2</action> + </object> + + <object type="text"> + <condition var1="tw_password_not_match" var2="1" /> + <font resource="font" color="%text_fail_color%" /> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>Passwords Do Not Match</text> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row2_y%" /> + <text>Cancel</text> + <actions> + <action function="set">tw_encrypt_backup=0</action> + <action function="set">tw_backup_password=</action> + <action function="set">tw_backup_password2=</action> + <action function="set">tw_backup_encrypt_display=</action> + <action function="set">tw_backup_encrypt_display2=</action> + <action function="page">backupoptions</action> + </actions> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">backupoptions</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="backupencryption2"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Encrypt your backup?</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Please Enter Password Again:</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_backup_encrypt_display2%</text> + <data name="tw_backup_password2" mask="*" maskvariable="tw_backup_encrypt_display2" /> + <restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" /> + <actions> + <action function="page">checkbackuppassword</action> + </actions> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row2_y%" /> + <text>Cancel</text> + <actions> + <action function="set">tw_encrypt_backup=0</action> + <action function="set">tw_backup_password=</action> + <action function="set">tw_backup_password2=</action> + <action function="set">tw_backup_encrypt_display=</action> + <action function="set">tw_backup_encrypt_display2=</action> + <action function="page">backupoptions</action> + </actions> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">backupoptions</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="checkbackuppassword"> + <object type="action"> + <condition var1="tw_backup_password2" var2="tw_backup_password" /> + <actions> + <action function="set">tw_encrypt_backup=1</action> + <action function="page">backupoptions</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_backup_password2" op="!=" var2="tw_backup_password" /> + <actions> + <action function="set">tw_encrypt_backup=0</action> + <action function="set">tw_password_not_match=1</action> + <action function="set">tw_backup_password=</action> + <action function="set">tw_backup_password2=</action> + <action function="set">tw_backup_encrypt_display=</action> + <action function="set">tw_backup_encrypt_display2=</action> + <action function="page">backupencryption</action> + </actions> + </object> + </page> + + <page name="backup_run"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_operation% %tw_partition%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_file_progress%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + + <object type="template" name="action_page_console" /> + + + + <object type="template" name="progress_bar" /> + + <object type="button" style="mediumbutton"> + <placement x="%col_center_medium_x%" y="%row4_y%" /> + <text>Cancel</text> + <actions> + <action function="cancelbackup"></action> + </actions> + </object> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <action function="nandroid">backup</action> + </object> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_cancel_backup" var2="0" /> + <actions> + <action function="set">tw_back=backup</action> + <action function="set">tw_complete_text1=Backup Complete</action> + <action function="set">tw_show_reboot=1</action> + <action function="page">action_complete</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_cancel_backup" var2="1" /> + <actions> + <action function="set">tw_back=backup</action> + <action function="set">tw_complete_text1=Backup Cancelled</action> + <action function="set">tw_show_reboot=1</action> + <action function="page">action_complete</action> + </actions> + </object> + </page> + + <page name="restore"> + <object type="template" name="header" /> + + <object type="button" style="fillbutton"> + <placement x="%col1_x%" y="%row1_header_y%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" /> + <text>Storage: %tw_storage_display_name% (%tw_storage_free_size% MB)</text> + <actions> + <action function="set">tw_back=restore</action> + <action function="page">selectstorage</action> + </actions> + </object> + + <object type="fileselector"> + <placement x="%fileselector_x%" y="%row2_text_y%" w="%fileselector_width%" h="%fileselector_install_height%" /> + <text>Select Package to Restore:</text> + <filter folders="1" files="0" nav="0" /> + <path name="tw_backups_folder" /> + <data name="tw_restore" default="" /> + <selection name="tw_restore_name" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="action"> + <condition var1="tw_restore" op="modified" /> + <actions> + <action function="readBackup"></action> + <action function="page">restore_read</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="restore_read"> + <object type="action"> + <condition var1="tw_restore_encrypted" var2="1" /> + <actions> + <action function="set">tw_password_fail=0</action> + <action function="page">restore_decrypt</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_restore_encrypted" var2="0" /> + <actions> + <action function="page">restore_select</action> + </actions> + </object> + </page> + + <page name="restore_decrypt"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Backup Encrypted</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Please Enter Your Password:</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_restore_display%</text> + <data name="tw_restore_password" mask="*" maskvariable="tw_restore_display" /> + <restrict minlen="1" maxlen="32" allow="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_" /> + <actions> + <action function="page">try_restore_decrypt</action> + </actions> + </object> + + <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" /> + <text>Password Failed, Please Try Again</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Cancel</text> + <actions> + <action function="set">tw_page_done=1</action> + <action function="page">restore</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row2_y%" /> + <text>Delete</text> + <actions> + <action function="set">tw_back=restore</action> + <action function="set">tw_action=cmd</action> + <action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf "%tw_restore_name%"</action> + <action function="set">tw_text1=Delete Backup? %tw_restore_name%</action> + <action function="set">tw_text2=This cannot be undone!</action> + <action function="set">tw_action_text1=Deleting Backup...</action> + <action function="set">tw_complete_text1=Backup Delete Complete</action> + <action function="set">tw_slider_text=Swipe to Delete</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">restore</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="try_restore_decrypt"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Trying Decryption with Your Password</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <action function="decrypt_backup"></action> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" op="!=" var2="0" /> + </conditions> + <actions> + <action function="set">tw_password_fail=1</action> + <action function="page">restore_decrypt</action> + </actions> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" op="=" var2="0" /> + </conditions> + <actions> + <action function="set">tw_page_done=1</action> + <action function="page">restore_select</action> + </actions> + </object> + </page> + + <page name="restore_select"> + <object type="template" name="header" /> + + <object type="partitionlist"> + <placement x="%listbox_x%" y="%row1_header_y%" w="%listbox_width%" h="%restore_list_height%" /> + <text>Restoring: %tw_restore_name%</text> + <data name="tw_restore_list" selectedlist="tw_restore_selected" /> + <listtype name="restore" /> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col1_x%" y="%backup_button_row2%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" /> + <text>Rename Backup</text> + <actions> + <action function="set">tw_backup_rename=</action> + <action function="set">tw_fileexists=0</action> + <action function="page">renamebackup</action> + </actions> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col2_x%" y="%backup_button_row2%" w="%button_fill_main_width%" h="%button_fill_quarter_height%" /> + <text>Delete Backup</text> + <actions> + <action function="set">tw_back=restore</action> + <action function="set">tw_action=cmd</action> + <action function="set">tw_action_param=cd %tw_backups_folder% && rm -rf "%tw_restore_name%"</action> + <action function="set">tw_text1=Delete Backup? %tw_restore_name%</action> + <action function="set">tw_text2=This cannot be undone!</action> + <action function="set">tw_action_text1=Deleting Backup...</action> + <action function="set">tw_complete_text1=Backup Delete Complete</action> + <action function="set">tw_slider_text=Swipe to Delete</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%backup_button_row1%" /> + <text>Enable MD5 verification of backup.</text> + <data variable="tw_skip_md5_check" /> + </object> + + <object type="slider"> + <text>Swipe to Restore</text> + <action function="page">restore_run</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">restore</action> + </object> + </page> + + <page name="renamebackup"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Please Enter a New Backup Name</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_backup_rename%</text> + <data name="tw_backup_rename" /> + <restrict minlen="1" maxlen="64" allow=" abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_.{}[]" /> + <actions> + <action function="set">tw_back=restore</action> + <action function="set">tw_action=cmd</action> + <action function="set">tw_action_param=cd %tw_backups_folder% && mv "%tw_restore_name%" "%tw_backup_rename%"</action> + <action function="set">tw_text1=Rename Backup?</action> + <action function="set">tw_text2=This cannot be undone!</action> + <action function="set">tw_action_text1=Renaming Backup...</action> + <action function="set">tw_complete_text1=Backup Rename Complete</action> + <action function="set">tw_slider_text=Swipe to Rename</action> + <action function="set">tw_filecheck=%tw_backups_folder%/%tw_backup_rename%</action> + <action function="set">tw_existpage=renamebackup</action> + <action function="set">tw_notexistpage=confirm_action</action> + <action function="page">filecheck</action> + </actions> + </object> + + <object type="text"> + <condition var1="tw_fileexists" var2="1" /> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <font resource="font" color="%text_fail_color%" /> + <text>A backup with that name already exists!</text> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row2_y%" /> + <text>Cancel</text> + <action function="page">restore_select</action> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">restore_select</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="restore_run"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_operation% %tw_partition%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>%tw_size_progress%</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <condition var1="tw_operation_state" var2="1" /> + <actions> + <action function="set">tw_back=restore_select</action> + <action function="set">tw_complete_text1=Restore Complete</action> + <action function="set">tw_show_reboot=1</action> + <action function="page">action_complete</action> + </actions> + </object> + + <object type="action"> + <action function="nandroid">restore</action> + </object> + </page> + + <page name="selectstorage"> + <object type="template" name="header" /> + + <object type="partitionlist"> + <placement x="%listbox_x%" y="%row1_header_y%" w="%listbox_width%" h="%storage_list_height%" /> + <text>Select Storage:</text> + <icon selected="radio_true" unselected="radio_false" /> + <data name="tw_storage_path" /> + <listtype name="storage" /> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row4_y%" /> + <text>OK</text> + <actions> + <action function="set">tw_clear_destination=%tw_back%</action> + <action function="page">clear_vars</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <actions> + <action function="page">%tw_back%</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="mount"> + <object type="template" name="header" /> + + <object type="partitionlist"> + <placement x="%listbox_x%" y="%row1_header_y%" w="%listbox_width%" h="%mount_list_height%" /> + <text>Select Partitions to Mount:</text> + <listtype name="mount" /> + </object> + + <object type="button" style="fillbutton"> + <placement x="%col1_x%" y="%mount_storage_row%" w="%button_fill_full_width%" h="%button_fill_quarter_height%" /> + <text>Storage: %tw_storage_display_name% (%tw_storage_free_size% MB)</text> + <actions> + <action function="set">tw_back=mount</action> + <action function="page">selectstorage</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_has_usb_storage" var2="1" /> + <placement x="%col1_x%" y="row4_y" /> + <text>USB Storage</text> + <action function="page">usb_mount</action> + </object> + + <object type="button"> + <conditions> + <condition var1="tw_has_mtp" var2="1" /> + <condition var1="tw_mtp_enabled" var2="0" /> + </conditions> + <placement x="%col2_x%" y="row4_y" /> + <text>Enable MTP</text> + <action function="startmtp"></action> + </object> + + <object type="button"> + <conditions> + <condition var1="tw_has_mtp" var2="1" /> + <condition var1="tw_mtp_enabled" var2="1" /> + </conditions> + <placement x="%col2_x%" y="row4_y" /> + <text>Disable MTP</text> + <action function="stopmtp"></action> + </object> + + <object type="button"> + <conditions> + <condition var1="tw_is_encrypted" var2="1" /> + <condition var1="tw_is_decrypted" var2="0" /> + </conditions> + <placement x="%col2_x%" y="row4_y" /> + <text>Decrypt Data</text> + <action function="page">decrypt</action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%system_ro_y%" /> + <font resource="font" color="%text_color%" /> + <condition var1="tw_mount_system_ro" op="=" var2="0" /> + <text>Only mount system read-only</text> + <image resource="checkbox_false" /> + <action function="mountsystemtoggle">1</action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%system_ro_y%" /> + <font resource="font" color="%text_color%" /> + <condition var1="tw_mount_system_ro" op="!=" var2="0" /> + <text>Only mount system read-only</text> + <image resource="checkbox_true" /> + <actions> + <action function="set">tw_lifetime_writes=2</action> + <action function="page">system_readonly_check</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="usb_mount"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>USB Storage Mounted</text> + </object> + + <object type="text" color="%text_color%"> + <placement x="%col1_x%" y="%row1_text_y%" /> + <font resource="font" /> + <text>Be sure to safely remove your device</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row2_text_y%" /> + <text>from your computer before unmounting!</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row3_y%" /> + <text>Unmount</text> + <action function="page">usb_umount</action> + </object> + + <object type="action"> + <action function="mount">usb</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="usb_umount"> + <object type="action"> + <action function="unmount">usb</action> + </object> + + <object type="action"> + <action function="page">mount</action> + </object> + </page> + + <page name="system_readonly_check"> + <object type="action"> + <action function="checkpartitionlifetimewrites">/system</action> + </object> + + <object type="action"> + <condition var1="tw_lifetime_writes" var2="1" /> + <actions> + <action function="mountsystemtoggle">0</action> + <action function="page">mount</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_lifetime_writes" var2="0" /> + <actions> + <action function="set">tw_back=mount</action> + <action function="page">system_readonly</action> + </actions> + </object> + </page> + + <page name="reboot"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Reboot Menu</text> + </object> + + <object type="button" style="rebootsystem"> + <placement x="%col1_x%" y="%row1_y%" /> + <text>System</text> + </object> + + <object type="button"> + <condition var1="tw_reboot_poweroff" var2="1" /> + <placement x="%col2_x%" y="%row1_y%" /> + <text>Power Off</text> + <actions> + <action function="set">tw_back=reboot</action> + <action function="set">tw_action=reboot</action> + <action function="set">tw_action_param=poweroff</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=No OS Installed! Are you</action> + <action function="set">tw_text2=sure you wish to power off?</action> + <action function="set">tw_action_text1=Turning Off...</action> + <action function="set">tw_complete_text1=Turning Off...</action> + <action function="set">tw_slider_text=Swipe to Power Off</action> + <action function="page">rebootcheck</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_reboot_recovery" var2="1" /> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Recovery</text> + <actions> + <action function="set">tw_back=reboot</action> + <action function="set">tw_action=reboot</action> + <action function="set">tw_action_param=recovery</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=No OS Installed! Are you</action> + <action function="set">tw_text2=sure you wish to reboot?</action> + <action function="set">tw_action_text1=Rebooting...</action> + <action function="set">tw_complete_text1=Rebooting...</action> + <action function="set">tw_slider_text=Swipe to Reboot</action> + <action function="page">rebootcheck</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_reboot_bootloader" var2="1" /> + <placement x="%col2_x%" y="%row2_y%" /> + <text>Bootloader</text> + <actions> + <action function="set">tw_back=reboot</action> + <action function="set">tw_action=reboot</action> + <action function="set">tw_action_param=bootloader</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=No OS Installed! Are you</action> + <action function="set">tw_text2=sure you wish to reboot?</action> + <action function="set">tw_action_text1=Rebooting...</action> + <action function="set">tw_complete_text1=Rebooting...</action> + <action function="set">tw_slider_text=Swipe to Reboot</action> + <action function="page">rebootcheck</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_download_mode" var2="1" /> + <placement x="%col1_x%" y="%row3_y%" /> + <text>Download</text> + <actions> + <action function="set">tw_back=reboot</action> + <action function="set">tw_action=reboot</action> + <action function="set">tw_action_param=download</action> + <action function="set">tw_has_action2=0</action> + <action function="set">tw_text1=No OS Installed! Are you</action> + <action function="set">tw_text2=sure you wish to reboot?</action> + <action function="set">tw_action_text1=Rebooting...</action> + <action function="set">tw_complete_text1=Rebooting...</action> + <action function="set">tw_slider_text=Swipe to Reboot</action> + <action function="page">rebootcheck</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="settings"> + <object type="template" name="header" /> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row1_header_y%" /> + <text>Zip file signature verification.</text> + <data variable="tw_signed_zip_verify" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row1_text_y%" /> + <text>Use rm -rf instead of formatting.</text> + <data variable="tw_rm_rf" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row2_text_y%" /> + <text>Skip MD5 generation during backup.</text> + <data variable="tw_skip_md5_generate" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row3_text_y%" /> + <text>Enable MD5 verification of backup files.</text> + <data variable="tw_skip_md5_check" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row4_text_y%" /> + <text>Use 24-hour clock.</text> + <data variable="tw_military_time" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row5_text_y%" /> + <text>Simulate actions for theme testing.</text> + <data variable="tw_simulate_actions" /> + </object> + + <object type="checkbox"> + <condition var1="tw_simulate_actions" var2="1" /> + <placement x="%col1_x%" y="%row6_text_y%" /> + <text>Simulate failure for actions.</text> + <data variable="tw_simulate_fail" /> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row3_y%" /> + <text>Time Zone</text> + <action function="page">timezone</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row3_y%" /> + <text>Screen</text> + <action function="page">screen</action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row4_y%" /> + <text>Restore Defaults</text> + <action function="restoredefaultsettings"></action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row4_y%" /> + <text>Vibration</text> + <action function="page">vibrate</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="timezone"> + <object type="template" name="header" /> + + <object type="listbox" style="scrolllist"> + <placement x="%listbox_x%" y="%row1_header_y%" w="%listbox_width%" h="%listbox_tz_height%" /> + <text>Select Time Zone:</text> + <icon selected="radio_true" unselected="radio_false" /> + <data name="tw_time_zone_guisel" /> + <listitem name="(UTC -11) Samoa, Midway Island">BST11;BDT</listitem> + <listitem name="(UTC -10) Hawaii">HST10;HDT</listitem> + <listitem name="(UTC -9) Alaska">AST9;ADT</listitem> + <listitem name="(UTC -8) Pacific Time">PST8;PDT,M3.2.0,M11.1.0</listitem> + <listitem name="(UTC -7) Mountain Time">MST7;MDT,M3.2.0,M11.1.0</listitem> + <listitem name="(UTC -6) Central Time">CST6;CDT,M3.2.0,M11.1.0</listitem> + <listitem name="(UTC -5) Eastern Time">EST5;EDT,M3.2.0,M11.1.0</listitem> + <listitem name="(UTC -4) Atlantic Time">AST4;ADT</listitem> + <listitem name="(UTC -3) Brazil, Buenos Aires">GRNLNDST3;GRNLNDDT</listitem> + <listitem name="(UTC -2) Mid-Atlantic">FALKST2;FALKDT</listitem> + <listitem name="(UTC -1) Azores, Cape Verde">AZOREST1;AZOREDT</listitem> + <listitem name="(UTC 0) London, Dublin, Lisbon">GMT0;BST,M3.5.0,M10.5.0</listitem> + <listitem name="(UTC +1) Berlin, Brussels, Paris">CET-1;CEST,M3.5.0,M10.5.0</listitem> + <listitem name="(UTC +2) Athens, Istanbul, South Africa">WET-2;WET,M3.5.0,M10.5.0</listitem> + <listitem name="(UTC +3) Moscow, Baghdad">SAUST-3;SAUDT</listitem> + <listitem name="(UTC +4) Abu Dhabi, Tbilisi, Muscat">WST-4;WDT</listitem> + <listitem name="(UTC +5) Yekaterinburg, Islamabad">PAKST-5;PAKDT</listitem> + <listitem name="(UTC +6) Almaty, Dhaka, Colombo">TASHST-6;TASHDT</listitem> + <listitem name="(UTC +7) Bangkok, Hanoi, Jakarta">THAIST-7;THAIDT</listitem> + <listitem name="(UTC +8) Beijing, Singapore, Hong Kong">TAIST-8;TAIDT</listitem> + <listitem name="(UTC +9) Tokyo, Seoul, Yakutsk">JST-9;JSTDT</listitem> + <listitem name="(UTC +10) Eastern Australia, Guam">EET-10;EETDT</listitem> + <listitem name="(UTC +11) Vladivostok, Solomon Islands">MET-11;METDT</listitem> + <listitem name="(UTC +12) Auckland, Wellington, Fiji">NZST-12;NZDT</listitem> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row_dst_text_y%" /> + <text>Do you use daylight savings time (DST)?</text> + <data variable="tw_time_zone_guidst" /> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row_offset_text_y%" placement="5" /> + <text>Offset (usually 0): %tw_time_zone_guioffset%</text> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%col1_medium_x%" y="%row_offset_medium_y%" /> + <text>None</text> + <action function="set">tw_time_zone_guioffset=0</action> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%col2_medium_x%" y="%row_offset_medium_y%" /> + <text>15</text> + <action function="set">tw_time_zone_guioffset=15</action> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%col3_medium_x%" y="%row_offset_medium_y%" /> + <text>30</text> + <action function="set">tw_time_zone_guioffset=30</action> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%col4_medium_x%" y="%row_offset_medium_y%" /> + <text>45</text> + <action function="set">tw_time_zone_guioffset=45</action> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%tz_set_y%" /> + <text>Set Time Zone</text> + <action function="setguitimezone"></action> + </object> + + <object type="text"> + <placement x="%center_x%" y="%tz_current_y%" placement="5" /> + <text>Current Time Zone: %tw_time_zone%</text> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">settings</action> + </object> + </page> + + <page name="screen"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Screen Settings</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row2_text_y%" /> + <font resource="font" color="%text_color%" /> + <condition var1="tw_screen_timeout_secs" op="=" var2="0" /> + <condition var1="tw_no_screen_timeout" op="!=" var2="1" /> + <text>Enable screen timeout.</text> + <image resource="checkbox_false" /> + <action function="set">tw_screen_timeout_secs=60</action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row2_text_y%" /> + <font resource="font" color="%text_color%" /> + <condition var1="tw_screen_timeout_secs" op="!=" var2="0" /> + <condition var1="tw_no_screen_timeout" op="!=" var2="1" /> + <text>Enable screen timeout.</text> + <image resource="checkbox_true" /> + <action function="set">tw_screen_timeout_secs=0</action> + </object> + + <object type="slidervalue"> + <conditions> + <condition var1="tw_screen_timeout_secs" op="!=" var2="0" /> + <condition var1="tw_no_screen_timeout" op="!=" var2="1" /> + </conditions> + <placement x="col1_x" y="%row4_text_y%" w="%slidervalue_w%" /> + <text>Screen timeout in seconds:</text> + <data variable="tw_screen_timeout_secs" min="15" max="300" /> + </object> + + <object type="slidervalue"> + <condition var1="tw_has_brightnesss_file" var2="1" /> + <placement x="col1_x" y="%row8_text_y%" w="%slidervalue_w%" /> + <text>Brightness: %tw_brightness_pct%%</text> + <data variable="tw_brightness_pct" min="10" max="100" /> + <actions> + <action function="set">tw_brightness=%tw_brightness_max%</action> + <action function="compute">tw_brightness*%tw_brightness_pct%</action> + <action function="compute">tw_brightness/100</action> + <action function="setbrightness">%tw_brightness%</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">settings</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="vibrate"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Vibration Settings :</text> + </object> + + <object type="slidervalue"> + <placement x="col1_x" y="%row1_text_y%" w="%slidervalue_w%" /> + <text>Button Vibration:</text> + <data variable="tw_button_vibrate" min="0" max="300" /> + </object> + + <object type="slidervalue"> + <placement x="col1_x" y="%row5_text_y%" w="%slidervalue_w%" /> + <text>Keyboard Vibration:</text> + <data variable="tw_keyboard_vibrate" min="0" max="300" /> + </object> + + <object type="slidervalue"> + <placement x="col1_x" y="%row9_text_y%" w="%slidervalue_w%" /> + <text>Action Vibration:</text> + <data variable="tw_action_vibrate" min="0" max="500" /> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">settings</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="advanced"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Advanced</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row1_y%" /> + <text>Copy Log to SD</text> + <actions> + <action function="set">tw_back=advanced</action> + <action function="set">tw_action=copylog</action> + <action function="set">tw_text1=Copy Log to SD Card?</action> + <action function="set">tw_action_text1=Copying Log to SD Card...</action> + <action function="set">tw_complete_text1=Log Copy Complete</action> + <action function="set">tw_slider_text=Swipe to Confirm</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row1_y%" /> + <text>Fix Permissions</text> + <action function="page">fixperms</action> + </object> + + <object type="button"> + <condition var1="tw_allow_partition_sdcard" var2="1" /> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Partition SD Card</text> + <action function="page">partsdcard</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row2_y%" /> + <text>File Manager</text> + <action function="page">filemanagerlist</action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row3_y%" /> + <text>Terminal Command</text> + <action function="page">terminalfolder</action> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row3_y%" /> + <text>Reload Theme</text> + <action function="reload"></action> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row4_y%" /> + <text>ADB Sideload</text> + <action function="page">sideload</action> + </object> + + <object type="button"> + <condition var1="tw_show_dumlock" var2="1" /> + <placement x="%col2_x%" y="%row4_y%" /> + <text>HTC Dumlock</text> + <action function="page">htcdumlock</action> + </object> + + <object type="button"> + <condition var1="tw_has_injecttwrp" var2="1" /> + <placement x="%col2_x%" y="%row4_y%" /> + <text>Re-Inject TWRP</text> + <actions> + <action function="set">tw_back=advanced</action> + <action function="set">tw_action=reinjecttwrp</action> + <action function="set">tw_text1=Re-Inject TWRP?</action> + <action function="set">tw_action_text1=Re-Injecting TWRP...</action> + <action function="set">tw_complete_text1=TWRP Injection Complete</action> + <action function="set">tw_slider_text=Swipe to Confirm</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">main</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="partsdcard"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Partition SD Card</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row1_y%" /> + <text></text> + <image resource="minus_button" /> + <action function="addsubtract">tw_sdext_size-128</action> + </object> + + <object type="button"> + <placement x="%sd_plus_x%" y="%row1_y%" /> + <text></text> + <image resource="plus_button" /> + <action function="addsubtract">tw_sdext_size+128</action> + </object> + + <object type="text"> + <placement x="%sdext_text_x%" y="%sdext_text_y%" /> + <text>EXT Size: %tw_sdext_size%</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%sdswap_button_y%" /> + <text></text> + <image resource="minus_button" /> + <action function="addsubtract">tw_swap_size-32</action> + </object> + + <object type="button"> + <placement x="%sd_plus_x%" y="%sdswap_button_y%" /> + <text></text> + <image resource="plus_button" /> + <action function="addsubtract">tw_swap_size+32</action> + </object> + + <object type="text"> + <placement x="%sdswap_text_x%" y="%sdswap_text_y%" /> + <text>Swap Size: %tw_swap_size%</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%sdfilesystem_text_y%" /> + <text>File system: %tw_sdpart_file_system%</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%sdfilesystem_button_y%" /> + <font resource="font" color="%button_text_color%" /> + <text>EXT3</text> + <action function="set">tw_sdpart_file_system=ext3</action> + </object> + + <object type="button"> + <condition var1="tw_sdext_disable_ext4" var2="0" /> + <placement x="%col2_x%" y="%sdfilesystem_button_y%" /> + <text>EXT4</text> + <image resource="main_button" /> + <action function="set">tw_sdpart_file_system=ext4</action> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row10_text_y%" /> + <text>You will lose all files on your SD card!</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row11_text_y%" /> + <text>This action cannot be undone!</text> + </object> + + <object type="slider"> + <text>Swipe to Partition</text> + <actions> + <action function="set">tw_back=partsdcard</action> + <action function="set">tw_action=partitionsd</action> + <action function="set">tw_has_action2=1</action> + <action function="set">tw_action2=set</action> + <action function="set">tw_action2_param=tw_zip_location=/sdcard</action> + <action function="set">tw_action_text1=Partitioning SD Card...</action> + <action function="set">tw_action_text2=This will take a few minutes.</action> + <action function="set">tw_complete_text1=Partitioning Complete</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + </page> + + <page name="htcdumlock"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>HTC Dumlock</text> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row1_y%" /> + <text>Restore Original Boot</text> + <actions> + <action function="set">tw_back=htcdumlock</action> + <action function="set">tw_action=htcdumlockrestoreboot</action> + <action function="set">tw_text1=Restore original boot image?</action> + <action function="set">tw_action_text1=Restoring Original Boot...</action> + <action function="set">tw_complete_text1=Restore Original Boot Complete</action> + <action function="set">tw_slider_text=Swipe to Confirm</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row1_y%" /> + <text>Reflash Recovery</text> + <actions> + <action function="set">tw_back=htcdumlock</action> + <action function="set">tw_action=htcdumlockreflashrecovery</action> + <action function="set">tw_text1=Reflash recovery to boot?</action> + <action function="set">tw_action_text1=Flashing recovery to boot...</action> + <action function="set">tw_complete_text1=Recovery Flash to Boot Complete</action> + <action function="set">tw_slider_text=Swipe to Confirm</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Install HTC Dumlock</text> + <actions> + <action function="set">tw_back=htcdumlock</action> + <action function="set">tw_action=installhtcdumlock</action> + <action function="set">tw_text1=Install HTC dumlock files to ROM?</action> + <action function="set">tw_action_text1=Installing HTC Dumlock...</action> + <action function="set">tw_complete_text1=HTC Dumlock Install Complete</action> + <action function="set">tw_slider_text=Swipe to Confirm</action> + <action function="page">confirm_action</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="lock"> + <background color="#000000A0" /> + + <object type="image"> + <image resource="unlock-icon" /> + <placement x="%center_x%" y="%lock_y%" placement="4" /> + </object> + + <object type="slider"> + <text>Swipe to Unlock</text> + <action function="overlay"></action> + </object> + </page> + + <page name="filemanagerlist"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>File Manager: Select a File or Folder</text> + </object> + + <object type="fileselector"> + <placement x="%fileselector_x%" y="%row1_y%" w="%fileselector_width%" h="%fileselector_install_height%" /> + <text>%tw_file_location1%</text> + <filter folders="1" files="1" /> + <path name="tw_file_location1" default="/" /> + <data name="tw_filename1" /> + <selection name="tw_selection1" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="action"> + <actions> + <action function="set">tw_fm_type=File</action> + <action function="set">tw_fm_isfolder=0</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + + <object type="action"> + <condition var1="tw_filename1" op="modified" /> + <actions> + <action function="page">filemanageroptions</action> + </actions> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%filemanager_select_x%" y="%filemanager_select_y%" /> + <text>Select</text> + <actions> + <action function="set">tw_filename1=tw_file_location1</action> + <action function="set">tw_fm_isfolder=1</action> + <action function="set">tw_fm_type=Folder</action> + <action function="page">filemanageroptions</action> + </actions> + </object> + </page> + + <page name="filemanageroptions"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5"/> + <text>%tw_fm_type% Selected:</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5"/> + <text>%tw_filename1%</text> + </object> + + <object type="button"> + <condition var1="tw_fm_isfolder" var2="0" /> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Copy File</text> + <actions> + <action function="set">tw_filemanager_command=cp</action> + <action function="set">tw_fm_text1=Copying</action> + <action function="page">choosedestinationfolder</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_fm_isfolder" var2="1" /> + <placement x="%col1_x%" y="%row2_y%" /> + <text>Copy Folder</text> + <actions> + <action function="set">tw_filemanager_command=cd "%tw_file_location1%" && cd .. && cp -R</action> + <action function="set">tw_fm_text1=Copying</action> + <action function="page">choosedestinationfolder</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row2_y%" /> + <text>Move</text> + <actions> + <action function="set">tw_filemanager_command=mv</action> + <action function="set">tw_fm_text1=Moving</action> + <action function="page">choosedestinationfolder</action> + </actions> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row3_y%" /> + <text>chmod 755</text> + <actions> + <action function="set">tw_filemanager_command=chmod 755</action> + <action function="set">tw_fm_text1=chmod 755</action> + <action function="set">tw_fm_text2=</action> + <action function="set">tw_fm_text3=</action> + <action function="set">tw_include_text3=0</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + + <object type="button"> + <placement x="%col2_x%" y="%row3_y%" /> + <text>chmod</text> + <actions> + <action function="set">tw_filemanager_rename=0000</action> + <action function="set">tw_fm_text2=</action> + <action function="set">tw_fm_text3=</action> + <action function="set">tw_include_text3=0</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerchmod</action> + </actions> + </object> + + <object type="button"> + <placement x="%col1_x%" y="%row4_y%" /> + <text>Delete</text> + <actions> + <action function="set">tw_filemanager_command=rm -rf</action> + <action function="set">tw_fm_text1=Deleting</action> + <action function="set">tw_fm_text2=</action> + <action function="set">tw_fm_text3=</action> + <action function="set">tw_include_text3=0</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_fm_isfolder" var2="0" /> + <placement x="%col2_x%" y="%row4_y%" /> + <text>Rename File</text> + <actions> + <action function="set">tw_filemanager_rename=tw_selection1</action> + <action function="set">tw_fm_text1=Renaming</action> + <action function="set">tw_filemanager_command=mv</action> + <action function="page">filemanagerrenamefile</action> + </actions> + </object> + + <object type="button"> + <condition var1="tw_fm_isfolder" var2="1" /> + <placement x="%col2_x%" y="%row4_y%" /> + <text>Rename Folder</text> + <actions> + <action function="set">tw_filemanager_rename=tw_selection1</action> + <action function="set">tw_fm_text1=Renaming</action> + <action function="set">tw_filemanager_command=cd "%tw_file_location1%" && cd .. && mv</action> + <action function="page">filemanagerrenamefolder</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">filemanagerlist</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="choosedestinationfolder"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5"/> + <text>Browse to Destination & Press Select</text> + </object> + + <object type="fileselector"> + <placement x="%fileselector_x%" y="%row1_y%" w="%fileselector_width%" h="%fileselector_install_height%" /> + <text>%tw_file_location2%</text> + <filter folders="1" files="0" /> + <path name="tw_file_location2" default="/" /> + <data name="tw_filename2" /> + <selection name="tw_selection2" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">filemanageroptions</action> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%filemanager_select_x%" y="%filemanager_select_y%" /> + <text>Select</text> + <actions> + <action function="set">tw_fm_text2=to</action> + <action function="set">tw_fm_text3=%tw_file_location2%</action> + <action function="set">tw_include_text3=1</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + </page> + + <page name="filemanagerrenamefile"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Please Enter a New %tw_fm_type% Name</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_filemanager_rename%</text> + <data name="tw_filemanager_rename" /> + <restrict minlen="1" maxlen="128" /> + <actions> + <action function="set">tw_fm_text2=to</action> + <action function="set">tw_fm_text3="%tw_file_location1%/%tw_filemanager_rename%"</action> + <action function="set">tw_include_text3=1</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row2_y%" /> + <text>Cancel</text> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="filemanagerrenamefolder"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Please Enter a New %tw_fm_type% Name</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_filemanager_rename%</text> + <data name="tw_filemanager_rename" /> + <restrict minlen="1" maxlen="128" /> + <actions> + <action function="set">tw_fm_text2=to</action> + <action function="set">tw_fm_text3=%tw_filemanager_rename%</action> + <action function="set">tw_include_text3=1</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row2_y%" /> + <text>Cancel</text> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="filemanagerchmod"> + <object type="template" name="header" /> + + <object type="text" color="%text_color%"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <font resource="font" /> + <text>Please Enter New Permissions</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_filemanager_rename%</text> + <data name="tw_filemanager_rename" /> + <restrict minlen="3" maxlen="4" allow="0123456789" /> + <actions> + <action function="set">tw_filemanager_command=chmod %tw_filemanager_rename%</action> + <action function="set">tw_fm_text1=chmod %tw_filemanager_rename%</action> + <action function="set">tw_back=filemanageroptions</action> + <action function="page">filemanagerconfirm</action> + </actions> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row2_y%" /> + <text>Cancel</text> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">filemanageroptions</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="filemanagerconfirm"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5"/> + <text>%tw_fm_text1%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5"/> + <text>%tw_filename1%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5"/> + <text>%tw_fm_text2%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row4_text_y%" placement="5"/> + <text>%tw_fm_text3%</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row10_text_y%" placement="5"/> + <text>Press back button to cancel.</text> + </object> + + <object type="slider"> + <action function="page">filemanageracction</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">%tw_back%</action> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + </page> + + <page name="filemanageracction"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>%tw_fm_text1%</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" var2="0" /> + </conditions> + <actions> + <action function="set">tw_back=filemanagerlist</action> + <action function="set">tw_complete_text1=File Operation Complete</action> + <action function="page">action_complete</action> + </actions> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" op="!=" var2="0" /> + </conditions> + <actions> + <action function="set">tw_complete_text1=File Operation Complete</action> + <action function="page">action_complete</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_include_text3" var2="0" /> + <actions> + <action function="cmd">%tw_filemanager_command% "%tw_filename1%"</action> + </actions> + </object> + + <object type="action"> + <condition var1="tw_include_text3" var2="1" /> + <actions> + <action function="cmd">%tw_filemanager_command% "%tw_filename1%" "%tw_fm_text3%"</action> + </actions> + </object> + </page> + + <page name="decrypt"> + <object type="template" name="header" /> + + <object type="action"> + <condition var1="tw_crypto_pwtype" var2="2" /> + <action function="page">decrypt_pattern</action> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Please Enter Your Password</text> + </object> + + <object type="input"> + <placement x="%col1_x%" y="%row3_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_crypto_display%</text> + <data name="tw_crypto_password" mask="*" maskvariable="tw_crypto_display" /> + <restrict minlen="1" maxlen="254" /> + <actions> + <action function="page">trydecrypt</action> + </actions> + </object> + + <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" /> + <text>Password Failed, Please Try Again</text> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row2_y%" /> + <text>Cancel</text> + <actions> + <action function="set">tw_page_done=1</action> + <action function="page">main</action> + </actions> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="template" name="footer" /> + </page> + + <page name="decrypt_pattern"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Please Enter Your Pattern</text> + </object> + + <object type="text"> + <condition var1="tw_password_fail" var2="1" /> + <font resource="font" color="%text_fail_color%"/> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Pattern Failed, Please Try Again</text> + </object> + + <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%" /> + <line color="%pattern_line_color%" width="%pattern_line_width%" /> + <data name="tw_crypto_password"/> + <action function="page">trydecrypt</action> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row4_y%" /> + <text>Cancel</text> + <actions> + <action function="set">tw_page_done=1</action> + <action function="page">main</action> + </actions> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="trydecrypt"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>Trying Decryption with Your Password</text> + </object> + + <object type="template" name="action_page_console" /> + + <object type="template" name="progress_bar" /> + + <object type="action"> + <action function="decrypt"></action> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" op="!=" var2="0" /> + </conditions> + <actions> + <action function="set">tw_password_fail=1</action> + <action function="page">decrypt</action> + </actions> + </object> + + <object type="action"> + <conditions> + <condition var1="tw_operation_state" var2="1" /> + <condition var1="tw_operation_status" op="=" var2="0" /> + </conditions> + <actions> + <action function="set">tw_page_done=1</action> + <action function="page">main</action> + </actions> + </object> + </page> + + <page name="terminalfolder"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5"/> + <text>Browse to Starting Folder</text> + </object> + + <object type="fileselector"> + <placement x="%fileselector_x%" y="%row1_y%" w="%fileselector_width%" h="%fileselector_install_height%" /> + <text>%tw_terminal_location%</text> + <filter folders="1" files="0" /> + <path name="tw_terminal_location" default="/" /> + <data name="tw_terminal" /> + <selection name="tw_terminal_selection" /> + </object> + + <object type="template" name="sort_options" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + + <object type="button" style="mediumbutton"> + <placement x="%filemanager_select_x%" y="%filemanager_select_y%" /> + <text>Select</text> + <actions> + <action function="page">terminalcommand</action> + </actions> + </object> + </page> + + <page name="terminalcommand"> + <object type="template" name="header" /> + + <object type="console"> + <placement x="%console_x%" y="0" w="%console_width%" h="%terminal_console_height%" /> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%terminal_text_y%" placement="0" /> + <text>Starting Path: %tw_terminal_location%</text> + </object> + + <object type="input"> + <condition var1="tw_terminal_state" var2="0" /> + <placement x="%col1_x%" y="%terminal_text_y%" w="%input_width%" h="%input_height%" placement="0" /> + <text>%tw_terminal_command%</text> + <font resource="fixed" color="%text_color%" /> + <data name="tw_terminal_command" /> + <restrict minlen="1" /> + <action function="terminalcommand">%tw_terminal_command%</action> + </object> + + <object type="button" style="mediumbutton"> + <condition var1="tw_terminal_state" var2="1" /> + <placement x="%filemanager_select_x%" y="%terminal_button_y%" /> + <text>KILL</text> + <action function="killterminal"></action> + </object> + + <object type="template" name="keyboardtemplate" /> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">terminalfolder</action> + </object> + </page> + + <page name="sideload"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5"/> + <text>ADB Sideload</text> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row2_text_y%" /> + <text>Wipe Dalvik Cache.</text> + <data variable="tw_wipe_dalvik" /> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row3_text_y%" /> + <text>Wipe Cache.</text> + <data variable="tw_wipe_cache" /> + </object> + + <object type="slider"> + <text>Swipe to Start Sideload</text> + <actions> + <action function="set">tw_back=advanced</action> + <action function="set">tw_action=adbsideload</action> + <action function="set">tw_action_text1=ADB Sideload</action> + <action function="set">tw_action_text2=Usage: adb sideload filename.zip</action> + <action function="set">tw_complete_text1=ADB Sideload Complete</action> + <action function="set">tw_has_cancel=1</action> + <action function="set">tw_show_reboot=1</action> + <action function="set">tw_cancel_action=adbsideloadcancel</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + </page> + + <page name="fixperms"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5"/> + <text>Fix Permissions</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row2_text_y%" /> + <text>Note: Fixing permissions is rarely needed.</text> + </object> + + <object type="checkbox"> + <placement x="%col1_x%" y="%row3_text_y%" /> + <text>Also fix SELinux contexts</text> + <data variable="tw_fixperms_restorecon" /> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row4_text_y%" /> + <text>Fixing SELinux contexts may cause</text> + </object> + + <object type="text"> + <placement x="%col1_x%" y="%row5_text_y%" /> + <text>your device to not boot properly.</text> + </object> + + <object type="slider"> + <text>Swipe to Fix Permissions</text> + <actions> + <action function="set">tw_back=advanced</action> + <action function="set">tw_action=fixpermissions</action> + <action function="set">tw_action_text1=Fixing Permissions...</action> + <action function="set">tw_complete_text1=Fix Permissions Complete</action> + <action function="set">tw_slider_text=Swipe to Confirm</action> + <action function="set">tw_show_reboot=1</action> + <action function="page">action_page</action> + </actions> + </object> + + <object type="action"> + <touch key="home" /> + <action function="page">main</action> + </object> + + <object type="action"> + <touch key="back" /> + <action function="page">advanced</action> + </object> + + <object type="template" name="footer" /> + </page> + + <page name="installsu"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5"/> + <text>Install SuperSU?</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5"/> + <text>Your device does not appear to be rooted.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5"/> + <text>Install SuperSU now?</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row4_text_y%" placement="5"/> + <text>This will root your device.</text> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row3_y%" /> + <text>Do Not Install</text> + <action function="set">tw_page_done=1</action> + </object> + + <object type="slider"> + <text>Swipe to Install</text> + <actions> + <action function="set">tw_action=installsu</action> + <action function="set">tw_action_text1=Installing SuperSU</action> + <action function="set">tw_action_text2=</action> + <action function="page">singleaction_page</action> + </actions> + </object> + </page> + + <page name="system_readonly"> + <object type="template" name="header" /> + + <object type="text"> + <placement x="%center_x%" y="%row1_header_y%" placement="5" /> + <text>Keep System Read Only?</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row1_text_y%" placement="5" /> + <text>TWRP can leave your system partition unmodified</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row2_text_y%" placement="5" /> + <text>to make it easier for you to take official updates.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row3_text_y%" placement="5" /> + <text>TWRP will be unable to prevent the stock ROM from</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row4_text_y%" placement="5" /> + <text>replacing TWRP and will not offer to root your device.</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row5_text_y%" placement="5" /> + <text>Installing zips or performing adb operations may still</text> + </object> + + <object type="text"> + <placement x="%center_x%" y="%row6_text_y%" placement="5" /> + <text>modify the system partition.</text> + </object> + + <object type="checkbox"> + <condition var1="tw_is_encrypted" var2="0" /> + <placement x="%col1_x%" y="%row7_text_y%" /> + <text>Never show this screen during boot again</text> + <data variable="tw_never_show_system_ro_page" /> + </object> + + <object type="button"> + <placement x="%col_center_x%" y="%row9_text_y%" /> + <text>Keep Read Only</text> + <actions> + <action function="mountsystemtoggle">1</action> + <action function="set">tw_page_done=1</action> + <action function="page">%tw_back%</action> + </actions> + </object> + + <object type="slider"> + <text>Swipe to Allow Modifications</text> + <actions> + <action function="mountsystemtoggle">0</action> + <action function="set">tw_page_done=1</action> + <action function="page">%tw_back%</action> + </actions> + </object> + </page> + </pages> +</recovery> diff --git a/gui/fileselector.cpp b/gui/fileselector.cpp new file mode 100644 index 000000000..a97ff34b1 --- /dev/null +++ b/gui/fileselector.cpp @@ -0,0 +1,382 @@ +/* + Copyright 2012 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <string.h> +#include <sys/stat.h> +#include <dirent.h> +#include <algorithm> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" +#include "../data.hpp" +#include "../twrp-functions.hpp" + +#define TW_FILESELECTOR_UP_A_LEVEL "(Up A Level)" + +int GUIFileSelector::mSortOrder = 0; + +GUIFileSelector::GUIFileSelector(xml_node<>* node) : GUIScrollList(node) +{ + xml_attribute<>* attr; + xml_node<>* child; + + mFolderIcon = mFileIcon = NULL; + mShowFolders = mShowFiles = mShowNavFolders = 1; + mUpdate = 0; + mPathVar = "cwd"; + updateFileList = false; + + // Load filter for filtering files (e.g. *.zip for only zips) + child = FindNode(node, "filter"); + if (child) { + attr = child->first_attribute("extn"); + if (attr) + mExtn = attr->value(); + attr = child->first_attribute("folders"); + if (attr) + mShowFolders = atoi(attr->value()); + attr = child->first_attribute("files"); + if (attr) + mShowFiles = atoi(attr->value()); + attr = child->first_attribute("nav"); + if (attr) + mShowNavFolders = atoi(attr->value()); + } + + // Handle the path variable + child = FindNode(node, "path"); + if (child) { + attr = child->first_attribute("name"); + if (attr) + mPathVar = attr->value(); + attr = child->first_attribute("default"); + if (attr) { + mPathDefault = attr->value(); + DataManager::SetValue(mPathVar, attr->value()); + } + } + + // Handle the result variable + child = FindNode(node, "data"); + if (child) { + attr = child->first_attribute("name"); + if (attr) + mVariable = attr->value(); + attr = child->first_attribute("default"); + if (attr) + DataManager::SetValue(mVariable, attr->value()); + } + + // Handle the sort variable + child = FindNode(node, "sort"); + if (child) { + attr = child->first_attribute("name"); + if (attr) + mSortVariable = attr->value(); + attr = child->first_attribute("default"); + if (attr) + DataManager::SetValue(mSortVariable, attr->value()); + + DataManager::GetValue(mSortVariable, mSortOrder); + } + + // Handle the selection variable + child = FindNode(node, "selection"); + if (child && (attr = child->first_attribute("name"))) + mSelection = attr->value(); + else + mSelection = "0"; + + // Get folder and file icons if present + child = FindNode(node, "icon"); + if (child) { + mFolderIcon = LoadAttrImage(child, "folder"); + mFileIcon = LoadAttrImage(child, "file"); + } + int iconWidth = std::max(mFolderIcon->GetWidth(), mFileIcon->GetWidth()); + int iconHeight = std::max(mFolderIcon->GetHeight(), mFileIcon->GetHeight()); + SetMaxIconSize(iconWidth, iconHeight); + + // Fetch the file/folder list + std::string value; + DataManager::GetValue(mPathVar, value); + GetFileList(value); +} + +GUIFileSelector::~GUIFileSelector() +{ +} + +int GUIFileSelector::Update(void) +{ + if(!isConditionTrue()) + return 0; + + GUIScrollList::Update(); + + // Update the file list if needed + if (updateFileList) { + string value; + DataManager::GetValue(mPathVar, value); + if (GetFileList(value) == 0) { + updateFileList = false; + mUpdate = 1; + } else + return 0; + } + + if (mUpdate) { + mUpdate = 0; + if (Render() == 0) + return 2; + } + return 0; +} + +int GUIFileSelector::NotifyVarChange(const std::string& varName, const std::string& value) +{ + GUIScrollList::NotifyVarChange(varName, value); + + if(!isConditionTrue()) + return 0; + + if (varName.empty()) { + // Always clear the data variable so we know to use it + DataManager::SetValue(mVariable, ""); + } + if (varName == mPathVar || varName == mSortVariable) { + if (varName == mSortVariable) { + DataManager::GetValue(mSortVariable, mSortOrder); + } else { + // Reset the list to the top + SetVisibleListLocation(0); + if (value.empty()) + DataManager::SetValue(mPathVar, mPathDefault); + } + updateFileList = true; + mUpdate = 1; + return 0; + } + return 0; +} + +bool GUIFileSelector::fileSort(FileData d1, FileData d2) +{ + if (d1.fileName == ".") + return -1; + if (d2.fileName == ".") + return 0; + if (d1.fileName == TW_FILESELECTOR_UP_A_LEVEL) + return -1; + if (d2.fileName == TW_FILESELECTOR_UP_A_LEVEL) + return 0; + + switch (mSortOrder) { + case 3: // by size largest first + if (d1.fileSize == d2.fileSize || d1.fileType == DT_DIR) // some directories report a different size than others - but this is not the size of the files inside the directory, so we just sort by name on directories + return (strcasecmp(d1.fileName.c_str(), d2.fileName.c_str()) < 0); + return d1.fileSize < d2.fileSize; + case -3: // by size smallest first + if (d1.fileSize == d2.fileSize || d1.fileType == DT_DIR) // some directories report a different size than others - but this is not the size of the files inside the directory, so we just sort by name on directories + return (strcasecmp(d1.fileName.c_str(), d2.fileName.c_str()) > 0); + return d1.fileSize > d2.fileSize; + case 2: // by last modified date newest first + if (d1.lastModified == d2.lastModified) + return (strcasecmp(d1.fileName.c_str(), d2.fileName.c_str()) < 0); + return d1.lastModified < d2.lastModified; + case -2: // by date oldest first + if (d1.lastModified == d2.lastModified) + return (strcasecmp(d1.fileName.c_str(), d2.fileName.c_str()) > 0); + return d1.lastModified > d2.lastModified; + case -1: // by name descending + return (strcasecmp(d1.fileName.c_str(), d2.fileName.c_str()) > 0); + default: // should be a 1 - sort by name ascending + return (strcasecmp(d1.fileName.c_str(), d2.fileName.c_str()) < 0); + } + return 0; +} + +int GUIFileSelector::GetFileList(const std::string folder) +{ + DIR* d; + struct dirent* de; + struct stat st; + + // Clear all data + mFolderList.clear(); + mFileList.clear(); + + d = opendir(folder.c_str()); + if (d == NULL) { + LOGINFO("Unable to open '%s'\n", folder.c_str()); + if (folder != "/" && (mShowNavFolders != 0 || mShowFiles != 0)) { + size_t found; + found = folder.find_last_of('/'); + if (found != string::npos) { + string new_folder = folder.substr(0, found); + + if (new_folder.length() < 2) + new_folder = "/"; + DataManager::SetValue(mPathVar, new_folder); + } + } + return -1; + } + + while ((de = readdir(d)) != NULL) { + FileData data; + + data.fileName = de->d_name; + if (data.fileName == ".") + continue; + if (data.fileName == ".." && folder == "/") + continue; + if (data.fileName == "..") { + data.fileName = TW_FILESELECTOR_UP_A_LEVEL; + data.fileType = DT_DIR; + } else { + data.fileType = de->d_type; + } + + std::string path = folder + "/" + data.fileName; + stat(path.c_str(), &st); + data.protection = st.st_mode; + data.userId = st.st_uid; + data.groupId = st.st_gid; + data.fileSize = st.st_size; + data.lastAccess = st.st_atime; + data.lastModified = st.st_mtime; + data.lastStatChange = st.st_ctime; + + if (data.fileType == DT_UNKNOWN) { + data.fileType = TWFunc::Get_D_Type_From_Stat(path); + } + if (data.fileType == DT_DIR) { + if (mShowNavFolders || (data.fileName != "." && data.fileName != TW_FILESELECTOR_UP_A_LEVEL)) + mFolderList.push_back(data); + } else if (data.fileType == DT_REG || data.fileType == DT_LNK || data.fileType == DT_BLK) { + if (mExtn.empty() || (data.fileName.length() > mExtn.length() && data.fileName.substr(data.fileName.length() - mExtn.length()) == mExtn)) { + mFileList.push_back(data); + } + } + } + closedir(d); + + std::sort(mFolderList.begin(), mFolderList.end(), fileSort); + std::sort(mFileList.begin(), mFileList.end(), fileSort); + + return 0; +} + +void GUIFileSelector::SetPageFocus(int inFocus) +{ + GUIScrollList::SetPageFocus(inFocus); + if (inFocus) { + std::string value; + DataManager::GetValue(mPathVar, value); + if (value.empty()) + DataManager::SetValue(mPathVar, mPathDefault); + updateFileList = true; + mUpdate = 1; + } +} + +size_t GUIFileSelector::GetItemCount() +{ + size_t folderSize = mShowFolders ? mFolderList.size() : 0; + size_t fileSize = mShowFiles ? mFileList.size() : 0; + return folderSize + fileSize; +} + +void GUIFileSelector::RenderItem(size_t itemindex, int yPos, bool selected) +{ + size_t folderSize = mShowFolders ? mFolderList.size() : 0; + size_t fileSize = mShowFiles ? mFileList.size() : 0; + + ImageResource* icon; + std::string text; + + if (itemindex < folderSize) { + text = mFolderList.at(itemindex).fileName; + icon = mFolderIcon; + } else { + text = mFileList.at(itemindex - folderSize).fileName; + icon = mFileIcon; + } + + RenderStdItem(yPos, selected, icon, text.c_str()); +} + +void GUIFileSelector::NotifySelect(size_t item_selected) +{ + size_t folderSize = mShowFolders ? mFolderList.size() : 0; + size_t fileSize = mShowFiles ? mFileList.size() : 0; + + if (item_selected < folderSize + fileSize) { + // We've selected an item! + std::string str; + if (item_selected < folderSize) { + std::string cwd; + + str = mFolderList.at(item_selected).fileName; + if (mSelection != "0") + DataManager::SetValue(mSelection, str); + DataManager::GetValue(mPathVar, cwd); + + // Ignore requests to do nothing + if (str == ".") return; + if (str == TW_FILESELECTOR_UP_A_LEVEL) { + if (cwd != "/") { + size_t found; + found = cwd.find_last_of('/'); + cwd = cwd.substr(0,found); + + if (cwd.length() < 2) cwd = "/"; + } + } else { + // Add a slash if we're not the root folder + if (cwd != "/") cwd += "/"; + cwd += str; + } + + if (mShowNavFolders == 0 && mShowFiles == 0) { + // nav folders and files are disabled, this is probably the restore list and we need to save chosen location to mVariable instead of mPathVar + DataManager::SetValue(mVariable, cwd); + } else { + // We are changing paths, so we need to set mPathVar + DataManager::SetValue(mPathVar, cwd); + } + } else if (!mVariable.empty()) { + str = mFileList.at(item_selected - folderSize).fileName; + if (mSelection != "0") + DataManager::SetValue(mSelection, str); + + std::string cwd; + DataManager::GetValue(mPathVar, cwd); + if (cwd != "/") + cwd += "/"; + DataManager::SetValue(mVariable, cwd + str); + } + } + mUpdate = 1; +} diff --git a/gui/fill.cpp b/gui/fill.cpp new file mode 100644 index 000000000..b315cd08a --- /dev/null +++ b/gui/fill.cpp @@ -0,0 +1,52 @@ +// fill.cpp - GUIFill object + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" + +GUIFill::GUIFill(xml_node<>* node) : GUIObject(node) +{ + bool has_color = false; + mColor = LoadAttrColor(node, "color", &has_color); + if (!has_color) { + LOGERR("No color specified for fill\n"); + return; + } + + // Load the placement + LoadPlacement(FindNode(node, "placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH); + + return; +} + +int GUIFill::Render(void) +{ + if(!isConditionTrue()) + return 0; + + gr_color(mColor.red, mColor.green, mColor.blue, mColor.alpha); + gr_fill(mRenderX, mRenderY, mRenderW, mRenderH); + return 0; +} + diff --git a/gui/gui.cpp b/gui/gui.cpp new file mode 100644 index 000000000..ebd70534c --- /dev/null +++ b/gui/gui.cpp @@ -0,0 +1,1051 @@ +/* + Copyright 2012 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <linux/input.h> +#include <pthread.h> +#include <stdarg.h> +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/mount.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> + +extern "C" +{ +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +#include <pixelflinger/pixelflinger.h> +} + +#include "rapidxml.hpp" +#include "objects.hpp" +#include "../data.hpp" +#include "../variables.h" +#include "../partitions.hpp" +#include "../twrp-functions.hpp" +#include "../openrecoveryscript.hpp" +#include "../orscmd/orscmd.h" +#include "blanktimer.hpp" +#include "../tw_atomic.hpp" + +// Enable to print render time of each frame to the log file +//#define PRINT_RENDER_TIME 1 + +#ifdef _EVENT_LOGGING +#define LOGEVENT(...) LOGERR(__VA_ARGS__) +#else +#define LOGEVENT(...) do {} while (0) +#endif + +const static int CURTAIN_FADE = 32; + +using namespace rapidxml; + +// Global values +static gr_surface gCurtain = NULL; +static int gGuiInitialized = 0; +static TWAtomicInt gGuiConsoleRunning; +static TWAtomicInt gGuiConsoleTerminate; +static TWAtomicInt gForceRender; +const int gNoAnimation = 1; +blanktimer blankTimer; +int ors_read_fd = -1; +static float scale_theme_w = 1; +static float scale_theme_h = 1; + +// Needed by pages.cpp too +int gGuiRunning = 0; + +static int gRecorder = -1; + +extern "C" void gr_write_frame_to_file(int fd); + +void flip(void) +{ + if (gRecorder != -1) + { + timespec time; + clock_gettime(CLOCK_MONOTONIC, &time); + write(gRecorder, &time, sizeof(timespec)); + gr_write_frame_to_file(gRecorder); + } + gr_flip(); +} + +void rapidxml::parse_error_handler(const char *what, void *where) +{ + fprintf(stderr, "Parser error: %s\n", what); + fprintf(stderr, " Start of string: %s\n",(char *) where); + LOGERR("Error parsing XML file.\n"); + //abort(); +} + +static void curtainSet() +{ + gr_color(0, 0, 0, 255); + gr_fill(0, 0, gr_fb_width(), gr_fb_height()); + gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain), gr_get_height(gCurtain), TW_X_OFFSET, TW_Y_OFFSET); + gr_flip(); +} + +static void curtainRaise(gr_surface surface) +{ + int sy = 0; + int h = gr_get_height(gCurtain) - 1; + int w = gr_get_width(gCurtain); + int fy = 1; + + int msw = gr_get_width(surface); + int msh = gr_get_height(surface); + int CURTAIN_RATE = msh / 30; + + if (gNoAnimation == 0) + { + for (; h > 0; h -= CURTAIN_RATE, sy += CURTAIN_RATE, fy += CURTAIN_RATE) + { + gr_blit(surface, 0, 0, msw, msh, 0, 0); + gr_blit(gCurtain, 0, sy, w, h, 0, 0); + gr_flip(); + } + } + gr_blit(surface, 0, 0, msw, msh, 0, 0); + flip(); +} + +void curtainClose() +{ +#if 0 + int w = gr_get_width(gCurtain); + int h = 1; + int sy = gr_get_height(gCurtain) - 1; + int fbh = gr_fb_height(); + int CURTAIN_RATE = fbh / 30; + + if (gNoAnimation == 0) + { + for (; h < fbh; h += CURTAIN_RATE, sy -= CURTAIN_RATE) + { + gr_blit(gCurtain, 0, sy, w, h, 0, 0); + gr_flip(); + } + gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain), + gr_get_height(gCurtain), 0, 0); + gr_flip(); + + if (gRecorder != -1) + close(gRecorder); + + int fade; + for (fade = 16; fade < 255; fade += CURTAIN_FADE) + { + gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain), + gr_get_height(gCurtain), 0, 0); + gr_color(0, 0, 0, fade); + gr_fill(0, 0, gr_fb_width(), gr_fb_height()); + gr_flip(); + } + gr_color(0, 0, 0, 255); + gr_fill(0, 0, gr_fb_width(), gr_fb_height()); + gr_flip(); + } +#else + gr_blit(gCurtain, 0, 0, gr_get_width(gCurtain), gr_get_height(gCurtain), 0, 0); + gr_flip(); +#endif +} + +class InputHandler +{ +public: + void init() + { + // these might be read from DataManager in the future + touch_hold_ms = 500; + touch_repeat_ms = 100; + key_hold_ms = 500; + key_repeat_ms = 100; + touch_status = TS_NONE; + key_status = KS_NONE; + state = AS_NO_ACTION; + x = y = 0; + +#ifndef TW_NO_SCREEN_TIMEOUT + { + string seconds; + DataManager::GetValue("tw_screen_timeout_secs", seconds); + blankTimer.setTime(atoi(seconds.c_str())); + blankTimer.resetTimerAndUnblank(); + } +#else + LOGINFO("Skipping screen timeout: TW_NO_SCREEN_TIMEOUT is set\n"); +#endif + } + + // process input events. returns true if any event was received. + bool processInput(int timeout_ms); + + void handleDrag(); + +private: + // timeouts for touch/key hold and repeat + int touch_hold_ms; + int touch_repeat_ms; + int key_hold_ms; + int key_repeat_ms; + + enum touch_status_enum { + TS_NONE = 0, + TS_TOUCH_AND_HOLD = 1, + TS_TOUCH_REPEAT = 2, + }; + + enum key_status_enum { + KS_NONE = 0, + KS_KEY_PRESSED = 1, + KS_KEY_REPEAT = 2, + }; + + enum action_state_enum { + AS_IN_ACTION_AREA = 0, // we've touched a spot with an action + AS_NO_ACTION = 1, // we've touched in an empty area (no action) and ignore remaining events until touch release + }; + touch_status_enum touch_status; + key_status_enum key_status; + action_state_enum state; + int x, y; // x and y coordinates of last touch + struct timeval touchStart; // used to track time for long press / key repeat + + void processHoldAndRepeat(); + void process_EV_REL(input_event& ev); + void process_EV_ABS(input_event& ev); + void process_EV_KEY(input_event& ev); + + void doTouchStart(); +}; + +InputHandler input_handler; + + +bool InputHandler::processInput(int timeout_ms) +{ + input_event ev; + int ret = ev_get(&ev, timeout_ms); + + if (ret < 0) + { + // This path means that we did not get any new touch data, but + // we do not get new touch data if you press and hold on either + // the screen or on a keyboard key or mouse button + if (touch_status || key_status) + processHoldAndRepeat(); + return (ret != -2); // -2 means no more events in the queue + } + + switch (ev.type) + { + case EV_ABS: + process_EV_ABS(ev); + break; + + case EV_REL: + process_EV_REL(ev); + break; + + case EV_KEY: + process_EV_KEY(ev); + break; + } + + blankTimer.resetTimerAndUnblank(); + return true; // we got an event, so there might be more in the queue +} + +void InputHandler::processHoldAndRepeat() +{ + HardwareKeyboard *kb = PageManager::GetHardwareKeyboard(); + + // touch and key repeat section + struct timeval curTime; + gettimeofday(&curTime, NULL); + long seconds = curTime.tv_sec - touchStart.tv_sec; + long useconds = curTime.tv_usec - touchStart.tv_usec; + long mtime = ((seconds) * 1000 + useconds / 1000.0) + 0.5; + + if (touch_status == TS_TOUCH_AND_HOLD && mtime > touch_hold_ms) + { + touch_status = TS_TOUCH_REPEAT; + gettimeofday(&touchStart, NULL); + LOGEVENT("TOUCH_HOLD: %d,%d\n", x, y); + PageManager::NotifyTouch(TOUCH_HOLD, x, y); + } + else if (touch_status == TS_TOUCH_REPEAT && mtime > touch_repeat_ms) + { + LOGEVENT("TOUCH_REPEAT: %d,%d\n", x, y); + gettimeofday(&touchStart, NULL); + PageManager::NotifyTouch(TOUCH_REPEAT, x, y); + } + else if (key_status == KS_KEY_PRESSED && mtime > key_hold_ms) + { + LOGEVENT("KEY_HOLD: %d,%d\n", x, y); + gettimeofday(&touchStart, NULL); + key_status = KS_KEY_REPEAT; + kb->KeyRepeat(); + } + else if (key_status == KS_KEY_REPEAT && mtime > key_repeat_ms) + { + LOGEVENT("KEY_REPEAT: %d,%d\n", x, y); + gettimeofday(&touchStart, NULL); + kb->KeyRepeat(); + } +} + +void InputHandler::doTouchStart() +{ + LOGEVENT("TOUCH_START: %d,%d\n", x, y); + if (PageManager::NotifyTouch(TOUCH_START, x, y) > 0) + state = AS_NO_ACTION; + else + state = AS_IN_ACTION_AREA; + touch_status = TS_TOUCH_AND_HOLD; + gettimeofday(&touchStart, NULL); +} + +void InputHandler::process_EV_ABS(input_event& ev) +{ + x = ev.value >> 16; + y = ev.value & 0xFFFF; + + if (ev.code == 0) + { +#ifndef TW_USE_KEY_CODE_TOUCH_SYNC + if (state == AS_IN_ACTION_AREA) + { + LOGEVENT("TOUCH_RELEASE: %d,%d\n", x, y); + PageManager::NotifyTouch(TOUCH_RELEASE, x, y); + } + touch_status = TS_NONE; +#endif + } + else + { + if (!touch_status) + { +#ifndef TW_USE_KEY_CODE_TOUCH_SYNC + doTouchStart(); +#endif + } + else + { + if (state == AS_IN_ACTION_AREA) + { + LOGEVENT("TOUCH_DRAG: %d,%d\n", x, y); + } + } + } +} + +void InputHandler::process_EV_KEY(input_event& ev) +{ + HardwareKeyboard *kb = PageManager::GetHardwareKeyboard(); + + // Handle key-press here + LOGEVENT("TOUCH_KEY: %d\n", ev.code); + // Left mouse button is treated as a touch + if(ev.code == BTN_LEFT) + { + MouseCursor *cursor = PageManager::GetMouseCursor(); + if(ev.value == 1) + { + cursor->GetPos(x, y); + doTouchStart(); + } + else if(touch_status) + { + // Left mouse button was previously pressed and now is + // being released so send a TOUCH_RELEASE + if (state == AS_IN_ACTION_AREA) + { + cursor->GetPos(x, y); + + LOGEVENT("Mouse TOUCH_RELEASE: %d,%d\n", x, y); + PageManager::NotifyTouch(TOUCH_RELEASE, x, y); + } + touch_status = TS_NONE; + } + } + // side mouse button, often used for "back" function + else if(ev.code == BTN_SIDE) + { + if(ev.value == 1) + kb->KeyDown(KEY_BACK); + else + kb->KeyUp(KEY_BACK); + } else if (ev.value != 0) { + // This is a key press +#ifdef TW_USE_KEY_CODE_TOUCH_SYNC + if (ev.code == TW_USE_KEY_CODE_TOUCH_SYNC) { + LOGEVENT("key code %i key press == touch start %i %i\n", TW_USE_KEY_CODE_TOUCH_SYNC, x, y); + doTouchStart(); + return; + } +#endif + if (kb->KeyDown(ev.code)) { + // Key repeat is enabled for this key + key_status = KS_KEY_PRESSED; + touch_status = TS_NONE; + gettimeofday(&touchStart, NULL); + } else { + key_status = KS_NONE; + touch_status = TS_NONE; + } + } else { + // This is a key release + kb->KeyUp(ev.code); + key_status = KS_NONE; + touch_status = TS_NONE; +#ifdef TW_USE_KEY_CODE_TOUCH_SYNC + if (ev.code == TW_USE_KEY_CODE_TOUCH_SYNC) { + LOGEVENT("key code %i key release == touch release %i %i\n", TW_USE_KEY_CODE_TOUCH_SYNC, x, y); + PageManager::NotifyTouch(TOUCH_RELEASE, x, y); + } +#endif + } +} + +void InputHandler::process_EV_REL(input_event& ev) +{ + // Mouse movement + MouseCursor *cursor = PageManager::GetMouseCursor(); + LOGEVENT("EV_REL %d %d\n", ev.code, ev.value); + if(ev.code == REL_X) + cursor->Move(ev.value, 0); + else if(ev.code == REL_Y) + cursor->Move(0, ev.value); + + if(touch_status) { + cursor->GetPos(x, y); + LOGEVENT("Mouse TOUCH_DRAG: %d, %d\n", x, y); + key_status = KS_NONE; + } +} + +void InputHandler::handleDrag() +{ + // This allows us to only send one NotifyTouch event per render + // cycle to reduce overhead and perceived input latency. + static int prevx = 0, prevy = 0; // these track where the last drag notice was so that we don't send duplicate drag notices + if (touch_status && (x != prevx || y != prevy)) { + prevx = x; + prevy = y; + if (PageManager::NotifyTouch(TOUCH_DRAG, x, y) > 0) + state = AS_NO_ACTION; + else + state = AS_IN_ACTION_AREA; + } +} + +static void setup_ors_command() +{ + ors_read_fd = -1; + + unlink(ORS_INPUT_FILE); + if (mkfifo(ORS_INPUT_FILE, 06660) != 0) { + LOGINFO("Unable to mkfifo %s\n", ORS_INPUT_FILE); + return; + } + unlink(ORS_OUTPUT_FILE); + if (mkfifo(ORS_OUTPUT_FILE, 06666) != 0) { + LOGINFO("Unable to mkfifo %s\n", ORS_OUTPUT_FILE); + unlink(ORS_INPUT_FILE); + return; + } + + ors_read_fd = open(ORS_INPUT_FILE, O_RDONLY | O_NONBLOCK); + if (ors_read_fd < 0) { + LOGINFO("Unable to open %s\n", ORS_INPUT_FILE); + unlink(ORS_INPUT_FILE); + unlink(ORS_OUTPUT_FILE); + } +} + +static void ors_command_read() +{ + FILE* orsout; + char command[1024], result[512]; + int set_page_done = 0, read_ret = 0; + + if ((read_ret = read(ors_read_fd, &command, sizeof(command))) > 0) { + command[1022] = '\n'; + command[1023] = '\0'; + LOGINFO("Command '%s' received\n", command); + orsout = fopen(ORS_OUTPUT_FILE, "w"); + if (!orsout) { + close(ors_read_fd); + ors_read_fd = -1; + LOGINFO("Unable to fopen %s\n", ORS_OUTPUT_FILE); + unlink(ORS_INPUT_FILE); + unlink(ORS_OUTPUT_FILE); + return; + } + if (DataManager::GetIntValue("tw_busy") != 0) { + strcpy(result, "Failed, operation in progress\n"); + fprintf(orsout, "%s", result); + LOGINFO("Command cannot be performed, operation in progress.\n"); + } else { + if (gui_console_only() == 0) { + LOGINFO("Console started successfully\n"); + gui_set_FILE(orsout); + if (strlen(command) > 11 && strncmp(command, "runscript", 9) == 0) { + char* filename = command + 11; + if (OpenRecoveryScript::copy_script_file(filename) == 0) { + LOGERR("Unable to copy script file\n"); + } else { + OpenRecoveryScript::run_script_file(); + } + } else if (strlen(command) > 5 && strncmp(command, "get", 3) == 0) { + char* varname = command + 4; + string temp; + DataManager::GetValue(varname, temp); + gui_print("%s = %s\n", varname, temp.c_str()); + } else if (strlen(command) > 9 && strncmp(command, "decrypt", 7) == 0) { + char* pass = command + 8; + gui_print("Attempting to decrypt data partition via command line.\n"); + if (PartitionManager.Decrypt_Device(pass) == 0) { + set_page_done = 1; + } + } else if (OpenRecoveryScript::Insert_ORS_Command(command)) { + OpenRecoveryScript::run_script_file(); + } + gui_set_FILE(NULL); + gGuiConsoleTerminate.set_value(1); + } + } + fclose(orsout); + LOGINFO("Done reading ORS command from command line\n"); + if (set_page_done) { + DataManager::SetValue("tw_page_done", 1); + } else { + // The select function will return ready to read and the + // read function will return errno 19 no such device unless + // we set everything up all over again. + close(ors_read_fd); + setup_ors_command(); + } + } else { + LOGINFO("ORS command line read returned an error: %i, %i, %s\n", read_ret, errno, strerror(errno)); + } + return; +} + +// This special function will return immediately the first time, but then +// always returns 1/30th of a second (or immediately if called later) from +// the last time it was called +static void loopTimer(int input_timeout_ms) +{ + static timespec lastCall; + static int initialized = 0; + + if (!initialized) + { + clock_gettime(CLOCK_MONOTONIC, &lastCall); + initialized = 1; + return; + } + + do + { + bool got_event = input_handler.processInput(input_timeout_ms); // get inputs but don't send drag notices + timespec curTime; + clock_gettime(CLOCK_MONOTONIC, &curTime); + + timespec diff = TWFunc::timespec_diff(lastCall, curTime); + + // This is really 2 or 30 times per second + // As long as we get events, increase the timeout so we can catch up with input + long timeout = got_event ? 500000000 : 33333333; + + if (diff.tv_sec || diff.tv_nsec > timeout) + { + // int32_t input_time = TWFunc::timespec_diff_ms(lastCall, curTime); + // LOGINFO("loopTimer(): %u ms, count: %u\n", input_time, count); + + lastCall = curTime; + input_handler.handleDrag(); // send only drag notices if needed + return; + } + + // We need to sleep some period time microseconds + //unsigned int sleepTime = 33333 -(diff.tv_nsec / 1000); + //usleep(sleepTime); // removed so we can scan for input + input_timeout_ms = 0; + } while (1); +} + +static int runPages(const char *page_name, const int stop_on_page_done) +{ + DataManager::SetValue("tw_page_done", 0); + DataManager::SetValue("tw_gui_done", 0); + + if (page_name) + gui_changePage(page_name); + + // Raise the curtain + if (gCurtain != NULL) + { + gr_surface surface; + + PageManager::Render(); + gr_get_surface(&surface); + curtainRaise(surface); + gr_free_surface(surface); + } + + gGuiRunning = 1; + + DataManager::SetValue("tw_loaded", 1); + +#ifndef TW_OEM_BUILD + struct timeval timeout; + fd_set fdset; + int has_data = 0; +#endif + + int input_timeout_ms = 0; + int idle_frames = 0; + + for (;;) + { + loopTimer(input_timeout_ms); +#ifndef TW_OEM_BUILD + if (ors_read_fd > 0) { + FD_ZERO(&fdset); + FD_SET(ors_read_fd, &fdset); + timeout.tv_sec = 0; + timeout.tv_usec = 1; + has_data = select(ors_read_fd+1, &fdset, NULL, NULL, &timeout); + if (has_data > 0) { + ors_command_read(); + } + } +#endif + + if (gGuiConsoleRunning.get_value()) { + continue; + } + + if (!gForceRender.get_value()) + { + int ret = PageManager::Update(); + if (ret == 0) + ++idle_frames; + else + idle_frames = 0; + // due to possible animation objects, we need to delay activating the input timeout + input_timeout_ms = idle_frames > 15 ? 1000 : 0; + +#ifndef PRINT_RENDER_TIME + if (ret > 1) + PageManager::Render(); + + if (ret > 0) + flip(); +#else + if (ret > 1) + { + timespec start, end; + int32_t render_t, flip_t; + clock_gettime(CLOCK_MONOTONIC, &start); + PageManager::Render(); + clock_gettime(CLOCK_MONOTONIC, &end); + render_t = TWFunc::timespec_diff_ms(start, end); + + flip(); + clock_gettime(CLOCK_MONOTONIC, &start); + flip_t = TWFunc::timespec_diff_ms(end, start); + + LOGINFO("Render(): %u ms, flip(): %u ms, total: %u ms\n", render_t, flip_t, render_t+flip_t); + } + else if (ret > 0) + flip(); +#endif + } + else + { + gForceRender.set_value(0); + PageManager::Render(); + flip(); + input_timeout_ms = 0; + } + + blankTimer.checkForTimeout(); + if (stop_on_page_done && DataManager::GetIntValue("tw_page_done") != 0) + { + gui_changePage("main"); + break; + } + if (DataManager::GetIntValue("tw_gui_done") != 0) + break; + } + if (ors_read_fd > 0) + close(ors_read_fd); + ors_read_fd = -1; + gGuiRunning = 0; + return 0; +} + +int gui_forceRender(void) +{ + gForceRender.set_value(1); + return 0; +} + +int gui_changePage(std::string newPage) +{ + LOGINFO("Set page: '%s'\n", newPage.c_str()); + PageManager::ChangePage(newPage); + gForceRender.set_value(1); + return 0; +} + +int gui_changeOverlay(std::string overlay) +{ + LOGINFO("Set overlay: '%s'\n", overlay.c_str()); + PageManager::ChangeOverlay(overlay); + gForceRender.set_value(1); + return 0; +} + +int gui_changePackage(std::string newPackage) +{ + PageManager::SelectPackage(newPackage); + gForceRender.set_value(1); + return 0; +} + +std::string gui_parse_text(std::string str) +{ + // This function parses text for DataManager values encompassed by %value% in the XML + // and string resources (%@resource_name%) + size_t pos = 0; + + while (1) + { + size_t next = str.find('%', pos); + if (next == std::string::npos) + return str; + + size_t end = str.find('%', next + 1); + if (end == std::string::npos) + return str; + + // We have a block of data + std::string var = str.substr(next + 1, (end - next) - 1); + str.erase(next, (end - next) + 1); + + if (next + 1 == end) + str.insert(next, 1, '%'); + else + { + std::string value; + if (var.size() > 0 && var[0] == '@') { + // this is a string resource ("%@string_name%") + value = PageManager::GetResources()->FindString(var.substr(1)); + str.insert(next, value); + } + else if (DataManager::GetValue(var, value) == 0) + str.insert(next, value); + } + + pos = next + 1; + } +} + +extern "C" int gui_init(void) +{ + gr_init(); + std::string curtain_path = TWRES "images/curtain.jpg"; + gr_surface source_Surface = NULL; + + if (res_create_surface(curtain_path.c_str(), &source_Surface)) + { + printf("Unable to locate '%s'\nDid you set a TW_THEME in your config files?\n", curtain_path.c_str()); + return -1; + } + if (gr_get_width(source_Surface) != gr_fb_width() || gr_get_height(source_Surface) != gr_fb_height()) { + // We need to scale the curtain to fit the screen + float scale_w = (float)gr_fb_width() / (float)gr_get_width(source_Surface); + float scale_h = (float)gr_fb_height() / (float)gr_get_height(source_Surface); + if (res_scale_surface(source_Surface, &gCurtain, scale_w, scale_h)) { + LOGINFO("Failed to scale curtain\n"); + gCurtain = source_Surface; + } else { + LOGINFO("Scaling the curtain width %fx and height %fx\n", scale_w, scale_h); + } + } else { + gCurtain = source_Surface; + } + + curtainSet(); + + ev_init(); + return 0; +} + +extern "C" int gui_loadResources(void) +{ +#ifndef TW_OEM_BUILD + int check = 0; + DataManager::GetValue(TW_IS_ENCRYPTED, check); + + if (check) + { + if (PageManager::LoadPackage("TWRP", TWRES "ui.xml", "decrypt")) + { + LOGERR("Failed to load base packages.\n"); + goto error; + } + else + check = 1; + } + + if (check == 0 && PageManager::LoadPackage("TWRP", "/script/ui.xml", "main")) + { + std::string theme_path; + + theme_path = DataManager::GetSettingsStoragePath(); + if (!PartitionManager.Mount_Settings_Storage(false)) + { + int retry_count = 5; + while (retry_count > 0 && !PartitionManager.Mount_Settings_Storage(false)) + { + usleep(500000); + retry_count--; + } + + if (!PartitionManager.Mount_Settings_Storage(false)) + { + LOGERR("Unable to mount %s during GUI startup.\n", + theme_path.c_str()); + check = 1; + } + } + + theme_path += "/TWRP/theme/ui.zip"; + if (check || PageManager::LoadPackage("TWRP", theme_path, "main")) + { +#endif // ifndef TW_OEM_BUILD + if (PageManager::LoadPackage("TWRP", TWRES "ui.xml", "main")) + { + LOGERR("Failed to load base packages.\n"); + goto error; + } +#ifndef TW_OEM_BUILD + } + } +#endif // ifndef TW_OEM_BUILD + // Set the default package + PageManager::SelectPackage("TWRP"); + + gGuiInitialized = 1; + return 0; + +error: + LOGERR("An internal error has occurred: unable to load theme.\n"); + gGuiInitialized = 0; + return -1; +} + +extern "C" int gui_loadCustomResources(void) +{ +#ifndef TW_OEM_BUILD + if (!PartitionManager.Mount_Settings_Storage(false)) { + LOGERR("Unable to mount settings storage during GUI startup.\n"); + return -1; + } + + std::string theme_path = DataManager::GetSettingsStoragePath(); + theme_path += "/TWRP/theme/ui.zip"; + // Check for a custom theme + if (TWFunc::Path_Exists(theme_path)) { + // There is a custom theme, try to load it + if (PageManager::ReloadPackage("TWRP", theme_path)) { + // Custom theme failed to load, try to load stock theme + if (PageManager::ReloadPackage("TWRP", TWRES "ui.xml")) { + LOGERR("Failed to load base packages.\n"); + goto error; + } + } + } + // Set the default package + PageManager::SelectPackage("TWRP"); +#endif + return 0; + +error: + LOGERR("An internal error has occurred: unable to load theme.\n"); + gGuiInitialized = 0; + return -1; +} + +extern "C" int gui_start(void) +{ + return gui_startPage(NULL, 1, 0); +} + +extern "C" int gui_startPage(const char *page_name, const int allow_commands, int stop_on_page_done) +{ + if (!gGuiInitialized) + return -1; + + gGuiConsoleTerminate.set_value(1); + + while (gGuiConsoleRunning.get_value()) + usleep(10000); + + // Set the default package + PageManager::SelectPackage("TWRP"); + + input_handler.init(); +#ifndef TW_OEM_BUILD + if (allow_commands) + { + if (ors_read_fd < 0) + setup_ors_command(); + } else { + if (ors_read_fd >= 0) { + close(ors_read_fd); + ors_read_fd = -1; + } + } +#endif + return runPages(page_name, stop_on_page_done); +} + +static void * console_thread(void *cookie) +{ + PageManager::SwitchToConsole(); + + while (!gGuiConsoleTerminate.get_value()) + { + loopTimer(0); + + if (!gForceRender.get_value()) + { + int ret; + + ret = PageManager::Update(); + if (ret > 1) + PageManager::Render(); + + if (ret > 0) + flip(); + + if (ret < 0) + LOGERR("An update request has failed.\n"); + } + else + { + gForceRender.set_value(0); + PageManager::Render(); + flip(); + } + } + gGuiConsoleRunning.set_value(0); + gForceRender.set_value(1); // this will kickstart the GUI to render again + PageManager::EndConsole(); + LOGINFO("Console stopping\n"); + return NULL; +} + +extern "C" int gui_console_only(void) +{ + if (!gGuiInitialized) + return -1; + + gGuiConsoleTerminate.set_value(0); + + if (gGuiConsoleRunning.get_value()) + return 0; + + gGuiConsoleRunning.set_value(1); + + // Start by spinning off an input handler. + pthread_t t; + pthread_create(&t, NULL, console_thread, NULL); + + return 0; +} + +extern "C" void set_scale_values(float w, float h) +{ + scale_theme_w = w; + scale_theme_h = h; +} + +extern "C" int scale_theme_x(int initial_x) +{ + if (scale_theme_w != 1) { + int scaled = (float)initial_x * scale_theme_w; + if (scaled == 0 && initial_x > 0) + return 1; + return scaled; + } + return initial_x; +} + +extern "C" int scale_theme_y(int initial_y) +{ + if (scale_theme_h != 1) { + int scaled = (float)initial_y * scale_theme_h; + if (scaled == 0 && initial_y > 0) + return 1; + return scaled; + } + return initial_y; +} + +extern "C" int scale_theme_min(int initial_value) +{ + if (scale_theme_w != 1 || scale_theme_h != 1) { + if (scale_theme_w < scale_theme_h) + return scale_theme_x(initial_value); + else + return scale_theme_y(initial_value); + } + return initial_value; +} + +extern "C" float get_scale_w() +{ + return scale_theme_w; +} + +extern "C" float get_scale_h() +{ + return scale_theme_h; +} diff --git a/gui/gui.h b/gui/gui.h new file mode 100644 index 000000000..f6f0483a4 --- /dev/null +++ b/gui/gui.h @@ -0,0 +1,42 @@ +/* + Copyright 2012 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef _GUI_HEADER +#define _GUI_HEADER + +#include <stdio.h> + +int gui_console_only(); +int gui_init(); +int gui_loadResources(); +int gui_loadCustomResources(); +int gui_start(); +int gui_startPage(const char* page_name, const int allow_comands, int stop_on_page_done); +void gui_print(const char *fmt, ...); +void gui_print_color(const char *color, const char *fmt, ...); +void gui_set_FILE(FILE* f); + +void set_scale_values(float w, float h); +int scale_theme_x(int initial_x); +int scale_theme_y(int initial_y); +int scale_theme_min(int initial_value); +float get_scale_w(); +float get_scale_h(); + +#endif // _GUI_HEADER + diff --git a/gui/hardwarekeyboard.cpp b/gui/hardwarekeyboard.cpp new file mode 100644 index 000000000..1f34c5e1d --- /dev/null +++ b/gui/hardwarekeyboard.cpp @@ -0,0 +1,416 @@ +// hardwarekeyboard.cpp - HardwareKeyboard object + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> + +#include <string> + +extern "C" { +#include "../common.h" +} + +#include "objects.hpp" +#include <linux/input.h> + +HardwareKeyboard::HardwareKeyboard() + : mLastKeyChar(0) +{ +} + +HardwareKeyboard::~HardwareKeyboard() +{ +} + +// Map keys to other keys. +static int TranslateKeyCode(int key_code) +{ + switch (key_code) { + case KEY_HOMEPAGE: // Home key on Asus Transformer hardware keyboard + return KEY_HOME; + case KEY_SLEEP: // Lock key on Asus Transformer hardware keyboard + return KEY_POWER; + } + return key_code; +} + +int HardwareKeyboard::KeyDown(int key_code) +{ +#ifdef _EVENT_LOGGING + LOGE("HardwareKeyboard::KeyDown %i\n", key_code); +#endif + key_code = TranslateKeyCode(key_code); + + // determine if any Shift key is held down + bool shiftkey = false; + std::set<int>::iterator it = mPressedKeys.find(KEY_LEFTSHIFT); + if (it == mPressedKeys.end()) + it = mPressedKeys.find(KEY_RIGHTSHIFT); + if (it != mPressedKeys.end()) + shiftkey = true; + + mPressedKeys.insert(key_code); + + int keyboard = -1; + + switch (key_code) { + case KEY_A: + if (shiftkey) + keyboard = 'A'; + else + keyboard = 'a'; + break; + case KEY_B: + if (shiftkey) + keyboard = 'B'; + else + keyboard = 'b'; + break; + case KEY_C: + if (shiftkey) + keyboard = 'C'; + else + keyboard = 'c'; + break; + case KEY_D: + if (shiftkey) + keyboard = 'D'; + else + keyboard = 'd'; + break; + case KEY_E: + if (shiftkey) + keyboard = 'E'; + else + keyboard = 'e'; + break; + case KEY_F: + if (shiftkey) + keyboard = 'F'; + else + keyboard = 'f'; + break; + case KEY_G: + if (shiftkey) + keyboard = 'G'; + else + keyboard = 'g'; + break; + case KEY_H: + if (shiftkey) + keyboard = 'H'; + else + keyboard = 'h'; + break; + case KEY_I: + if (shiftkey) + keyboard = 'I'; + else + keyboard = 'i'; + break; + case KEY_J: + if (shiftkey) + keyboard = 'J'; + else + keyboard = 'j'; + break; + case KEY_K: + if (shiftkey) + keyboard = 'K'; + else + keyboard = 'k'; + break; + case KEY_L: + if (shiftkey) + keyboard = 'L'; + else + keyboard = 'l'; + break; + case KEY_M: + if (shiftkey) + keyboard = 'M'; + else + keyboard = 'm'; + break; + case KEY_N: + if (shiftkey) + keyboard = 'N'; + else + keyboard = 'n'; + break; + case KEY_O: + if (shiftkey) + keyboard = 'O'; + else + keyboard = 'o'; + break; + case KEY_P: + if (shiftkey) + keyboard = 'P'; + else + keyboard = 'p'; + break; + case KEY_Q: + if (shiftkey) + keyboard = 'Q'; + else + keyboard = 'q'; + break; + case KEY_R: + if (shiftkey) + keyboard = 'R'; + else + keyboard = 'r'; + break; + case KEY_S: + if (shiftkey) + keyboard = 'S'; + else + keyboard = 's'; + break; + case KEY_T: + if (shiftkey) + keyboard = 'T'; + else + keyboard = 't'; + break; + case KEY_U: + if (shiftkey) + keyboard = 'U'; + else + keyboard = 'u'; + break; + case KEY_V: + if (shiftkey) + keyboard = 'V'; + else + keyboard = 'v'; + break; + case KEY_W: + if (shiftkey) + keyboard = 'W'; + else + keyboard = 'w'; + break; + case KEY_X: + if (shiftkey) + keyboard = 'X'; + else + keyboard = 'x'; + break; + case KEY_Y: + if (shiftkey) + keyboard = 'Y'; + else + keyboard = 'y'; + break; + case KEY_Z: + if (shiftkey) + keyboard = 'Z'; + else + keyboard = 'z'; + break; + case KEY_0: + if (shiftkey) + keyboard = ')'; + else + keyboard = '0'; + break; + case KEY_1: + if (shiftkey) + keyboard = '!'; + else + keyboard = '1'; + break; + case KEY_2: + if (shiftkey) + keyboard = '@'; + else + keyboard = '2'; + break; + case KEY_3: + if (shiftkey) + keyboard = '#'; + else + keyboard = '3'; + break; + case KEY_4: + if (shiftkey) + keyboard = '$'; + else + keyboard = '4'; + break; + case KEY_5: + if (shiftkey) + keyboard = '%'; + else + keyboard = '5'; + break; + case KEY_6: + if (shiftkey) + keyboard = '^'; + else + keyboard = '6'; + break; + case KEY_7: + if (shiftkey) + keyboard = '&'; + else + keyboard = '7'; + break; + case KEY_8: + if (shiftkey) + keyboard = '*'; + else + keyboard = '8'; + break; + case KEY_9: + if (shiftkey) + keyboard = '('; + else + keyboard = '9'; + break; + case KEY_SPACE: + keyboard = ' '; + break; + case KEY_BACKSPACE: + keyboard = KEYBOARD_BACKSPACE; + break; + case KEY_ENTER: + keyboard = KEYBOARD_ACTION; + break; + case KEY_SLASH: + if (shiftkey) + keyboard = '?'; + else + keyboard = '/'; + break; + case KEY_DOT: + if (shiftkey) + keyboard = '>'; + else + keyboard = '.'; + break; + case KEY_COMMA: + if (shiftkey) + keyboard = '<'; + else + keyboard = ','; + break; + case KEY_MINUS: + if (shiftkey) + keyboard = '_'; + else + keyboard = '-'; + break; + case KEY_GRAVE: + if (shiftkey) + keyboard = '~'; + else + keyboard = '`'; + break; + case KEY_EQUAL: + if (shiftkey) + keyboard = '+'; + else + keyboard = '='; + break; + case KEY_LEFTBRACE: + if (shiftkey) + keyboard = '{'; + else + keyboard = '['; + break; + case KEY_RIGHTBRACE: + if (shiftkey) + keyboard = '}'; + else + keyboard = ']'; + break; + case KEY_BACKSLASH: + if (shiftkey) + keyboard = '|'; + else + keyboard = '\\'; + break; + case KEY_SEMICOLON: + if (shiftkey) + keyboard = ':'; + else + keyboard = ';'; + break; + case KEY_APOSTROPHE: + if (shiftkey) + keyboard = '\"'; + else + keyboard = '\''; + break; + case KEY_UP: // Up arrow + keyboard = KEYBOARD_ARROW_UP; + break; + case KEY_DOWN: // Down arrow + keyboard = KEYBOARD_ARROW_DOWN; + break; + case KEY_LEFT: // Left arrow + keyboard = KEYBOARD_ARROW_LEFT; + break; + case KEY_RIGHT: // Right arrow + keyboard = KEYBOARD_ARROW_RIGHT; + break; + +#ifdef _EVENT_LOGGING + default: + LOGE("Unmapped keycode: %i\n", key_code); + break; +#endif + } + if (keyboard != -1) { + mLastKeyChar = keyboard; + // NotifyKeyboard means: "report character to input widget". KEYBOARD_* codes are special, others are ASCII chars. + if (!PageManager::NotifyKeyboard(keyboard)) + return 1; // Return 1 to enable key repeat + } else { + mLastKeyChar = 0; + PageManager::NotifyKey(key_code, true); + } + return 0; +} + +int HardwareKeyboard::KeyUp(int key_code) +{ +#ifdef _EVENT_LOGGING + LOGE("HardwareKeyboard::KeyUp %i\n", key_code); +#endif + key_code = TranslateKeyCode(key_code); + std::set<int>::iterator itr = mPressedKeys.find(key_code); + if (itr != mPressedKeys.end()) { + mPressedKeys.erase(itr); + PageManager::NotifyKey(key_code, false); + } + return 0; +} + +int HardwareKeyboard::KeyRepeat() +{ +#ifdef _EVENT_LOGGING + LOGE("HardwareKeyboard::KeyRepeat: %i\n", mLastKeyChar); +#endif + if (mLastKeyChar) + PageManager::NotifyKeyboard(mLastKeyChar); + return 0; +} + +void HardwareKeyboard::ConsumeKeyRelease(int key) +{ + // causes following KeyUp event to suppress notifications + mPressedKeys.erase(key); +} diff --git a/gui/image.cpp b/gui/image.cpp new file mode 100644 index 000000000..8b43aaa34 --- /dev/null +++ b/gui/image.cpp @@ -0,0 +1,92 @@ +// image.cpp - GUIImage object + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" + +GUIImage::GUIImage(xml_node<>* node) : GUIObject(node) +{ + mImage = NULL; + mHighlightImage = NULL; + isHighlighted = false; + + if (!node) + return; + + mImage = LoadAttrImage(FindNode(node, "image"), "resource"); + mHighlightImage = LoadAttrImage(FindNode(node, "image"), "highlightresource"); + + // Load the placement + LoadPlacement(FindNode(node, "placement"), &mRenderX, &mRenderY, NULL, NULL, &mPlacement); + + if (mImage && mImage->GetResource()) + { + mRenderW = mImage->GetWidth(); + mRenderH = mImage->GetHeight(); + + // Adjust for placement + if (mPlacement != TOP_LEFT && mPlacement != BOTTOM_LEFT) + { + if (mPlacement == CENTER) + mRenderX -= (mRenderW / 2); + else + mRenderX -= mRenderW; + } + if (mPlacement != TOP_LEFT && mPlacement != TOP_RIGHT) + { + if (mPlacement == CENTER) + mRenderY -= (mRenderH / 2); + else + mRenderY -= mRenderH; + } + SetPlacement(TOP_LEFT); + } +} + +int GUIImage::Render(void) +{ + if (!isConditionTrue()) + return 0; + + if (isHighlighted && mHighlightImage && mHighlightImage->GetResource()) { + gr_blit(mHighlightImage->GetResource(), 0, 0, mRenderW, mRenderH, mRenderX, mRenderY); + return 0; + } + else if (!mImage || !mImage->GetResource()) + return -1; + + gr_blit(mImage->GetResource(), 0, 0, mRenderW, mRenderH, mRenderX, mRenderY); + return 0; +} + +int GUIImage::SetRenderPos(int x, int y, int w, int h) +{ + if (w || h) + return -1; + + mRenderX = x; + mRenderY = y; + return 0; +} + diff --git a/gui/input.cpp b/gui/input.cpp new file mode 100644 index 000000000..ca27ea812 --- /dev/null +++ b/gui/input.cpp @@ -0,0 +1,713 @@ +/* + Copyright 2012 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see <http://www.gnu.org/licenses/>. +*/ + +// input.cpp - GUIInput object + +#include <linux/input.h> +#include <pthread.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" +#include "../data.hpp" + +GUIInput::GUIInput(xml_node<>* node) + : GUIObject(node) +{ + xml_attribute<>* attr; + xml_node<>* child; + + mInputText = NULL; + mAction = NULL; + mBackground = NULL; + mCursor = NULL; + mFont = NULL; + mRendered = false; + HasMask = false; + DrawCursor = false; + isLocalChange = true; + HasAllowed = false; + HasDisabled = false; + skipChars = scrollingX = mFontHeight = mFontY = lastX = 0; + mBackgroundX = mBackgroundY = mBackgroundW = mBackgroundH = MinLen = MaxLen = 0; + mCursorLocation = -1; // -1 is always the end of the string + CursorWidth = 3; + ConvertStrToColor("black", &mBackgroundColor); + ConvertStrToColor("white", &mCursorColor); + + if (!node) + return; + + // Load text directly from the node + mInputText = new GUIText(node); + // Load action directly from the node + mAction = new GUIAction(node); + + if (mInputText->Render() < 0) + { + delete mInputText; + mInputText = NULL; + } + + // Load the background + child = FindNode(node, "background"); + if (child) + { + mBackground = LoadAttrImage(child, "resource"); + mBackgroundColor = LoadAttrColor(child, "color", mBackgroundColor); + } + if (mBackground && mBackground->GetResource()) + { + mBackgroundW = mBackground->GetWidth(); + mBackgroundH = mBackground->GetHeight(); + } + + // Load the cursor color + child = FindNode(node, "cursor"); + if (child) + { + mCursor = LoadAttrImage(child, "resource"); + mCursorColor = LoadAttrColor(child, "color", mCursorColor); + attr = child->first_attribute("hasfocus"); + if (attr) + { + std::string focus = attr->value(); + SetInputFocus(atoi(focus.c_str())); + } + CursorWidth = LoadAttrIntScaleX(child, "width", CursorWidth); + } + DrawCursor = HasInputFocus; + + // Load the font + child = FindNode(node, "font"); + if (child) + { + mFont = LoadAttrFont(child, "resource"); + mFontHeight = mFont->GetHeight(); + } + + child = FindNode(node, "text"); + if (child) mText = child->value(); + mLastValue = gui_parse_text(mText); + + child = FindNode(node, "data"); + if (child) + { + attr = child->first_attribute("name"); + if (attr) + mVariable = attr->value(); + attr = child->first_attribute("default"); + if (attr) + DataManager::SetValue(mVariable, attr->value()); + mMask = LoadAttrString(child, "mask"); + HasMask = !mMask.empty(); + attr = child->first_attribute("maskvariable"); + if (attr) + mMaskVariable = attr->value(); + else + mMaskVariable = mVariable; + } + + // Load input restrictions + child = FindNode(node, "restrict"); + if (child) + { + MinLen = LoadAttrInt(child, "minlen", MinLen); + MaxLen = LoadAttrInt(child, "maxlen", MaxLen); + AllowedList = LoadAttrString(child, "allow"); + HasAllowed = !AllowedList.empty(); + DisabledList = LoadAttrString(child, "disable"); + HasDisabled = !DisabledList.empty(); + } + + // Load the placement + LoadPlacement(FindNode(node, "placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH); + SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH); + + if (mInputText && mFontHeight && mFontHeight < (unsigned)mRenderH) { + mFontY = ((mRenderH - mFontHeight) / 2) + mRenderY; + mInputText->SetRenderPos(mRenderX, mFontY); + } else + mFontY = mRenderY; + + if (mInputText) + mInputText->SetMaxWidth(mRenderW); + + isLocalChange = false; + HandleTextLocation(-3); +} + +GUIInput::~GUIInput() +{ + delete mInputText; + delete mAction; +} + +int GUIInput::HandleTextLocation(int x) +{ + int textWidth; + string displayValue, originalValue, insertChar; + void* fontResource = NULL; + + if (mFont) + fontResource = mFont->GetResource(); + + DataManager::GetValue(mVariable, originalValue); + displayValue = originalValue; + if (HasMask) { + int index, string_size = displayValue.size(); + string maskedValue; + for (index=0; index<string_size; index++) + maskedValue += mMask; + displayValue = maskedValue; + } + textWidth = gr_measureEx(displayValue.c_str(), fontResource); + if (textWidth <= mRenderW) { + lastX = x; + scrollingX = 0; + skipChars = 0; + mInputText->SkipCharCount(skipChars); + mRendered = false; + return 0; + } + + if (skipChars && skipChars < displayValue.size()) + displayValue.erase(0, skipChars); + + textWidth = gr_measureEx(displayValue.c_str(), fontResource); + mRendered = false; + + int deltaX, deltaText, newWidth; + + if (x < -1000) { + // No change in scrolling + if (x == -1003) + mCursorLocation = -1; + + if (mCursorLocation == -1) { + displayValue = originalValue; + skipChars = 0; + textWidth = gr_measureEx(displayValue.c_str(), fontResource); + while (textWidth > mRenderW) { + displayValue.erase(0, 1); + skipChars++; + textWidth = gr_measureEx(displayValue.c_str(), fontResource); + } + scrollingX = mRenderW - textWidth; + mInputText->SkipCharCount(skipChars); + } else if (x == -1001) { + // Added a new character + int adjust_scrollingX = 0; + string cursorLocate; + + cursorLocate = displayValue; + cursorLocate.resize(mCursorLocation); + textWidth = gr_measureEx(cursorLocate.c_str(), fontResource); + while (textWidth > mRenderW) { + skipChars++; + mCursorLocation--; + cursorLocate.erase(0, 1); + textWidth = gr_measureEx(cursorLocate.c_str(), fontResource); + adjust_scrollingX = -1; + } + if (adjust_scrollingX) { + scrollingX = mRenderW - textWidth; + if (scrollingX < 0) + scrollingX = 0; + } + mInputText->SkipCharCount(skipChars); + } else if (x == -1002) { + // Deleted a character + while (-1) { + if (skipChars == 0) { + scrollingX = 0; + mInputText->SkipCharCount(skipChars); + return 0; + } + insertChar = originalValue.substr(skipChars - 1, 1); + displayValue.insert(0, insertChar); + newWidth = gr_measureEx(displayValue.c_str(), fontResource); + deltaText = newWidth - textWidth; + if (newWidth > mRenderW) { + scrollingX = mRenderW - textWidth; + if (scrollingX < 0) + scrollingX = 0; + mInputText->SkipCharCount(skipChars); + return 0; + } else { + textWidth = newWidth; + skipChars--; + mCursorLocation++; + } + } + } else + LOGINFO("GUIInput::HandleTextLocation -> We really shouldn't ever get here...\n"); + } else if (x > lastX) { + // Dragging to right, scrolling left + while (-1) { + deltaX = x - lastX + scrollingX; + if (skipChars == 0 || deltaX == 0) { + scrollingX = 0; + lastX = x; + mInputText->SkipCharCount(skipChars); + return 0; + } + insertChar = originalValue.substr(skipChars - 1, 1); + displayValue.insert(0, insertChar); + newWidth = gr_measureEx(displayValue.c_str(), fontResource); + deltaText = newWidth - textWidth; + if (deltaText < deltaX) { + lastX += deltaText; + textWidth = newWidth; + skipChars--; + } else { + scrollingX = deltaX; + lastX = x; + mInputText->SkipCharCount(skipChars); + return 0; + } + } + } else if (x < lastX) { + // Dragging to left, scrolling right + if (textWidth <= mRenderW) { + lastX = x; + scrollingX = mRenderW - textWidth; + return 0; + } + if (scrollingX) { + deltaX = lastX - x; + if (scrollingX > deltaX) { + scrollingX -= deltaX; + lastX = x; + return 0; + } else { + lastX -= deltaX; + scrollingX = 0; + } + } + while (-1) { + deltaX = lastX - x; + displayValue.erase(0, 1); + skipChars++; + newWidth = gr_measureEx(displayValue.c_str(), fontResource); + deltaText = textWidth - newWidth; + if (newWidth <= mRenderW) { + scrollingX = mRenderW - newWidth; + lastX = x; + mInputText->SkipCharCount(skipChars); + return 0; + } + if (deltaText < deltaX) { + lastX -= deltaText; + textWidth = newWidth; + } else { + scrollingX = deltaText - deltaX; + lastX = x; + mInputText->SkipCharCount(skipChars); + return 0; + } + } + } + return 0; +} + +int GUIInput::Render(void) +{ + if (!isConditionTrue()) + { + mRendered = false; + return 0; + } + + void* fontResource = NULL; + if (mFont) fontResource = mFont->GetResource(); + + // First step, fill background + gr_color(mBackgroundColor.red, mBackgroundColor.green, mBackgroundColor.blue, 255); + gr_fill(mRenderX, mRenderY, mRenderW, mRenderH); + + // Next, render the background resource (if it exists) + if (mBackground && mBackground->GetResource()) + { + mBackgroundX = mRenderX + ((mRenderW - mBackgroundW) / 2); + mBackgroundY = mRenderY + ((mRenderH - mBackgroundH) / 2); + gr_blit(mBackground->GetResource(), 0, 0, mBackgroundW, mBackgroundH, mBackgroundX, mBackgroundY); + } + + int ret = 0; + + // Render the text + mInputText->SetRenderPos(mRenderX + scrollingX, mFontY); + mInputText->SetMaxWidth(mRenderW - scrollingX); + if (mInputText) ret = mInputText->Render(); + if (ret < 0) return ret; + + if (HasInputFocus && DrawCursor) { + // Render the cursor + string displayValue; + int cursorX; + DataManager::GetValue(mVariable, displayValue); + if (HasMask) { + int index, string_size = displayValue.size(); + string maskedValue; + for (index=0; index<string_size; index++) + maskedValue += mMask; + displayValue = maskedValue; + } + if (displayValue.size() == 0) { + skipChars = 0; + mCursorLocation = -1; + cursorX = mRenderX; + } else { + if (skipChars && skipChars < displayValue.size()) { + displayValue.erase(0, skipChars); + } + if (mCursorLocation == 0) { + // Cursor is at the beginning + cursorX = mRenderX; + } else if (mCursorLocation > 0) { + // Cursor is in the middle + if (displayValue.size() > (unsigned)mCursorLocation) { + string cursorDisplay; + + cursorDisplay = displayValue; + cursorDisplay.resize(mCursorLocation); + cursorX = gr_measureEx(cursorDisplay.c_str(), fontResource) + mRenderX; + } else { + // Cursor location is after the end of the text - reset to -1 + mCursorLocation = -1; + cursorX = gr_measureEx(displayValue.c_str(), fontResource) + mRenderX; + } + } else { + // Cursor is at the end (-1) + cursorX = gr_measureEx(displayValue.c_str(), fontResource) + mRenderX; + } + } + cursorX += scrollingX; + // Make sure that the cursor doesn't go past the boundaries of the box + if (cursorX + (int)CursorWidth > mRenderX + mRenderW) + cursorX = mRenderX + mRenderW - CursorWidth; + + // Set the color for the cursor + gr_color(mCursorColor.red, mCursorColor.green, mCursorColor.blue, 255); + gr_fill(cursorX, mFontY, CursorWidth, mFontHeight); + } + + mRendered = true; + return ret; +} + +int GUIInput::Update(void) +{ + if (!isConditionTrue()) return (mRendered ? 2 : 0); + if (!mRendered) return 2; + + int ret = 0; + + if (mInputText) ret = mInputText->Update(); + if (ret < 0) return ret; + + return ret; +} + +int GUIInput::GetSelection(int x, int y) +{ + if (x < mRenderX || x - mRenderX > mRenderW || y < mRenderY || y - mRenderY > mRenderH) return -1; + return (x - mRenderX); +} + +int GUIInput::NotifyTouch(TOUCH_STATE state, int x, int y) +{ + static int startSelection = -1; + int textWidth; + string displayValue, originalValue; + void* fontResource = NULL; + + if (mFont) fontResource = mFont->GetResource(); + + if (!isConditionTrue()) + return -1; + + if (!HasInputFocus) { + if (state != TOUCH_RELEASE) + return 0; // Only change focus if touch releases within the input box + if (GetSelection(x, y) >= 0) { + // When changing focus, we don't scroll or change the cursor location + PageManager::SetKeyBoardFocus(0); + PageManager::NotifyKeyboard(0); + SetInputFocus(1); + DrawCursor = true; + mRendered = false; + } + } else { + switch (state) { + case TOUCH_HOLD: + case TOUCH_REPEAT: + break; + case TOUCH_START: + startSelection = GetSelection(x,y); + lastX = x; + DrawCursor = false; + mRendered = false; + break; + + case TOUCH_DRAG: + // Check if we dragged out of the selection window + if (GetSelection(x, y) == -1) { + lastX = 0; + break; + } + + DrawCursor = false; + + // Provide some debounce on initial touches + if (startSelection != -1 && abs(x - lastX) < 6) { + break; + } + + startSelection = -1; + if (lastX != x) + HandleTextLocation(x); + break; + + case TOUCH_RELEASE: + // We've moved the cursor location + int relativeX = x - mRenderX; + + mRendered = false; + DrawCursor = true; + DataManager::GetValue(mVariable, displayValue); + if (HasMask) { + int index, string_size = displayValue.size(); + string maskedValue; + for (index=0; index<string_size; index++) + maskedValue += mMask; + displayValue = maskedValue; + } + if (displayValue.size() == 0) { + skipChars = 0; + mCursorLocation = -1; + return 0; + } else if (skipChars && skipChars < displayValue.size()) { + displayValue.erase(0, skipChars); + } + + string cursorString; + int cursorX = 0; + unsigned index = 0; + + for(index=0; index<displayValue.size(); index++) + { + cursorString = displayValue.substr(0, index); + cursorX = gr_measureEx(cursorString.c_str(), fontResource) + mRenderX; + if (cursorX > x) { + if (index > 0) + mCursorLocation = index - 1; + else + mCursorLocation = index; + return 0; + } + } + mCursorLocation = -1; + break; + } + } + return 0; +} + +int GUIInput::NotifyVarChange(const std::string& varName, const std::string& value) +{ + GUIObject::NotifyVarChange(varName, value); + + if (varName == mVariable && !isLocalChange) { + HandleTextLocation(-1003); + return 0; + } + return 0; +} + +int GUIInput::NotifyKeyboard(int key) +{ + string variableValue; + + if (HasInputFocus) { + if (key == KEYBOARD_BACKSPACE) { + //Backspace + DataManager::GetValue(mVariable, variableValue); + if (variableValue.size() > 0 && (mCursorLocation + skipChars != 0 || mCursorLocation == -1)) { + if (mCursorLocation == -1) { + variableValue.resize(variableValue.size() - 1); + } else { + variableValue.erase(mCursorLocation + skipChars - 1, 1); + if (mCursorLocation > 0) + mCursorLocation--; + else if (skipChars > 0) + skipChars--; + } + isLocalChange = true; + DataManager::SetValue(mVariable, variableValue); + isLocalChange = false; + + if (HasMask) { + int index, string_size = variableValue.size(); + string maskedValue; + for (index=0; index<string_size; index++) + maskedValue += mMask; + DataManager::SetValue(mMaskVariable, maskedValue); + } + HandleTextLocation(-1002); + } + } else if (key == KEYBOARD_SWIPE_LEFT) { + // Delete all + isLocalChange = true; + if (mCursorLocation == -1) { + DataManager::SetValue (mVariable, ""); + if (HasMask) + DataManager::SetValue(mMaskVariable, ""); + mCursorLocation = -1; + } else { + DataManager::GetValue(mVariable, variableValue); + variableValue.erase(0, mCursorLocation + skipChars); + DataManager::SetValue(mVariable, variableValue); + if (HasMask) { + DataManager::GetValue(mMaskVariable, variableValue); + variableValue.erase(0, mCursorLocation + skipChars); + DataManager::SetValue(mMaskVariable, variableValue); + } + mCursorLocation = 0; + } + skipChars = 0; + scrollingX = 0; + mInputText->SkipCharCount(skipChars); + isLocalChange = false; + mRendered = false; + return 0; + } else if (key == KEYBOARD_ARROW_LEFT) { + if (mCursorLocation == 0 && skipChars == 0) + return 0; // we're already at the beginning + if (mCursorLocation == -1) { + DataManager::GetValue(mVariable, variableValue); + if (variableValue.size() == 0) + return 0; + mCursorLocation = variableValue.size() - skipChars - 1; + } else if (mCursorLocation == 0) { + skipChars--; + HandleTextLocation(-1002); + } else { + mCursorLocation--; + HandleTextLocation(-1002); + } + mRendered = false; + return 0; + } else if (key == KEYBOARD_ARROW_RIGHT) { + if (mCursorLocation == -1) + return 0; // we're already at the end + mCursorLocation++; + DataManager::GetValue(mVariable, variableValue); + if (variableValue.size() <= mCursorLocation + skipChars) + mCursorLocation = -1; + HandleTextLocation(-1001); + mRendered = false; + return 0; + } else if (key == KEYBOARD_HOME || key == KEYBOARD_ARROW_UP) { + DataManager::GetValue(mVariable, variableValue); + if (variableValue.size() == 0) + return 0; + mCursorLocation = 0; + skipChars = 0; + mRendered = false; + HandleTextLocation(-1002); + return 0; + } else if (key == KEYBOARD_END || key == KEYBOARD_ARROW_DOWN) { + mCursorLocation = -1; + mRendered = false; + HandleTextLocation(-1003); + return 0; + } else if (key < KEYBOARD_SPECIAL_KEYS && key > 0) { + // Regular key + if (HasAllowed && AllowedList.find((char)key) == string::npos) { + return 0; + } + if (HasDisabled && DisabledList.find((char)key) != string::npos) { + return 0; + } + DataManager::GetValue(mVariable, variableValue); + if (MaxLen != 0 && variableValue.size() >= MaxLen) { + return 0; + } + if (mCursorLocation == -1) { + variableValue += key; + } else { + variableValue.insert(mCursorLocation + skipChars, 1, key); + mCursorLocation++; + } + isLocalChange = true; + DataManager::SetValue(mVariable, variableValue); + HandleTextLocation(-1001); + isLocalChange = false; + + if (HasMask) { + int index, string_size = variableValue.size(); + string maskedValue; + for (index=0; index<string_size; index++) + maskedValue += mMask; + DataManager::SetValue(mMaskVariable, maskedValue); + } + } else if (key == KEYBOARD_ACTION) { + // Action + DataManager::GetValue(mVariable, variableValue); + if (mAction) { + unsigned inputLen = variableValue.length(); + if (inputLen < MinLen) + return 0; + else if (MaxLen != 0 && inputLen > MaxLen) + return 0; + else + return (mAction ? mAction->NotifyTouch(TOUCH_RELEASE, mRenderX, mRenderY) : 1); + } + } + return 0; + } else { + if (key == 0) { + // Somewhat ugly hack-ish way to tell the box to redraw after losing focus to remove the cursor + mRendered = false; + return 1; + } + } + return 1; +} diff --git a/gui/keyboard.cpp b/gui/keyboard.cpp new file mode 100644 index 000000000..f35a5d318 --- /dev/null +++ b/gui/keyboard.cpp @@ -0,0 +1,571 @@ +/* + Copyright 2012 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include <string.h> +#include "../data.hpp" + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +#include "gui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" + +GUIKeyboard::GUIKeyboard(xml_node<>* node) + : GUIObject(node) +{ + int layoutindex, rowindex, keyindex, Xindex, Yindex, keyHeight = 0, keyWidth = 0; + currentKey = NULL; + highlightRenderCount = 0; + hasHighlight = hasCapsHighlight = false; + char resource[10], layout[8], row[5], key[6], longpress[7]; + xml_attribute<>* attr; + xml_node<>* child; + xml_node<>* keylayout; + xml_node<>* keyrow; + + for (layoutindex=0; layoutindex<MAX_KEYBOARD_LAYOUTS; layoutindex++) { + layouts[layoutindex].keyboardImg = NULL; + memset(layouts[layoutindex].keys, 0, sizeof(Layout::keys)); + memset(layouts[layoutindex].row_end_y, 0, sizeof(Layout::row_end_y)); + } + + mRendered = false; + currentLayout = 1; + CapsLockOn = false; + + if (!node) return; + + mHighlightColor = LoadAttrColor(FindNode(node, "highlight"), "color", &hasHighlight); + mCapsHighlightColor = LoadAttrColor(FindNode(node, "capshighlight"), "color", &hasCapsHighlight); + + child = FindNode(node, "keymargin"); + mKeyMarginX = LoadAttrIntScaleX(child, "x", 0); + mKeyMarginY = LoadAttrIntScaleY(child, "y", 0); + + child = FindNode(node, "background"); + mBackgroundColor = LoadAttrColor(child, "color", COLOR(32,32,32,255)); + + child = FindNode(node, "key-alphanumeric"); + mFont = PageManager::GetResources()->FindFont(LoadAttrString(child, "font", "keylabel")); + mFontColor = LoadAttrColor(child, "textcolor", COLOR(255,255,255,255)); + mKeyColorAlphanumeric = LoadAttrColor(child, "color", COLOR(0,0,0,0)); + + child = FindNode(node, "key-other"); + mSmallFont = PageManager::GetResources()->FindFont(LoadAttrString(child, "font", "keylabel-small")); + mFontColorSmall = LoadAttrColor(child, "textcolor", COLOR(192,192,192,255)); + mKeyColorOther = LoadAttrColor(child, "color", COLOR(0,0,0,0)); + + child = FindNode(node, "longpress"); + mLongpressFont = PageManager::GetResources()->FindFont(LoadAttrString(child, "font", "keylabel-longpress")); + mLongpressFontColor = LoadAttrColor(child, "textcolor", COLOR(128,128,128,255)); + LoadPlacement(child, &longpressOffsetX, &longpressOffsetY); + + LoadKeyLabels(node, 0); // load global key labels + + // compatibility ugliness: resources should be specified in the layouts themselves instead + // Load the images for the different layouts + child = FindNode(node, "layout"); + if (child) + { + layoutindex = 1; + strcpy(resource, "resource1"); + attr = child->first_attribute(resource); + while (attr && layoutindex < (MAX_KEYBOARD_LAYOUTS + 1)) { + layouts[layoutindex - 1].keyboardImg = LoadAttrImage(child, resource); + + layoutindex++; + resource[8] = (char)(layoutindex + 48); + attr = child->first_attribute(resource); + } + } + + // Check the first image to get height and width + if (layouts[0].keyboardImg && layouts[0].keyboardImg->GetResource()) + { + mRenderW = layouts[0].keyboardImg->GetWidth(); + mRenderH = layouts[0].keyboardImg->GetHeight(); + } + + // Load all of the layout maps + layoutindex = 1; + strcpy(layout, "layout1"); + keylayout = FindNode(node, layout); + while (keylayout) + { + if (layoutindex > MAX_KEYBOARD_LAYOUTS) { + LOGERR("Too many layouts defined in keyboard.\n"); + return; + } + + LoadKeyLabels(keylayout, layoutindex); // load per-layout key labels + + Layout& lay = layouts[layoutindex - 1]; + + child = keylayout->first_node("keysize"); + keyHeight = LoadAttrIntScaleY(child, "height", 0); + keyWidth = LoadAttrIntScaleX(child, "width", 0); + // compatibility ugliness: capslock="0" means that this is the caps layout. Also it has nothing to do with keysize. + lay.is_caps = (LoadAttrInt(child, "capslock", 1) == 0); + // compatibility ugliness: revert_layout has nothing to do with keysize. + lay.revert_layout = LoadAttrInt(child, "revert_layout", -1); + + rowindex = 1; + Yindex = 0; + strcpy(row, "row1"); + keyrow = keylayout->first_node(row); + while (keyrow) + { + if (rowindex > MAX_KEYBOARD_ROWS) { + LOGERR("Too many rows defined in keyboard.\n"); + return; + } + + Yindex += keyHeight; + lay.row_end_y[rowindex - 1] = Yindex; + + keyindex = 1; + Xindex = 0; + strcpy(key, "key01"); + attr = keyrow->first_attribute(key); + + while (attr) { + if (keyindex > MAX_KEYBOARD_KEYS) { + LOGERR("Too many keys defined in a keyboard row.\n"); + return; + } + + const char* keyinfo = attr->value(); + + if (strlen(keyinfo) == 0) { + LOGERR("No key info on layout%i, row%i, key%dd.\n", layoutindex, rowindex, keyindex); + return; + } + + if (ParseKey(keyinfo, lay.keys[rowindex - 1][keyindex - 1], Xindex, keyWidth, false)) + LOGERR("Invalid key info on layout%i, row%i, key%02i.\n", layoutindex, rowindex, keyindex); + + + // PROCESS LONG PRESS INFO IF EXISTS + sprintf(longpress, "long%02i", keyindex); + attr = keyrow->first_attribute(longpress); + if (attr) { + const char* keyinfo = attr->value(); + + if (strlen(keyinfo) == 0) { + LOGERR("No long press info on layout%i, row%i, long%dd.\n", layoutindex, rowindex, keyindex); + return; + } + + if (ParseKey(keyinfo, lay.keys[rowindex - 1][keyindex - 1], Xindex, keyWidth, true)) + LOGERR("Invalid long press key info on layout%i, row%i, long%02i.\n", layoutindex, rowindex, keyindex); + } + keyindex++; + sprintf(key, "key%02i", keyindex); + attr = keyrow->first_attribute(key); + } + rowindex++; + row[3] = (char)(rowindex + 48); + keyrow = keylayout->first_node(row); + } + layoutindex++; + layout[6] = (char)(layoutindex + 48); + keylayout = FindNode(node, layout); + } + + int x, y; + // Load the placement + LoadPlacement(FindNode(node, "placement"), &x, &y, &mRenderW, &mRenderH); + SetRenderPos(x, y, mRenderW, mRenderH); + return; +} + +GUIKeyboard::~GUIKeyboard() +{ +} + +int GUIKeyboard::ParseKey(const char* keyinfo, Key& key, int& Xindex, int keyWidth, bool longpress) +{ + key.layout = 0; + int keychar = 0; + if (strlen(keyinfo) == 1) { + // This is a single key, simple definition + keychar = keyinfo[0]; + } else { + // This key has extra data: {keywidth}:{what_the_key_does} + keyWidth = scale_theme_x(atoi(keyinfo)); + + const char* ptr = keyinfo; + while (*ptr > 32 && *ptr != ':') + ptr++; + if (*ptr != ':') + return -1; // no colon is an error + ptr++; + + if (*ptr == 0) { // This is an empty area + keychar = 0; + } else if (strlen(ptr) == 1) { // This is the character that this key uses + keychar = *ptr; + } else if (*ptr == 'c') { // This is an ASCII character code: "c:{number}" + keychar = atoi(ptr + 2); + } else if (*ptr == 'l') { // This is a different layout: "layout{number}" + keychar = KEYBOARD_LAYOUT; + key.layout = atoi(ptr + 6); + } else if (*ptr == 'a') { // This is an action: "action" + keychar = KEYBOARD_ACTION; + } else + return -1; + } + + if (longpress) { + key.longpresskey = keychar; + } else { + key.key = keychar; + Xindex += keyWidth; + key.end_x = Xindex - 1; + } + + return 0; +} + +void GUIKeyboard::LoadKeyLabels(xml_node<>* parent, int layout) +{ + for (xml_node<>* child = parent->first_node(); child; child = child->next_sibling()) { + std::string name = child->name(); + if (name == "keylabel") { + std::string keydef = LoadAttrString(child, "key", ""); + Key tempkey; + int dummyX; + if (ParseKey(keydef.c_str(), tempkey, dummyX, 0, false) == 0) { + KeyLabel keylabel; + keylabel.key = tempkey.key; + keylabel.layout_from = layout; + keylabel.layout_to = tempkey.layout; + keylabel.text = LoadAttrString(child, "text", ""); + keylabel.image = LoadAttrImage(child, "resource"); + mKeyLabels.push_back(keylabel); + } else { + LOGERR("Ignoring invalid keylabel in layout %d: '%s'.\n", layout, keydef.c_str()); + } + } + } +} + +void GUIKeyboard::DrawKey(Key& key, int keyX, int keyY, int keyW, int keyH) +{ + unsigned char keychar = key.key; + if (!keychar) + return; + + // key background + COLOR& c = (keychar >= 32 && keychar < 127) ? mKeyColorAlphanumeric : mKeyColorOther; + gr_color(c.red, c.green, c.blue, c.alpha); + keyX += mKeyMarginX; + keyY += mKeyMarginY; + keyW -= mKeyMarginX * 2; + keyH -= mKeyMarginY * 2; + gr_fill(keyX, keyY, keyW, keyH); + + // key label + FontResource* labelFont = mFont; + string labelText; + ImageResource* labelImage = NULL; + if (keychar > 32 && keychar < 127) { + labelText = (char) keychar; + gr_color(mFontColor.red, mFontColor.green, mFontColor.blue, mFontColor.alpha); + } + else { + // search for a special key label + for (std::vector<KeyLabel>::iterator it = mKeyLabels.begin(); it != mKeyLabels.end(); ++it) { + if (it->layout_from > 0 && it->layout_from != currentLayout) + continue; // this label is for another layout + if (it->key == key.key && it->layout_to == key.layout) + { + // found a label + labelText = it->text; + labelImage = it->image; + break; + } + } + labelFont = mSmallFont; + gr_color(mFontColorSmall.red, mFontColorSmall.green, mFontColorSmall.blue, mFontColorSmall.alpha); + } + + if (labelImage) + { + int w = labelImage->GetWidth(); + int h = labelImage->GetHeight(); + int x = keyX + (keyW - w) / 2; + int y = keyY + (keyH - h) / 2; + gr_blit(labelImage->GetResource(), 0, 0, w, h, x, y); + } + else if (!labelText.empty()) + { + void* fontResource = labelFont->GetResource(); + int textW = gr_measureEx(labelText.c_str(), fontResource); + int textH = labelFont->GetHeight(); + int textX = keyX + (keyW - textW) / 2; + int textY = keyY + (keyH - textH) / 2; + gr_textEx(textX, textY, labelText.c_str(), fontResource); + } + + // longpress key label (only if font is defined) + keychar = key.longpresskey; + if (keychar > 32 && keychar < 127 && mLongpressFont->GetResource()) { + void* fontResource = mLongpressFont->GetResource(); + gr_color(mLongpressFontColor.red, mLongpressFontColor.green, mLongpressFontColor.blue, mLongpressFontColor.alpha); + string text(1, keychar); + int textH = mLongpressFont->GetHeight(); + int textW = gr_measureEx(text.c_str(), fontResource); + int textX = keyX + keyW - longpressOffsetX - textW; + int textY = keyY + longpressOffsetY; + gr_textEx(textX, textY, text.c_str(), fontResource); + } +} + +int GUIKeyboard::Render(void) +{ + if (!isConditionTrue()) + { + mRendered = false; + return 0; + } + + Layout& lay = layouts[currentLayout - 1]; + + bool drawKeys = false; + if (lay.keyboardImg && lay.keyboardImg->GetResource()) + // keyboard is image based + gr_blit(lay.keyboardImg->GetResource(), 0, 0, mRenderW, mRenderH, mRenderX, mRenderY); + else { + // keyboard is software drawn + // fill background + gr_color(mBackgroundColor.red, mBackgroundColor.green, mBackgroundColor.blue, mBackgroundColor.alpha); + gr_fill(mRenderX, mRenderY, mRenderW, mRenderH); + drawKeys = true; + } + + // draw keys + int y1 = 0; + for (int row = 0; row < MAX_KEYBOARD_ROWS; ++row) { + int rowY = mRenderY + y1; + int rowH = lay.row_end_y[row] - y1; + y1 = lay.row_end_y[row]; + int x1 = 0; + for (int col = 0; col < MAX_KEYBOARD_KEYS; ++col) { + Key& key = lay.keys[row][col]; + int keyY = rowY; + int keyH = rowH; + int keyX = mRenderX + x1; + int keyW = key.end_x - x1; + x1 = key.end_x; + + // Draw key for software drawn keyboard + if (drawKeys) + DrawKey(key, keyX, keyY, keyW, keyH); + + // Draw highlight for capslock + if (hasCapsHighlight && lay.is_caps && CapsLockOn && (int)key.key == KEYBOARD_LAYOUT && key.layout == lay.revert_layout) { + gr_color(mCapsHighlightColor.red, mCapsHighlightColor.green, mCapsHighlightColor.blue, mCapsHighlightColor.alpha); + gr_fill(keyX, keyY, keyW, keyH); + } + + // Highlight current key + if (hasHighlight && &key == currentKey && highlightRenderCount != 0) { + gr_color(mHighlightColor.red, mHighlightColor.green, mHighlightColor.blue, mHighlightColor.alpha); + gr_fill(keyX, keyY, keyW, keyH); + } + } + } + + if (!hasHighlight || highlightRenderCount == 0) + mRendered = true; + else if (highlightRenderCount > 0) + highlightRenderCount--; + return 0; +} + +int GUIKeyboard::Update(void) +{ + if (!isConditionTrue()) return (mRendered ? 2 : 0); + if (!mRendered) return 2; + + return 0; +} + +int GUIKeyboard::SetRenderPos(int x, int y, int w, int h) +{ + RenderObject::SetRenderPos(x, y, w, h); + SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH); + return 0; +} + +GUIKeyboard::Key* GUIKeyboard::HitTestKey(int x, int y) +{ + if (!IsInRegion(x, y)) + return NULL; + + int rely = y - mRenderY; + int relx = x - mRenderX; + + Layout& lay = layouts[currentLayout - 1]; + + // Find the correct row + int row; + for (row = 0; row < MAX_KEYBOARD_ROWS; ++row) { + if (lay.row_end_y[row] > rely) + break; + } + if (row == MAX_KEYBOARD_ROWS) + return NULL; + + // Find the correct key (column) + int col; + int x1 = 0; + for (col = 0; col < MAX_KEYBOARD_KEYS; ++col) { + Key& key = lay.keys[row][col]; + if (x1 <= relx && relx < key.end_x && key.key != 0) { + // This is the key that was pressed! + return &key; + } + x1 = key.end_x; + } + return NULL; +} + +int GUIKeyboard::NotifyTouch(TOUCH_STATE state, int x, int y) +{ + static int was_held = 0, startX = 0; + + if (!isConditionTrue()) return -1; + + switch (state) + { + case TOUCH_START: + was_held = 0; + startX = x; + currentKey = HitTestKey(x, y); + if (currentKey) + highlightRenderCount = -1; + else + highlightRenderCount = 0; + mRendered = false; + break; + + case TOUCH_DRAG: + break; + + case TOUCH_RELEASE: + if (x < startX - (mRenderW * 0.5)) { + if (highlightRenderCount != 0) { + highlightRenderCount = 0; + mRendered = false; + } + PageManager::NotifyKeyboard(KEYBOARD_SWIPE_LEFT); + return 0; + } else if (x > startX + (mRenderW * 0.5)) { + if (highlightRenderCount != 0) { + highlightRenderCount = 0; + mRendered = false; + } + PageManager::NotifyKeyboard(KEYBOARD_SWIPE_RIGHT); + return 0; + } + // fall through + case TOUCH_HOLD: + case TOUCH_REPEAT: + if (!currentKey) { + if (highlightRenderCount != 0) { + highlightRenderCount = 0; + mRendered = false; + } + return 0; + } + + if (highlightRenderCount != 0) { + if (state == TOUCH_RELEASE) + highlightRenderCount = 2; + else + highlightRenderCount = -1; + mRendered = false; + } + + if (HitTestKey(x, y) != currentKey) { + // We dragged off of the starting key + currentKey = NULL; + if (highlightRenderCount != 0) { + highlightRenderCount = 0; + mRendered = false; + } + return 0; + } else { + Key& key = *currentKey; + Layout& lay = layouts[currentLayout - 1]; + if (state == TOUCH_RELEASE && was_held == 0) { + DataManager::Vibrate("tw_keyboard_vibrate"); + if ((int)key.key == KEYBOARD_LAYOUT) { + // Switch layouts + if (lay.is_caps && key.layout == lay.revert_layout && !CapsLockOn) { + CapsLockOn = true; // Set the caps lock + } else { + CapsLockOn = false; // Unset the caps lock and change layouts + currentLayout = key.layout; + } + mRendered = false; + } else if ((int)key.key == KEYBOARD_ACTION) { + // Action + highlightRenderCount = 0; + // Send action notification + PageManager::NotifyKeyboard(key.key); + } else if ((int)key.key < KEYBOARD_SPECIAL_KEYS && (int)key.key > 0) { + // Regular key + PageManager::NotifyKeyboard(key.key); + if (!CapsLockOn && lay.is_caps) { + // caps lock was not set, change layouts + currentLayout = lay.revert_layout; + mRendered = false; + } + } + } else if (state == TOUCH_HOLD) { + was_held = 1; + if ((int)key.key == KEYBOARD_BACKSPACE) { + // Repeat backspace + PageManager::NotifyKeyboard(key.key); + } else if ((int)key.longpresskey < KEYBOARD_SPECIAL_KEYS && (int)key.longpresskey > 0) { + // Long Press Key + DataManager::Vibrate("tw_keyboard_vibrate"); + PageManager::NotifyKeyboard(key.longpresskey); + } + } else if (state == TOUCH_REPEAT) { + was_held = 1; + if ((int)key.key == KEYBOARD_BACKSPACE) { + // Repeat backspace + PageManager::NotifyKeyboard(key.key); + } + } + } + break; + } + + return 0; +} diff --git a/gui/listbox.cpp b/gui/listbox.cpp new file mode 100644 index 000000000..4c9a68ac8 --- /dev/null +++ b/gui/listbox.cpp @@ -0,0 +1,176 @@ +/* + Copyright 2013 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <string.h> +#include <sys/stat.h> +#include <dirent.h> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" +#include "../data.hpp" + +GUIListBox::GUIListBox(xml_node<>* node) : GUIScrollList(node) +{ + xml_attribute<>* attr; + xml_node<>* child; + mIconSelected = mIconUnselected = NULL; + mUpdate = 0; + + // Get the icons, if any + child = FindNode(node, "icon"); + if (child) { + mIconSelected = LoadAttrImage(child, "selected"); + mIconUnselected = LoadAttrImage(child, "unselected"); + } + int iconWidth = std::max(mIconSelected->GetWidth(), mIconUnselected->GetWidth()); + int iconHeight = std::max(mIconSelected->GetHeight(), mIconUnselected->GetHeight()); + SetMaxIconSize(iconWidth, iconHeight); + + // Handle the result variable + child = FindNode(node, "data"); + if (child) { + attr = child->first_attribute("name"); + if (attr) + mVariable = attr->value(); + attr = child->first_attribute("default"); + if (attr) + DataManager::SetValue(mVariable, attr->value()); + // Get the currently selected value for the list + DataManager::GetValue(mVariable, currentValue); + } + else + allowSelection = false; // allows using listbox as a read-only list + + // Get the data for the list + child = FindNode(node, "listitem"); + if (!child) return; + while (child) { + ListData data; + + attr = child->first_attribute("name"); + if (!attr) + continue; + data.displayName = gui_parse_text(attr->value()); + data.variableValue = gui_parse_text(child->value()); + if (child->value() == currentValue) { + data.selected = 1; + } else { + data.selected = 0; + } + data.action = NULL; + xml_node<>* action = child->first_node("action"); + if (action) { + data.action = new GUIAction(action); + allowSelection = true; + } + + mList.push_back(data); + + child = child->next_sibling("listitem"); + } +} + +GUIListBox::~GUIListBox() +{ +} + +int GUIListBox::Update(void) +{ + if(!isConditionTrue()) + return 0; + + GUIScrollList::Update(); + + if (mUpdate) { + mUpdate = 0; + if (Render() == 0) + return 2; + } + return 0; +} + +int GUIListBox::NotifyVarChange(const std::string& varName, const std::string& value) +{ + GUIScrollList::NotifyVarChange(varName, value); + + if(!isConditionTrue()) + return 0; + + // Check to see if the variable that we are using to store the list selected value has been updated + if (varName == mVariable) { + int i, listSize = mList.size(); + + currentValue = value; + + for (i = 0; i < listSize; i++) { + if (mList.at(i).variableValue == currentValue) { + mList.at(i).selected = 1; + SetVisibleListLocation(i); + } else + mList.at(i).selected = 0; + } + mUpdate = 1; + return 0; + } + return 0; +} + +void GUIListBox::SetPageFocus(int inFocus) +{ + GUIScrollList::SetPageFocus(inFocus); + if (inFocus) { + DataManager::GetValue(mVariable, currentValue); + NotifyVarChange(mVariable, currentValue); + } +} + +size_t GUIListBox::GetItemCount() +{ + return mList.size(); +} + +void GUIListBox::RenderItem(size_t itemindex, int yPos, bool selected) +{ + // note: the "selected" parameter above is for the currently touched item + // don't confuse it with the more persistent "selected" flag per list item used below + ImageResource* icon = mList.at(itemindex).selected ? mIconSelected : mIconUnselected; + const std::string& text = mList.at(itemindex).displayName; + + RenderStdItem(yPos, selected, icon, text.c_str()); +} + +void GUIListBox::NotifySelect(size_t item_selected) +{ + for (size_t i = 0; i < mList.size(); i++) { + mList.at(i).selected = 0; + } + if (item_selected < mList.size()) { + ListData& data = mList.at(item_selected); + data.selected = 1; + string str = data.variableValue; // [check] should this set currentValue instead? + DataManager::SetValue(mVariable, str); + if (data.action) + data.action->doActions(); + } + mUpdate = 1; +} diff --git a/gui/mousecursor.cpp b/gui/mousecursor.cpp new file mode 100644 index 000000000..84e6322a4 --- /dev/null +++ b/gui/mousecursor.cpp @@ -0,0 +1,147 @@ +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" + +MouseCursor::MouseCursor(int resX, int resY) +{ + ResetData(resX, resY); +} + +MouseCursor::~MouseCursor() +{ +} + +void MouseCursor::ResetData(int resX, int resY) +{ + m_resX = resX; + m_resY = resY; + m_moved = false; + m_speedMultiplier = 2.5f; + m_image = NULL; + m_present = false; + + ConvertStrToColor("red", &m_color); + + SetRenderPos(resX/2, resY/2, 10, 10); +} + +void MouseCursor::LoadData(xml_node<>* node) +{ + xml_attribute<>* attr; + xml_node<>* child; + + child = FindNode(node, "placement"); + if(child) + LoadPlacement(child, &mRenderX, &mRenderY, &mRenderW, &mRenderH); + + child = FindNode(node, "background"); + if(child) + { + m_color = LoadAttrColor(child, "color", m_color); + m_image = LoadAttrImage(child, "resource"); + if(m_image) + { + mRenderW = m_image->GetWidth(); + mRenderH = m_image->GetHeight(); + } + } + + child = FindNode(node, "speed"); + if(child) + { + attr = child->first_attribute("multiplier"); + if(attr) + m_speedMultiplier = atof(attr->value()); + } +} + +int MouseCursor::Render(void) +{ + if(!m_present) + return 0; + + if(m_image) + { + gr_blit(m_image->GetResource(), 0, 0, mRenderW, mRenderH, mRenderX, mRenderY); + } + else + { + gr_color(m_color.red, m_color.green, m_color.blue, m_color.alpha); + gr_fill(mRenderX, mRenderY, mRenderW, mRenderH); + } + return 0; +} + +int MouseCursor::Update(void) +{ + if(m_present != ev_has_mouse()) + { + m_present = ev_has_mouse(); + if(m_present) + SetRenderPos(m_resX/2, m_resY/2); + return 2; + } + + if(m_present && m_moved) + { + m_moved = false; + return 2; + } + return 0; +} + +int MouseCursor::SetRenderPos(int x, int y, int w, int h) +{ + if(x == mRenderX && y == mRenderY) + m_moved = true; + + return RenderObject::SetRenderPos(x, y, w, h); +} + +void MouseCursor::Move(int deltaX, int deltaY) +{ + if(deltaX != 0) + { + mRenderX += deltaX*m_speedMultiplier; + mRenderX = (std::min)(mRenderX, m_resX); + mRenderX = (std::max)(mRenderX, 0); + + m_moved = true; + } + + if(deltaY != 0) + { + mRenderY += deltaY*m_speedMultiplier; + mRenderY = (std::min)(mRenderY, m_resY); + mRenderY = (std::max)(mRenderY, 0); + + m_moved = true; + } +} + +void MouseCursor::GetPos(int& x, int& y) +{ + x = mRenderX; + y = mRenderY; +} diff --git a/gui/object.cpp b/gui/object.cpp new file mode 100644 index 000000000..7cce5db8b --- /dev/null +++ b/gui/object.cpp @@ -0,0 +1,210 @@ +// checkbox.cpp - GUICheckbox object + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +#include "../variables.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" +#include "../data.hpp" + +GUIObject::GUIObject(xml_node<>* node) +{ + mConditionsResult = true; + + // Break out early, it's too hard to check if valid every step + if (!node) return; + + // First, get the action + xml_node<>* condition = FindNode(node, "conditions"); + if (condition) condition = FindNode(condition, "condition"); + else condition = FindNode(node, "condition"); + + if (!condition) return; + + while (condition) + { + Condition cond; + + cond.mCompareOp = "="; + + xml_attribute<>* attr; + attr = condition->first_attribute("var1"); + if (attr) cond.mVar1 = attr->value(); + + attr = condition->first_attribute("op"); + if (attr) cond.mCompareOp = attr->value(); + + attr = condition->first_attribute("var2"); + if (attr) cond.mVar2 = attr->value(); + + mConditions.push_back(cond); + + condition = condition->next_sibling("condition"); + } +} + +GUIObject::~GUIObject() +{ +} + +bool GUIObject::IsConditionVariable(std::string var) +{ + std::vector<Condition>::iterator iter; + for (iter = mConditions.begin(); iter != mConditions.end(); iter++) + { + if (iter->mVar1 == var) + return true; + } + return false; +} + +bool GUIObject::isConditionTrue() +{ + return mConditionsResult; +} + +bool GUIObject::isConditionTrue(Condition* condition) +{ + // This is used to hold the proper value of "true" based on the '!' NOT flag + bool bTrue = true; + + if (condition->mVar1.empty()) + return bTrue; + + if (!condition->mCompareOp.empty() && condition->mCompareOp[0] == '!') + bTrue = false; + + if (condition->mVar2.empty() && condition->mCompareOp != "modified") + { + if (!DataManager::GetStrValue(condition->mVar1).empty()) + return bTrue; + + return !bTrue; + } + + string var1, var2; + if (DataManager::GetValue(condition->mVar1, var1)) + var1 = condition->mVar1; + if (DataManager::GetValue(condition->mVar2, var2)) + var2 = condition->mVar2; + + // This is a special case, we stat the file and that determines our result + if (var1 == "fileexists") + { + struct stat st; + if (stat(var2.c_str(), &st) == 0) + var2 = var1; + else + var2 = "FAILED"; + } + if (var1 == "mounted") + { + if (isMounted(condition->mVar2)) + var2 = var1; + else + var2 = "FAILED"; + } + + if (condition->mCompareOp.find('=') != string::npos && var1 == var2) + return bTrue; + + if (condition->mCompareOp.find('>') != string::npos && (atof(var1.c_str()) > atof(var2.c_str()))) + return bTrue; + + if (condition->mCompareOp.find('<') != string::npos && (atof(var1.c_str()) < atof(var2.c_str()))) + return bTrue; + + if (condition->mCompareOp == "modified") + { + // This is a hack to allow areas to reset the default value + if (var1.empty()) + { + condition->mLastVal = var1; + return !bTrue; + } + + if (var1 != condition->mLastVal) + return bTrue; + } + + return !bTrue; +} + +bool GUIObject::isConditionValid() +{ + return !mConditions.empty(); +} + +int GUIObject::NotifyVarChange(const std::string& varName, const std::string& value) +{ + mConditionsResult = true; + + const bool varNameEmpty = varName.empty(); + std::vector<Condition>::iterator iter; + for (iter = mConditions.begin(); iter != mConditions.end(); ++iter) + { + if(varNameEmpty && iter->mCompareOp == "modified") + { + string val; + + // If this fails, val will not be set, which is perfect + if (DataManager::GetValue(iter->mVar1, val)) + { + DataManager::SetValue(iter->mVar1, ""); + DataManager::GetValue(iter->mVar1, val); + } + iter->mLastVal = val; + } + + if(varNameEmpty || iter->mVar1 == varName || iter->mVar2 == varName) + iter->mLastResult = isConditionTrue(&(*iter)); + + if(!iter->mLastResult) + mConditionsResult = false; + } + return 0; +} + +bool GUIObject::isMounted(string vol) +{ + FILE *fp; + char tmpOutput[255]; + + fp = fopen("/proc/mounts", "rt"); + while (fgets(tmpOutput,255,fp) != NULL) + { + char* mnt = tmpOutput; + while (*mnt > 32) mnt++; + while (*mnt > 0 && *mnt <= 32) mnt++; + char* pos = mnt; + while (*pos > 32) pos++; + *pos = 0; + if (vol == mnt) + { + fclose(fp); + return true; + } + } + fclose(fp); + return false; +} diff --git a/gui/objects.hpp b/gui/objects.hpp new file mode 100644 index 000000000..f8569d6ea --- /dev/null +++ b/gui/objects.hpp @@ -0,0 +1,1157 @@ +/* + Copyright 2013 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see <http://www.gnu.org/licenses/>. +*/ + +// objects.hpp - Base classes for object manager of GUI + +#ifndef _OBJECTS_HEADER +#define _OBJECTS_HEADER + +#include "rapidxml.hpp" +#include <vector> +#include <string> +#include <map> +#include <set> +#include <time.h> + +using namespace rapidxml; + +#include "../data.hpp" +#include "resources.hpp" +#include "pages.hpp" +#include "../partitions.hpp" + +#ifndef TW_X_OFFSET +#define TW_X_OFFSET 0 +#endif +#ifndef TW_Y_OFFSET +#define TW_Y_OFFSET 0 +#endif + +class RenderObject +{ +public: + enum Placement { + TOP_LEFT = 0, + TOP_RIGHT = 1, + BOTTOM_LEFT = 2, + BOTTOM_RIGHT = 3, + CENTER = 4, + CENTER_X_ONLY = 5, + }; + +public: + RenderObject() { mRenderX = 0; mRenderY = 0; mRenderW = 0; mRenderH = 0; mPlacement = TOP_LEFT; } + virtual ~RenderObject() {} + +public: + // Render - Render the full object to the GL surface + // Return 0 on success, <0 on error + virtual int Render(void) = 0; + + // Update - Update any UI component animations (called <= 30 FPS) + // Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error + virtual int Update(void) { return 0; } + + // GetRenderPos - Returns the current position of the object + virtual int GetRenderPos(int& x, int& y, int& w, int& h) { x = mRenderX; y = mRenderY; w = mRenderW; h = mRenderH; return 0; } + + // SetRenderPos - Update the position of the object + // Return 0 on success, <0 on error + virtual int SetRenderPos(int x, int y, int w = 0, int h = 0) { mRenderX = x; mRenderY = y; if (w || h) { mRenderW = w; mRenderH = h; } return 0; } + + // GetPlacement - Returns the current placement + virtual int GetPlacement(Placement& placement) { placement = mPlacement; return 0; } + + // SetPlacement - Update the current placement + virtual int SetPlacement(Placement placement) { mPlacement = placement; return 0; } + + // SetPageFocus - Notify when a page gains or loses focus + virtual void SetPageFocus(int inFocus) { return; } + +protected: + int mRenderX, mRenderY, mRenderW, mRenderH; + Placement mPlacement; +}; + +class ActionObject +{ +public: + ActionObject() { mActionX = 0; mActionY = 0; mActionW = 0; mActionH = 0; } + virtual ~ActionObject() {} + +public: + // NotifyTouch - Notify of a touch event + // Return 0 on success, >0 to ignore remainder of touch, and <0 on error + virtual int NotifyTouch(TOUCH_STATE state, int x, int y) { return 0; } + + // 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, 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; } + + // SetRenderPos - Update the position of the object + // Return 0 on success, <0 on error + virtual int SetActionPos(int x, int y, int w = 0, int h = 0); + + // IsInRegion - Checks if the request is handled by this object + // Return 1 if this object handles the request, 0 if not + virtual int IsInRegion(int x, int y) { return ((x < mActionX || x >= mActionX + mActionW || y < mActionY || y >= mActionY + mActionH) ? 0 : 1); } + +protected: + int mActionX, mActionY, mActionW, mActionH; +}; + +class GUIObject +{ +public: + GUIObject(xml_node<>* node); + virtual ~GUIObject(); + +public: + bool IsConditionVariable(std::string var); + bool isConditionTrue(); + bool isConditionValid(); + + // NotifyVarChange - Notify of a variable change + // Returns 0 on success, <0 on error + virtual int NotifyVarChange(const std::string& varName, const std::string& value); + +protected: + class Condition + { + public: + Condition() { + mLastResult = true; + } + + std::string mVar1; + std::string mVar2; + std::string mCompareOp; + std::string mLastVal; + bool mLastResult; + }; + + std::vector<Condition> mConditions; + +protected: + bool isMounted(std::string vol); + bool isConditionTrue(Condition* condition); + + bool mConditionsResult; +}; + +class InputObject +{ +public: + InputObject() { HasInputFocus = 0; } + virtual ~InputObject() {} + +public: + // NotifyKeyboard - Notify of keyboard input + // Return 0 on success (and consume key), >0 to pass key to next handler, and <0 on error + virtual int NotifyKeyboard(int key) { return 1; } + + virtual int SetInputFocus(int focus) { HasInputFocus = focus; return 1; } + +protected: + int HasInputFocus; +}; + +// Derived Objects +// GUIText - Used for static text +class GUIText : public GUIObject, public RenderObject, public ActionObject +{ +public: + // w and h may be ignored, in which case, no bounding box is applied + GUIText(xml_node<>* node); + +public: + // Render - Render the full object to the GL surface + // Return 0 on success, <0 on error + virtual int Render(void); + + // Update - Update any UI component animations (called <= 30 FPS) + // Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error + virtual int Update(void); + + // Retrieve the size of the current string (dynamic strings may change per call) + virtual int GetCurrentBounds(int& w, int& h); + + // Notify of a variable change + virtual int NotifyVarChange(const std::string& varName, const std::string& value); + + // Set maximum width in pixels + virtual int SetMaxWidth(unsigned width); + + // Set number of characters to skip (for scrolling) + virtual int SkipCharCount(unsigned skip); + +public: + bool isHighlighted; + +protected: + std::string mText; + std::string mLastValue; + COLOR mColor; + COLOR mHighlightColor; + FontResource* mFont; + int mIsStatic; + int mVarChanged; + int mFontHeight; + unsigned maxWidth; + unsigned charSkip; +}; + +// GUIImage - Used for static image +class GUIImage : public GUIObject, public RenderObject +{ +public: + GUIImage(xml_node<>* node); + +public: + // Render - Render the full object to the GL surface + // Return 0 on success, <0 on error + virtual int Render(void); + + // SetRenderPos - Update the position of the object + // Return 0 on success, <0 on error + virtual int SetRenderPos(int x, int y, int w = 0, int h = 0); + +public: + bool isHighlighted; + +protected: + ImageResource* mImage; + ImageResource* mHighlightImage; +}; + +// GUIFill - Used for fill colors +class GUIFill : public GUIObject, public RenderObject +{ +public: + GUIFill(xml_node<>* node); + +public: + // Render - Render the full object to the GL surface + // Return 0 on success, <0 on error + virtual int Render(void); + +protected: + COLOR mColor; +}; + +// GUIAction - Used for standard actions +class GUIAction : public GUIObject, public ActionObject +{ + friend class ActionThread; + +public: + GUIAction(xml_node<>* node); + +public: + virtual int NotifyTouch(TOUCH_STATE state, int x, int y); + virtual int NotifyKey(int key, bool down); + virtual int NotifyVarChange(const std::string& varName, const std::string& value); + + int doActions(); + +protected: + class Action + { + public: + std::string mFunction; + std::string mArg; + }; + + std::vector<Action> mActions; + std::map<int, bool> mKeys; + +protected: + enum ThreadType { THREAD_NONE, THREAD_ACTION, THREAD_CANCEL }; + + int getKeyByName(std::string key); + int doAction(Action action); + ThreadType getThreadType(const Action& action); + void simulate_progress_bar(void); + int flash_zip(std::string filename, int* wipe_cache); + void reinject_after_flash(); + void operation_start(const string operation_name); + void operation_end(const int operation_status); + time_t Start; + + // map action name to function pointer + typedef int (GUIAction::*execFunction)(std::string); + typedef std::map<std::string, execFunction> mapFunc; + static mapFunc mf; + static std::set<std::string> setActionsRunningInCallerThread; + + // GUI actions + int reboot(std::string arg); + int home(std::string arg); + int key(std::string arg); + int page(std::string arg); + int reload(std::string arg); + int readBackup(std::string arg); + int set(std::string arg); + int clear(std::string arg); + int mount(std::string arg); + int unmount(std::string arg); + int restoredefaultsettings(std::string arg); + int copylog(std::string arg); + int compute(std::string arg); + int setguitimezone(std::string arg); + int overlay(std::string arg); + int queuezip(std::string arg); + int cancelzip(std::string arg); + int queueclear(std::string arg); + int sleep(std::string arg); + int appenddatetobackupname(std::string arg); + int generatebackupname(std::string arg); + int checkpartitionlist(std::string arg); + int getpartitiondetails(std::string arg); + int screenshot(std::string arg); + int setbrightness(std::string arg); + + // (originally) threaded actions + int fileexists(std::string arg); + int flash(std::string arg); + int wipe(std::string arg); + int refreshsizes(std::string arg); + int nandroid(std::string arg); + int fixpermissions(std::string arg); + int dd(std::string arg); + int partitionsd(std::string arg); + int installhtcdumlock(std::string arg); + int htcdumlockrestoreboot(std::string arg); + int htcdumlockreflashrecovery(std::string arg); + int cmd(std::string arg); + int terminalcommand(std::string arg); + int killterminal(std::string arg); + int reinjecttwrp(std::string arg); + int checkbackupname(std::string arg); + int decrypt(std::string arg); + int adbsideload(std::string arg); + int adbsideloadcancel(std::string arg); + int openrecoveryscript(std::string arg); + int installsu(std::string arg); + int fixsu(std::string arg); + int decrypt_backup(std::string arg); + int repair(std::string arg); + int resize(std::string arg); + int changefilesystem(std::string arg); + int startmtp(std::string arg); + int stopmtp(std::string arg); + int flashimage(std::string arg); + int cancelbackup(std::string arg); + int checkpartitionlifetimewrites(std::string arg); + int mountsystemtoggle(std::string arg); + + int simulate; +}; + +class GUIButton : public GUIObject, public RenderObject, public ActionObject +{ +public: + GUIButton(xml_node<>* node); + virtual ~GUIButton(); + +public: + // Render - Render the full object to the GL surface + // Return 0 on success, <0 on error + virtual int Render(void); + + // Update - Update any UI component animations (called <= 30 FPS) + // Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error + virtual int Update(void); + + // SetPos - Update the position of the render object + // Return 0 on success, <0 on error + virtual int SetRenderPos(int x, int y, int w = 0, int h = 0); + + // NotifyTouch - Notify of a touch event + // Return 0 on success, >0 to ignore remainder of touch, and <0 on error + virtual int NotifyTouch(TOUCH_STATE state, int x, int y); + +protected: + GUIImage* mButtonImg; + ImageResource* mButtonIcon; + GUIText* mButtonLabel; + GUIAction* mAction; + int mTextX, mTextY, mTextW, mTextH; + int mIconX, mIconY, mIconW, mIconH; + bool mRendered; + bool hasHighlightColor; + bool renderHighlight; + bool hasFill; + COLOR mFillColor; + COLOR mHighlightColor; + Placement TextPlacement; +}; + +class GUICheckbox: public GUIObject, public RenderObject, public ActionObject +{ +public: + GUICheckbox(xml_node<>* node); + virtual ~GUICheckbox(); + +public: + // Render - Render the full object to the GL surface + // Return 0 on success, <0 on error + virtual int Render(void); + + // Update - Update any UI component animations (called <= 30 FPS) + // Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error + virtual int Update(void); + + // SetPos - Update the position of the render object + // Return 0 on success, <0 on error + virtual int SetRenderPos(int x, int y, int w = 0, int h = 0); + + // NotifyTouch - Notify of a touch event + // Return 0 on success, >0 to ignore remainder of touch, and <0 on error + virtual int NotifyTouch(TOUCH_STATE state, int x, int y); + +protected: + ImageResource* mChecked; + ImageResource* mUnchecked; + GUIText* mLabel; + int mTextX, mTextY; + int mCheckX, mCheckY, mCheckW, mCheckH; + int mLastState; + bool mRendered; + std::string mVarName; +}; + +class GUIScrollList : public GUIObject, public RenderObject, public ActionObject +{ +public: + GUIScrollList(xml_node<>* node); + virtual ~GUIScrollList(); + +public: + // Render - Render the full object to the GL surface + // Return 0 on success, <0 on error + virtual int Render(void); + + // Update - Update any UI component animations (called <= 30 FPS) + // Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error + virtual int Update(void); + + // NotifyTouch - Notify of a touch event + // Return 0 on success, >0 to ignore remainder of touch, and <0 on error + virtual int NotifyTouch(TOUCH_STATE state, int x, int y); + + // NotifyVarChange - Notify of a variable change + virtual int NotifyVarChange(const std::string& varName, const std::string& value); + + // SetPos - Update the position of the render object + // Return 0 on success, <0 on error + virtual int SetRenderPos(int x, int y, int w = 0, int h = 0); + + // SetPageFocus - Notify when a page gains or loses focus + virtual void SetPageFocus(int inFocus); + +protected: + // derived classes need to implement these + // get number of items + virtual size_t GetItemCount() { return 0; } + // render a single item in rect (mRenderX, yPos, mRenderW, actualItemHeight) + virtual void RenderItem(size_t itemindex, int yPos, bool selected); + // an item was selected + virtual void NotifySelect(size_t item_selected) {} + + // render a standard-layout list item with optional icon and text + void RenderStdItem(int yPos, bool selected, ImageResource* icon, const char* text, int iconAndTextH = 0); + + enum { NO_ITEM = (size_t)-1 }; + // returns item index at coordinates or NO_ITEM if there is no item there + size_t HitTestItem(int x, int y); + + // Called by the derived class to set the max icon size so we can calculate the proper actualItemHeight and center smaller icons if the icon size varies + void SetMaxIconSize(int w, int h); + + // This will make sure that the item indicated by list_index is visible on the screen + void SetVisibleListLocation(size_t list_index); + + // Handle scrolling changes for drags and kinetic scrolling + void HandleScrolling(); + + // Returns many full rows the list is capable of displaying + int GetDisplayItemCount(); + + // Returns the size in pixels of a partial item or row size + int GetDisplayRemainder(); + +protected: + // Background + COLOR mBackgroundColor; + ImageResource* mBackground; // background image, if any, automatically centered + + // Header + COLOR mHeaderBackgroundColor; + COLOR mHeaderFontColor; + std::string mHeaderText; // Original header text without parsing any variables + std::string mLastHeaderValue; // Header text after parsing variables + bool mHeaderIsStatic; // indicates if the header is static (no need to check for changes in NotifyVarChange) + int mHeaderH; // actual header height including font, icon, padding, and separator heights + ImageResource* mHeaderIcon; + int mHeaderIconHeight, mHeaderIconWidth; // width and height of the header icon if present + int mHeaderSeparatorH; // Height of the separator between header and list items + COLOR mHeaderSeparatorColor; // color of the header separator + + // Per-item layout + FontResource* mFont; + COLOR mFontColor; + bool hasHighlightColor; // indicates if a highlight color was set + COLOR mHighlightColor; // background row highlight color + COLOR mFontHighlightColor; + int mFontHeight; + int actualItemHeight; // Actual height of each item in pixels including max icon size, font size, and padding + int maxIconWidth, maxIconHeight; // max icon width and height for the list, set by derived class in SetMaxIconSize + int mItemSpacing; // stores the spacing or padding on the y axis, part of the actualItemHeight + int mSeparatorH; // Height of the separator between items + COLOR mSeparatorColor; // color of the separator that is between items + + // Scrollbar + int mFastScrollW; // width of the fastscroll area + int mFastScrollLineW; // width of the line for fastscroll rendering + int mFastScrollRectW; // width of the rectangle for fastscroll + int mFastScrollRectH; // minimum height of the rectangle for fastscroll + COLOR mFastScrollLineColor; + COLOR mFastScrollRectColor; + + // Scrolling and dynamic state + int mFastScrollRectCurrentY; // current top of fastscroll rect relative to list top + int mFastScrollRectCurrentH; // current height of fastscroll rect + int mFastScrollRectTouchY; // offset from top of fastscroll rect where the user initially touched + bool hasScroll; // indicates that we have enough items in the list to scroll + int firstDisplayedItem; // this item goes at the top of the display list - may only be partially visible + int scrollingSpeed; // on a touch release, this is set based on the difference in the y-axis between the last 2 touches and indicates how fast the kinetic scrolling will go + int y_offset; // this is how many pixels offset in the y axis for per pixel scrolling, is always <= 0 and should never be < -actualItemHeight + bool allowSelection; // true if touched item can be selected, false for pure read-only lists and the console + size_t selectedItem; // selected item index after the initial touch, set to -1 if we are scrolling + int touchDebounce; // debounce for touches, minimum of 6 pixels but may be larger calculated based actualItemHeight / 3 + int lastY, last2Y; // last 2 touch locations, used for tracking kinetic scroll speed + int fastScroll; // indicates that the inital touch was inside the fastscroll region - makes for easier fast scrolling as the touches don't have to stay within the fast scroll region and you drag your finger + int mUpdate; // indicates that a change took place and we need to re-render +}; + +class GUIFileSelector : public GUIScrollList +{ +public: + GUIFileSelector(xml_node<>* node); + virtual ~GUIFileSelector(); + +public: + // Update - Update any UI component animations (called <= 30 FPS) + // Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error + virtual int Update(void); + + // NotifyVarChange - Notify of a variable change + virtual int NotifyVarChange(const std::string& varName, const std::string& value); + + // SetPageFocus - Notify when a page gains or loses focus + virtual void SetPageFocus(int inFocus); + + virtual size_t GetItemCount(); + virtual void RenderItem(size_t itemindex, int yPos, bool selected); + virtual void NotifySelect(size_t item_selected); + +protected: + struct FileData { + std::string fileName; + unsigned char fileType; // Uses d_type format from struct dirent + mode_t protection; // Uses mode_t format from stat + uid_t userId; + gid_t groupId; + off_t fileSize; + time_t lastAccess; // Uses time_t format from stat + time_t lastModified; // Uses time_t format from stat + time_t lastStatChange; // Uses time_t format from stat + }; + +protected: + virtual int GetFileList(const std::string folder); + static bool fileSort(FileData d1, FileData d2); + +protected: + std::vector<FileData> mFolderList; + std::vector<FileData> mFileList; + std::string mPathVar; // current path displayed, saved in the data manager + std::string mPathDefault; // default value for the path if none is set in mPathVar + std::string mExtn; // used for filtering the file list, for example, *.zip + std::string mVariable; // set when the user selects an item, pull path like /path/to/foo + std::string mSortVariable; // data manager variable used to change the sorting of files + std::string mSelection; // set when the user selects an item without the full path like selecting /path/to/foo would just be set to foo + int mShowFolders, mShowFiles; // indicates if the list should show folders and/or files + int mShowNavFolders; // indicates if the list should include the "up a level" item and allow you to traverse folders (nav folders are disabled for the restore list, for instance) + static int mSortOrder; // must be static because it is used by the static function fileSort + ImageResource* mFolderIcon; + ImageResource* mFileIcon; + bool updateFileList; +}; + +class GUIListBox : public GUIScrollList +{ +public: + GUIListBox(xml_node<>* node); + virtual ~GUIListBox(); + +public: + // Update - Update any UI component animations (called <= 30 FPS) + // Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error + virtual int Update(void); + + // NotifyVarChange - Notify of a variable change + virtual int NotifyVarChange(const std::string& varName, const std::string& value); + + // SetPageFocus - Notify when a page gains or loses focus + virtual void SetPageFocus(int inFocus); + + virtual size_t GetItemCount(); + virtual void RenderItem(size_t itemindex, int yPos, bool selected); + virtual void NotifySelect(size_t item_selected); + +protected: + struct ListData { + std::string displayName; + std::string variableValue; + unsigned int selected; + GUIAction* action; + }; + +protected: + std::vector<ListData> mList; + std::string mVariable; + std::string currentValue; + ImageResource* mIconSelected; + ImageResource* mIconUnselected; +}; + +class GUIPartitionList : public GUIScrollList +{ +public: + GUIPartitionList(xml_node<>* node); + virtual ~GUIPartitionList(); + +public: + // Update - Update any UI component animations (called <= 30 FPS) + // Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error + virtual int Update(); + + // NotifyVarChange - Notify of a variable change + virtual int NotifyVarChange(const std::string& varName, const std::string& value); + + // SetPageFocus - Notify when a page gains or loses focus + virtual void SetPageFocus(int inFocus); + + virtual size_t GetItemCount(); + virtual void RenderItem(size_t itemindex, int yPos, bool selected); + virtual void NotifySelect(size_t item_selected); + +protected: + void MatchList(); + void SetPosition(); + +protected: + std::vector<PartitionList> mList; + std::string ListType; + std::string mVariable; + std::string selectedList; + std::string currentValue; + std::string mLastValue; + ImageResource* mIconSelected; + ImageResource* mIconUnselected; + bool updateList; +}; + +class GUIConsole : public GUIScrollList +{ +public: + GUIConsole(xml_node<>* node); + +public: + // Render - Render the full object to the GL surface + // Return 0 on success, <0 on error + virtual int Render(void); + + // Update - Update any UI component animations (called <= 30 FPS) + // Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error + virtual int Update(void); + + // IsInRegion - Checks if the request is handled by this object + // Return 1 if this object handles the request, 0 if not + virtual int IsInRegion(int x, int y); + + // NotifyTouch - Notify of a touch event + // Return 0 on success, >0 to ignore remainder of touch, and <0 on error (Return error to allow other handlers) + virtual int NotifyTouch(TOUCH_STATE state, int x, int y); + + // ScrollList interface + virtual size_t GetItemCount(); + virtual void RenderItem(size_t itemindex, int yPos, bool selected); + virtual void NotifySelect(size_t item_selected); +protected: + enum SlideoutState + { + hidden = 0, + visible, + request_hide, + request_show + }; + + ImageResource* mSlideoutImage; + size_t mLastCount; // lines from gConsole that are already split and copied into rConsole + bool scrollToEnd; // true if we want to keep tracking the last line + int mSlideoutX, mSlideoutY, mSlideoutW, mSlideoutH; + int mSlideout; + SlideoutState mSlideoutState; + std::vector<std::string> rConsole; + std::vector<std::string> rConsoleColor; + +protected: + bool AddLines(); + int RenderSlideout(void); + int RenderConsole(void); +}; + +// GUIAnimation - Used for animations +class GUIAnimation : public GUIObject, public RenderObject +{ +public: + GUIAnimation(xml_node<>* node); + +public: + // Render - Render the full object to the GL surface + // Return 0 on success, <0 on error + virtual int Render(void); + + // Update - Update any UI component animations (called <= 30 FPS) + // Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error + virtual int Update(void); + +protected: + AnimationResource* mAnimation; + int mFrame; + int mFPS; + int mLoop; + int mRender; + int mUpdateCount; +}; + +class GUIProgressBar : public GUIObject, public RenderObject, public ActionObject +{ +public: + GUIProgressBar(xml_node<>* node); + +public: + // Render - Render the full object to the GL surface + // Return 0 on success, <0 on error + virtual int Render(void); + + // Update - Update any UI component animations (called <= 30 FPS) + // Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error + virtual int Update(void); + + // NotifyVarChange - Notify of a variable change + // Returns 0 on success, <0 on error + virtual int NotifyVarChange(const std::string& varName, const std::string& value); + +protected: + ImageResource* mEmptyBar; + ImageResource* mFullBar; + std::string mMinValVar; + std::string mMaxValVar; + std::string mCurValVar; + float mSlide; + float mSlideInc; + int mSlideFrames; + int mLastPos; + +protected: + virtual int RenderInternal(void); // Does the actual render +}; + +class GUISlider : public GUIObject, public RenderObject, public ActionObject +{ +public: + GUISlider(xml_node<>* node); + virtual ~GUISlider(); + +public: + // Render - Render the full object to the GL surface + // Return 0 on success, <0 on error + virtual int Render(void); + + // Update - Update any UI component animations (called <= 30 FPS) + // Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error + virtual int Update(void); + + // NotifyTouch - Notify of a touch event + // Return 0 on success, >0 to ignore remainder of touch, and <0 on error + virtual int NotifyTouch(TOUCH_STATE state, int x, int y); + +protected: + GUIAction* sAction; + GUIText* sSliderLabel; + ImageResource* sSlider; + ImageResource* sSliderUsed; + ImageResource* sTouch; + int sTouchW, sTouchH; + int sCurTouchX; + int sUpdate; +}; + +#define KEYBOARD_ACTION 253 +#define KEYBOARD_LAYOUT 254 +#define KEYBOARD_SWIPE_LEFT 252 +#define KEYBOARD_SWIPE_RIGHT 251 +#define KEYBOARD_ARROW_LEFT 250 +#define KEYBOARD_ARROW_RIGHT 249 +#define KEYBOARD_HOME 248 +#define KEYBOARD_END 247 +#define KEYBOARD_ARROW_UP 246 +#define KEYBOARD_ARROW_DOWN 245 +#define KEYBOARD_SPECIAL_KEYS 245 +#define KEYBOARD_BACKSPACE 8 + +class GUIKeyboard : public GUIObject, public RenderObject, public ActionObject +{ +public: + GUIKeyboard(xml_node<>* node); + virtual ~GUIKeyboard(); + +public: + virtual int Render(void); + virtual int Update(void); + virtual int NotifyTouch(TOUCH_STATE state, int x, int y); + virtual int SetRenderPos(int x, int y, int w = 0, int h = 0); + +protected: + struct Key + { + unsigned char key; // ASCII code or one of the special KEYBOARD_* codes above + unsigned char longpresskey; + int end_x; + int layout; + }; + int ParseKey(const char* keyinfo, Key& key, int& Xindex, int keyWidth, bool longpress); + void LoadKeyLabels(xml_node<>* parent, int layout); + void DrawKey(Key& key, int keyX, int keyY, int keyW, int keyH); + + enum { + MAX_KEYBOARD_LAYOUTS = 5, + MAX_KEYBOARD_ROWS = 9, + MAX_KEYBOARD_KEYS = 20 + }; + struct Layout + { + ImageResource* keyboardImg; + struct Key keys[MAX_KEYBOARD_ROWS][MAX_KEYBOARD_KEYS]; + int row_end_y[MAX_KEYBOARD_ROWS]; + bool is_caps; + int revert_layout; + }; + Layout layouts[MAX_KEYBOARD_LAYOUTS]; + + struct KeyLabel + { + unsigned char key; // same as in struct Key + int layout_from; // 1-based; 0 for labels that apply to all layouts + int layout_to; // same as Key.layout + string text; // key label text + ImageResource* image; // image (overrides text if defined) + }; + std::vector<KeyLabel> mKeyLabels; + + // Find key at screen coordinates + Key* HitTestKey(int x, int y); + + bool mRendered; + std::string mVariable; + int currentLayout; + bool CapsLockOn; + int highlightRenderCount; + Key* currentKey; + bool hasHighlight, hasCapsHighlight; + COLOR mHighlightColor; + COLOR mCapsHighlightColor; + COLOR mFontColor; // for centered key labels + COLOR mFontColorSmall; // for centered key labels + FontResource* mFont; // for main key labels + FontResource* mSmallFont; // for key labels like "?123" + FontResource* mLongpressFont; // for the small longpress label in the upper right corner + int longpressOffsetX, longpressOffsetY; // distance of the longpress label from the key corner + COLOR mLongpressFontColor; + COLOR mBackgroundColor; // keyboard background color + COLOR mKeyColorAlphanumeric; // key background color + COLOR mKeyColorOther; // key background color + int mKeyMarginX, mKeyMarginY; // space around key boxes - applied to left/right and top/bottom +}; + +// GUIInput - Used for keyboard input +class GUIInput : public GUIObject, public RenderObject, public ActionObject, public InputObject +{ +public: + GUIInput(xml_node<>* node); + virtual ~GUIInput(); + +public: + // Render - Render the full object to the GL surface + // Return 0 on success, <0 on error + virtual int Render(void); + + // Update - Update any UI component animations (called <= 30 FPS) + // Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error + virtual int Update(void); + + // Notify of a variable change + virtual int NotifyVarChange(const std::string& varName, const std::string& value); + + // NotifyTouch - Notify of a touch event + // Return 0 on success, >0 to ignore remainder of touch, and <0 on error + virtual int NotifyTouch(TOUCH_STATE state, int x, int y); + + virtual int NotifyKeyboard(int key); + +protected: + virtual int GetSelection(int x, int y); + + // Handles displaying the text properly when chars are added, deleted, or for scrolling + virtual int HandleTextLocation(int x); + +protected: + GUIText* mInputText; + GUIAction* mAction; + ImageResource* mBackground; + ImageResource* mCursor; + FontResource* mFont; + std::string mText; + std::string mLastValue; + std::string mVariable; + std::string mMask; + std::string mMaskVariable; + COLOR mBackgroundColor; + COLOR mCursorColor; + int scrollingX; + int lastX; + int mCursorLocation; + int mBackgroundX, mBackgroundY, mBackgroundW, mBackgroundH; + int mFontY; + unsigned skipChars; + unsigned mFontHeight; + unsigned CursorWidth; + bool mRendered; + bool HasMask; + bool DrawCursor; + bool isLocalChange; + bool HasAllowed; + bool HasDisabled; + std::string AllowedList; + std::string DisabledList; + unsigned MinLen; + unsigned MaxLen; +}; + +class HardwareKeyboard +{ +public: + HardwareKeyboard(); + virtual ~HardwareKeyboard(); + +public: + // called by the input handler for key events + int KeyDown(int key_code); + int KeyUp(int key_code); + + // called by the input handler when holding a key down + int KeyRepeat(); + + // called by multi-key actions to suppress key-release notifications + void ConsumeKeyRelease(int key); + +private: + int mLastKeyChar; + std::set<int> mPressedKeys; +}; + +class GUISliderValue: public GUIObject, public RenderObject, public ActionObject +{ +public: + GUISliderValue(xml_node<>* node); + virtual ~GUISliderValue(); + +public: + // Render - Render the full object to the GL surface + // Return 0 on success, <0 on error + virtual int Render(void); + + // Update - Update any UI component animations (called <= 30 FPS) + // Return 0 if nothing to update, 1 on success and contiue, >1 if full render required, and <0 on error + virtual int Update(void); + + // SetPos - Update the position of the render object + // Return 0 on success, <0 on error + virtual int SetRenderPos(int x, int y, int w = 0, int h = 0); + + // NotifyTouch - Notify of a touch event + // Return 0 on success, >0 to ignore remainder of touch, and <0 on error + virtual int NotifyTouch(TOUCH_STATE state, int x, int y); + + // Notify of a variable change + virtual int NotifyVarChange(const std::string& varName, const std::string& value); + + // SetPageFocus - Notify when a page gains or loses focus + virtual void SetPageFocus(int inFocus); + +protected: + int measureText(const std::string& str); + int valueFromPct(float pct); + float pctFromValue(int value); + void loadValue(bool force = false); + + std::string mVariable; + int mMax; + int mMin; + int mValue; + char *mValueStr; + float mValuePct; + std::string mMaxStr; + std::string mMinStr; + FontResource *mFont; + GUIText* mLabel; + int mLabelW; + COLOR mTextColor; + COLOR mLineColor; + COLOR mSliderColor; + bool mShowRange; + bool mShowCurr; + int mLineX; + int mLineY; + int mLineH; + int mLinePadding; + int mPadding; + int mSliderY; + int mSliderW; + int mSliderH; + bool mRendered; + int mFontHeight; + GUIAction *mAction; + bool mChangeOnDrag; + int mLineW; + bool mDragging; + ImageResource *mBackgroundImage; + ImageResource *mHandleImage; + ImageResource *mHandleHoverImage; +}; + +class MouseCursor : public RenderObject +{ +public: + MouseCursor(int posX, int posY); + virtual ~MouseCursor(); + + virtual int Render(void); + virtual int Update(void); + virtual int SetRenderPos(int x, int y, int w = 0, int h = 0); + + void Move(int deltaX, int deltaY); + void GetPos(int& x, int& y); + void LoadData(xml_node<>* node); + void ResetData(int resX, int resY); + +private: + int m_resX; + int m_resY; + bool m_moved; + float m_speedMultiplier; + COLOR m_color; + ImageResource *m_image; + bool m_present; +}; + +class GUIPatternPassword : public GUIObject, public RenderObject, public ActionObject +{ +public: + GUIPatternPassword(xml_node<>* node); + virtual ~GUIPatternPassword(); + +public: + virtual int Render(void); + virtual int Update(void); + virtual int NotifyTouch(TOUCH_STATE state, int x, int y); + virtual int SetRenderPos(int x, int y, int w = 0, int h = 0); + +protected: + void CalculateDotPositions(); + void ResetActiveDots(); + void ConnectDot(int dot_idx); + void ConnectIntermediateDots(int dot_idx); + 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); + void PatternDrawn(); + + struct Dot { + int x; + int y; + bool active; + }; + + Dot mDots[9]; + int mConnectedDots[9]; + size_t mConnectedDotsLen; + int mCurLineX; + int mCurLineY; + bool mTrackingTouch; + bool mNeedRender; + + COLOR mDotColor; + COLOR mActiveDotColor; + COLOR mLineColor; + ImageResource *mDotImage; + ImageResource *mActiveDotImage; + gr_surface mDotCircle; + gr_surface mActiveDotCircle; + int mDotRadius; + int mLineWidth; + + std::string mPassVar; + GUIAction *mAction; + int mUpdate; +}; + + +// Helper APIs +xml_node<>* FindNode(xml_node<>* parent, const char* nodename, int depth = 0); +std::string LoadAttrString(xml_node<>* element, const char* attrname, const char* defaultvalue = ""); +int LoadAttrInt(xml_node<>* element, const char* attrname, int defaultvalue = 0); +int LoadAttrIntScaleX(xml_node<>* element, const char* attrname, int defaultvalue = 0); +int LoadAttrIntScaleY(xml_node<>* element, const char* attrname, int defaultvalue = 0); +COLOR LoadAttrColor(xml_node<>* element, const char* attrname, bool* found_color, COLOR defaultvalue = COLOR(0,0,0,0)); +COLOR LoadAttrColor(xml_node<>* element, const char* attrname, COLOR defaultvalue = COLOR(0,0,0,0)); +FontResource* LoadAttrFont(xml_node<>* element, const char* attrname); +ImageResource* LoadAttrImage(xml_node<>* element, const char* attrname); +AnimationResource* LoadAttrAnimation(xml_node<>* element, const char* attrname); + +bool LoadPlacement(xml_node<>* node, int* x, int* y, int* w = NULL, int* h = NULL, RenderObject::Placement* placement = NULL); + +#endif // _OBJECTS_HEADER + diff --git a/gui/pages.cpp b/gui/pages.cpp new file mode 100644 index 000000000..4c98a7233 --- /dev/null +++ b/gui/pages.cpp @@ -0,0 +1,1470 @@ +/* + Copyright 2013 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see <http://www.gnu.org/licenses/>. +*/ + +// pages.cpp - Source to manage GUI base objects + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> +#include "../twrp-functions.hpp" + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +#include "../minzip/SysUtil.h" +#include "../minzip/Zip.h" +#include "gui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" +#include "blanktimer.hpp" + +extern int gGuiRunning; + +std::map<std::string, PageSet*> PageManager::mPageSets; +PageSet* PageManager::mCurrentSet; +PageSet* PageManager::mBaseSet = NULL; +MouseCursor *PageManager::mMouseCursor = NULL; +HardwareKeyboard *PageManager::mHardwareKeyboard = NULL; + +int tw_x_offset = 0; +int tw_y_offset = 0; + +// Helper routine to convert a string to a color declaration +int ConvertStrToColor(std::string str, COLOR* color) +{ + // Set the default, solid black + memset(color, 0, sizeof(COLOR)); + color->alpha = 255; + + // Translate variables + DataManager::GetValue(str, str); + + // Look for some defaults + if (str == "black") return 0; + else if (str == "white") { color->red = color->green = color->blue = 255; return 0; } + else if (str == "red") { color->red = 255; return 0; } + else if (str == "green") { color->green = 255; return 0; } + else if (str == "blue") { color->blue = 255; return 0; } + + // At this point, we require an RGB(A) color + if (str[0] != '#') + return -1; + + str.erase(0, 1); + + int result; + if (str.size() >= 8) { + // We have alpha channel + string alpha = str.substr(6, 2); + result = strtol(alpha.c_str(), NULL, 16); + color->alpha = result & 0x000000FF; + str.resize(6); + result = strtol(str.c_str(), NULL, 16); + color->red = (result >> 16) & 0x000000FF; + color->green = (result >> 8) & 0x000000FF; + color->blue = result & 0x000000FF; + } else { + result = strtol(str.c_str(), NULL, 16); + color->red = (result >> 16) & 0x000000FF; + color->green = (result >> 8) & 0x000000FF; + color->blue = result & 0x000000FF; + } + return 0; +} + +// Helper APIs +xml_node<>* FindNode(xml_node<>* parent, const char* nodename, int depth /* = 0 */) +{ + if (!parent) + return NULL; + + xml_node<>* child = parent->first_node(nodename); + if (child) + return child; + + if (depth == 10) { + LOGERR("Too many style loops detected.\n"); + return NULL; + } + + xml_node<>* style = parent->first_node("style"); + if (style) { + while (style) { + if (!style->first_attribute("name")) { + LOGERR("No name given for style.\n"); + continue; + } else { + std::string name = style->first_attribute("name")->value(); + xml_node<>* node = PageManager::FindStyle(name); + + if (node) { + // We found the style that was named + xml_node<>* stylenode = FindNode(node, nodename, depth + 1); + if (stylenode) + return stylenode; + } + } + style = style->next_sibling("style"); + } + } else { + // Search for stylename in the parent node <object type="foo" stylename="foo2"> + xml_attribute<>* attr = parent->first_attribute("style"); + // If no style is found anywhere else and the node wasn't found in the object itself + // as a special case we will search for a style that uses the same style name as the + // object type, so <object type="button"> would search for a style named "button" + if (!attr) + attr = parent->first_attribute("type"); + if (attr) { + xml_node<>* node = PageManager::FindStyle(attr->value()); + if (node) { + xml_node<>* stylenode = FindNode(node, nodename, depth + 1); + if (stylenode) + return stylenode; + } + } + } + return NULL; +} + +std::string LoadAttrString(xml_node<>* element, const char* attrname, const char* defaultvalue) +{ + if (!element) + return defaultvalue; + + xml_attribute<>* attr = element->first_attribute(attrname); + return attr ? attr->value() : defaultvalue; +} + +int LoadAttrInt(xml_node<>* element, const char* attrname, int defaultvalue) +{ + string value = LoadAttrString(element, attrname); + // resolve variables + DataManager::GetValue(value, value); + return value.empty() ? defaultvalue : atoi(value.c_str()); +} + +int LoadAttrIntScaleX(xml_node<>* element, const char* attrname, int defaultvalue) +{ + return scale_theme_x(LoadAttrInt(element, attrname, defaultvalue)); +} + +int LoadAttrIntScaleY(xml_node<>* element, const char* attrname, int defaultvalue) +{ + return scale_theme_y(LoadAttrInt(element, attrname, defaultvalue)); +} + +COLOR LoadAttrColor(xml_node<>* element, const char* attrname, bool* found_color, COLOR defaultvalue) +{ + string value = LoadAttrString(element, attrname); + *found_color = !value.empty(); + // resolve variables + DataManager::GetValue(value, value); + COLOR ret = defaultvalue; + if (ConvertStrToColor(value, &ret) == 0) + return ret; + else + return defaultvalue; +} + +COLOR LoadAttrColor(xml_node<>* element, const char* attrname, COLOR defaultvalue) +{ + bool found_color = false; + return LoadAttrColor(element, attrname, &found_color, defaultvalue); +} + +FontResource* LoadAttrFont(xml_node<>* element, const char* attrname) +{ + std::string name = LoadAttrString(element, attrname, ""); + if (name.empty()) + return NULL; + else + return PageManager::GetResources()->FindFont(name); +} + +ImageResource* LoadAttrImage(xml_node<>* element, const char* attrname) +{ + std::string name = LoadAttrString(element, attrname, ""); + if (name.empty()) + return NULL; + else + return PageManager::GetResources()->FindImage(name); +} + +AnimationResource* LoadAttrAnimation(xml_node<>* element, const char* attrname) +{ + std::string name = LoadAttrString(element, attrname, ""); + if (name.empty()) + return NULL; + else + return PageManager::GetResources()->FindAnimation(name); +} + +bool LoadPlacement(xml_node<>* node, int* x, int* y, int* w /* = NULL */, int* h /* = NULL */, RenderObject::Placement* placement /* = NULL */) +{ + if (!node) + return false; + + if (node->first_attribute("x")) + *x = LoadAttrIntScaleX(node, "x") + tw_x_offset; + + if (node->first_attribute("y")) + *y = LoadAttrIntScaleY(node, "y") + tw_y_offset; + + if (w && node->first_attribute("w")) + *w = LoadAttrIntScaleX(node, "w"); + + if (h && node->first_attribute("h")) + *h = LoadAttrIntScaleY(node, "h"); + + if (placement && node->first_attribute("placement")) + *placement = (RenderObject::Placement) LoadAttrInt(node, "placement"); + + return true; +} + +int ActionObject::SetActionPos(int x, int y, int w, int h) +{ + if (x < 0 || y < 0) + return -1; + + mActionX = x; + mActionY = y; + if (w || h) + { + mActionW = w; + mActionH = h; + } + return 0; +} + +Page::Page(xml_node<>* page, std::vector<xml_node<>*> *templates) +{ + mTouchStart = NULL; + + // We can memset the whole structure, because the alpha channel is ignored + memset(&mBackground, 0, sizeof(COLOR)); + + // With NULL, we make a console-only display + if (!page) + { + mName = "console"; + + GUIConsole* element = new GUIConsole(NULL); + mRenders.push_back(element); + mActions.push_back(element); + return; + } + + if (page->first_attribute("name")) + mName = page->first_attribute("name")->value(); + else + { + LOGERR("No page name attribute found!\n"); + return; + } + + LOGINFO("Loading page %s\n", mName.c_str()); + + // This is a recursive routine for template handling + ProcessNode(page, templates, 0); +} + +Page::~Page() +{ + for (std::vector<GUIObject*>::iterator itr = mObjects.begin(); itr != mObjects.end(); ++itr) + delete *itr; +} + +bool Page::ProcessNode(xml_node<>* page, std::vector<xml_node<>*> *templates, int depth) +{ + if (depth == 10) + { + LOGERR("Page processing depth has exceeded 10. Failing out. This is likely a recursive template.\n"); + return false; + } + + for (xml_node<>* child = page->first_node(); child; child = child->next_sibling()) + { + std::string type = child->name(); + + if (type == "background") { + mBackground = LoadAttrColor(child, "color", COLOR(0,0,0,0)); + continue; + } + + if (type == "object") { + // legacy format : <object type="..."> + xml_attribute<>* attr = child->first_attribute("type"); + type = attr ? attr->value() : "*unspecified*"; + } + + if (type == "text") + { + GUIText* element = new GUIText(child); + mObjects.push_back(element); + mRenders.push_back(element); + mActions.push_back(element); + } + else if (type == "image") + { + GUIImage* element = new GUIImage(child); + mObjects.push_back(element); + mRenders.push_back(element); + } + else if (type == "fill") + { + GUIFill* element = new GUIFill(child); + mObjects.push_back(element); + mRenders.push_back(element); + } + else if (type == "action") + { + GUIAction* element = new GUIAction(child); + mObjects.push_back(element); + mActions.push_back(element); + } + else if (type == "console") + { + GUIConsole* element = new GUIConsole(child); + mObjects.push_back(element); + mRenders.push_back(element); + mActions.push_back(element); + } + else if (type == "button") + { + GUIButton* element = new GUIButton(child); + mObjects.push_back(element); + mRenders.push_back(element); + mActions.push_back(element); + } + else if (type == "checkbox") + { + GUICheckbox* element = new GUICheckbox(child); + mObjects.push_back(element); + mRenders.push_back(element); + mActions.push_back(element); + } + else if (type == "fileselector") + { + GUIFileSelector* element = new GUIFileSelector(child); + mObjects.push_back(element); + mRenders.push_back(element); + mActions.push_back(element); + } + else if (type == "animation") + { + GUIAnimation* element = new GUIAnimation(child); + mObjects.push_back(element); + mRenders.push_back(element); + } + else if (type == "progressbar") + { + GUIProgressBar* element = new GUIProgressBar(child); + mObjects.push_back(element); + mRenders.push_back(element); + mActions.push_back(element); + } + else if (type == "slider") + { + GUISlider* element = new GUISlider(child); + mObjects.push_back(element); + mRenders.push_back(element); + mActions.push_back(element); + } + else if (type == "slidervalue") + { + GUISliderValue *element = new GUISliderValue(child); + mObjects.push_back(element); + mRenders.push_back(element); + mActions.push_back(element); + } + else if (type == "listbox") + { + GUIListBox* element = new GUIListBox(child); + mObjects.push_back(element); + mRenders.push_back(element); + mActions.push_back(element); + } + else if (type == "keyboard") + { + GUIKeyboard* element = new GUIKeyboard(child); + mObjects.push_back(element); + mRenders.push_back(element); + mActions.push_back(element); + } + else if (type == "input") + { + GUIInput* element = new GUIInput(child); + mObjects.push_back(element); + mRenders.push_back(element); + mActions.push_back(element); + mInputs.push_back(element); + } + else if (type == "partitionlist") + { + GUIPartitionList* element = new GUIPartitionList(child); + mObjects.push_back(element); + mRenders.push_back(element); + mActions.push_back(element); + } + else if (type == "patternpassword") + { + GUIPatternPassword* element = new GUIPatternPassword(child); + mObjects.push_back(element); + mRenders.push_back(element); + mActions.push_back(element); + } + else if (type == "template") + { + if (!templates || !child->first_attribute("name")) + { + LOGERR("Invalid template request.\n"); + } + else + { + std::string name = child->first_attribute("name")->value(); + xml_node<>* node; + bool node_found = false; + + // We need to find the correct template + for (std::vector<xml_node<>*>::iterator itr = templates->begin(); itr != templates->end(); itr++) { + node = (*itr)->first_node("template"); + + while (node) + { + if (!node->first_attribute("name")) + continue; + + if (name == node->first_attribute("name")->value()) + { + if (!ProcessNode(node, templates, depth + 1)) + return false; + else { + node_found = true; + break; + } + } + if (node_found) + break; + node = node->next_sibling("template"); + } + // [check] why is there no if (node_found) here too? + } + } + } + else + { + LOGERR("Unknown object type: %s.\n", type.c_str()); + } + } + return true; +} + +int Page::Render(void) +{ + // Render background + gr_color(mBackground.red, mBackground.green, mBackground.blue, mBackground.alpha); + gr_fill(0, 0, gr_fb_width(), gr_fb_height()); + + // Render remaining objects + std::vector<RenderObject*>::iterator iter; + for (iter = mRenders.begin(); iter != mRenders.end(); iter++) + { + if ((*iter)->Render()) + LOGERR("A render request has failed.\n"); + } + return 0; +} + +int Page::Update(void) +{ + int retCode = 0; + + std::vector<RenderObject*>::iterator iter; + for (iter = mRenders.begin(); iter != mRenders.end(); iter++) + { + int ret = (*iter)->Update(); + if (ret < 0) + LOGERR("An update request has failed.\n"); + else if (ret > retCode) + retCode = ret; + } + + return retCode; +} + +int Page::NotifyTouch(TOUCH_STATE state, int x, int y) +{ + // By default, return 1 to ignore further touches if nobody is listening + int ret = 1; + + // Don't try to handle a lack of handlers + if (mActions.size() == 0) + return ret; + + // We record mTouchStart so we can pass all the touch stream to the same handler + if (state == TOUCH_START) + { + std::vector<ActionObject*>::reverse_iterator iter; + // We work backwards, from top-most element to bottom-most element + for (iter = mActions.rbegin(); iter != mActions.rend(); iter++) + { + if ((*iter)->IsInRegion(x, y)) + { + mTouchStart = (*iter); + ret = mTouchStart->NotifyTouch(state, x, y); + if (ret >= 0) + break; + mTouchStart = NULL; + } + } + } + else if (state == TOUCH_RELEASE && mTouchStart != NULL) + { + ret = mTouchStart->NotifyTouch(state, x, y); + mTouchStart = NULL; + } + else if ((state == TOUCH_DRAG || state == TOUCH_HOLD || state == TOUCH_REPEAT) && mTouchStart != NULL) + { + ret = mTouchStart->NotifyTouch(state, x, y); + } + return ret; +} + +int Page::NotifyKey(int key, bool down) +{ + std::vector<ActionObject*>::reverse_iterator iter; + + // Don't try to handle a lack of handlers + 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++) + { + ret = (*iter)->NotifyKey(key, down); + if (ret < 0) { + LOGERR("An action handler has returned an error\n"); + ret = 1; + } + } + return ret; +} + +int Page::NotifyKeyboard(int key) +{ + std::vector<InputObject*>::reverse_iterator iter; + + // Don't try to handle a lack of handlers + if (mInputs.size() == 0) + return 1; + + // We work backwards, from top-most element to bottom-most element + for (iter = mInputs.rbegin(); iter != mInputs.rend(); iter++) + { + int ret = (*iter)->NotifyKeyboard(key); + if (ret == 0) + return 0; + else if (ret < 0) + LOGERR("A keyboard handler has returned an error"); + } + return 1; +} + +int Page::SetKeyBoardFocus(int inFocus) +{ + std::vector<InputObject*>::reverse_iterator iter; + + // Don't try to handle a lack of handlers + if (mInputs.size() == 0) + return 1; + + // We work backwards, from top-most element to bottom-most element + for (iter = mInputs.rbegin(); iter != mInputs.rend(); iter++) + { + int ret = (*iter)->SetInputFocus(inFocus); + if (ret == 0) + return 0; + else if (ret < 0) + LOGERR("An input focus handler has returned an error"); + } + return 1; +} + +void Page::SetPageFocus(int inFocus) +{ + // Render remaining objects + std::vector<RenderObject*>::iterator iter; + for (iter = mRenders.begin(); iter != mRenders.end(); iter++) + (*iter)->SetPageFocus(inFocus); + + return; +} + +int Page::NotifyVarChange(std::string varName, std::string value) +{ + std::vector<GUIObject*>::iterator iter; + for (iter = mObjects.begin(); iter != mObjects.end(); ++iter) + { + if ((*iter)->NotifyVarChange(varName, value)) + LOGERR("An action handler errored on NotifyVarChange.\n"); + } + return 0; +} + +PageSet::PageSet(char* xmlFile) +{ + mResources = new ResourceManager; + mCurrentPage = NULL; + + mXmlFile = xmlFile; + if (xmlFile) + mDoc.parse<0>(mXmlFile); + else + mCurrentPage = new Page(NULL, NULL); +} + +PageSet::~PageSet() +{ + mOverlays.clear(); + for (std::vector<Page*>::iterator itr = mPages.begin(); itr != mPages.end(); ++itr) + delete *itr; + + delete mResources; + free(mXmlFile); + + mDoc.clear(); + + for (std::vector<xml_document<>*>::iterator itr = mIncludedDocs.begin(); itr != mIncludedDocs.end(); ++itr) { + (*itr)->clear(); + delete *itr; + } +} + +int PageSet::Load(ZipArchive* package) +{ + xml_node<>* parent; + xml_node<>* child; + xml_node<>* xmltemplate; + xml_node<>* xmlstyle; + + parent = mDoc.first_node("recovery"); + if (!parent) + parent = mDoc.first_node("install"); + + set_scale_values(1, 1); // Reset any previous scaling values + + // Now, let's parse the XML + LOGINFO("Checking resolution...\n"); + child = parent->first_node("details"); + if (child) { + xml_node<>* resolution = child->first_node("resolution"); + if (resolution) { + xml_attribute<>* width_attr = resolution->first_attribute("width"); + xml_attribute<>* height_attr = resolution->first_attribute("height"); + xml_attribute<>* noscale_attr = resolution->first_attribute("noscaling"); + if (width_attr && height_attr && !noscale_attr) { + int width = atoi(width_attr->value()); + int height = atoi(height_attr->value()); + int offx = 0, offy = 0; +#ifdef TW_ROUND_SCREEN + xml_node<>* roundscreen = child->first_node("roundscreen"); + if (roundscreen) { + LOGINFO("TW_ROUND_SCREEN := true, using round screen XML settings.\n"); + xml_attribute<>* offx_attr = roundscreen->first_attribute("offset_x"); + xml_attribute<>* offy_attr = roundscreen->first_attribute("offset_y"); + if (offx_attr) { + offx = atoi(offx_attr->value()); + } + if (offy_attr) { + offy = atoi(offy_attr->value()); + } + } +#endif + if (width != 0 && height != 0) { + float scale_w = ((float)gr_fb_width() - ((float)offx * 2.0)) / (float)width; + float scale_h = ((float)gr_fb_height() - ((float)offy * 2.0)) / (float)height; +#ifdef TW_ROUND_SCREEN + float scale_off_w = (float)gr_fb_width() / (float)width; + float scale_off_h = (float)gr_fb_height() / (float)height; + tw_x_offset = offx * scale_off_w; + tw_y_offset = offy * scale_off_h; +#endif + if (scale_w != 1 || scale_h != 1) { + LOGINFO("Scaling theme width %fx and height %fx, offsets x: %i y: %i\n", scale_w, scale_h, tw_x_offset, tw_y_offset); + set_scale_values(scale_w, scale_h); + } + } + } else { + LOGINFO("XML does not contain width and height, no scaling will be applied\n"); + } + } else { + LOGINFO("XML contains no resolution tag, no scaling will be applied.\n"); + } + } else { + LOGINFO("XML contains no details tag, no scaling will be applied.\n"); + } + LOGINFO("Loading resources...\n"); + child = parent->first_node("resources"); + if (child) + mResources->LoadResources(child, package); + + LOGINFO("Loading variables...\n"); + child = parent->first_node("variables"); + if (child) + LoadVariables(child); + + LOGINFO("Loading mouse cursor...\n"); + child = parent->first_node("mousecursor"); + if(child) + PageManager::LoadCursorData(child); + + LOGINFO("Loading pages...\n"); + // This may be NULL if no templates are present + xmltemplate = parent->first_node("templates"); + if (xmltemplate) + templates.push_back(xmltemplate); + + // Load styles if present + xmlstyle = parent->first_node("styles"); + if (xmlstyle) + styles.push_back(xmlstyle); + + child = parent->first_node("pages"); + if (child) { + if (LoadPages(child)) { + LOGERR("PageSet::Load returning -1\n"); + return -1; + } + } + + return CheckInclude(package, &mDoc); +} + +int PageSet::CheckInclude(ZipArchive* package, xml_document<> *parentDoc) +{ + xml_node<>* par; + xml_node<>* par2; + xml_node<>* chld; + xml_node<>* parent; + xml_node<>* child; + xml_node<>* xmltemplate; + xml_node<>* xmlstyle; + long len; + char* xmlFile = NULL; + string filename; + xml_document<> *doc = NULL; + + par = parentDoc->first_node("recovery"); + if (!par) { + par = parentDoc->first_node("install"); + } + if (!par) { + return 0; + } + + par2 = par->first_node("include"); + if (!par2) + return 0; + chld = par2->first_node("xmlfile"); + while (chld != NULL) { + xml_attribute<>* attr = chld->first_attribute("name"); + if (!attr) + break; + + if (!package) { + // We can try to load the XML directly... + filename = TWRES; + filename += attr->value(); + LOGINFO("PageSet::CheckInclude loading filename: '%s'\n", filename.c_str()); + struct stat st; + if(stat(filename.c_str(),&st) != 0) { + LOGERR("Unable to locate '%s'\n", filename.c_str()); + return -1; + } + + len = st.st_size; + xmlFile = (char*) malloc(len + 1); + if (!xmlFile) + return -1; + + int fd = open(filename.c_str(), O_RDONLY); + if (fd == -1) + return -1; + + read(fd, xmlFile, len); + close(fd); + } else { + filename += attr->value(); + LOGINFO("PageSet::CheckInclude loading filename: '%s'\n", filename.c_str()); + const ZipEntry* ui_xml = mzFindZipEntry(package, filename.c_str()); + if (ui_xml == NULL) + { + LOGERR("Unable to locate '%s' in zip file\n", filename.c_str()); + return -1; + } + + // Allocate the buffer for the file + len = mzGetZipEntryUncompLen(ui_xml); + xmlFile = (char*) malloc(len + 1); + if (!xmlFile) + return -1; + + if (!mzExtractZipEntryToBuffer(package, ui_xml, (unsigned char*) xmlFile)) + { + LOGERR("Unable to extract '%s'\n", filename.c_str()); + return -1; + } + } + + xmlFile[len] = '\0'; + doc = new xml_document<>(); + doc->parse<0>(xmlFile); + + parent = doc->first_node("recovery"); + if (!parent) + parent = doc->first_node("install"); + + // Now, let's parse the XML + LOGINFO("Loading included resources...\n"); + child = parent->first_node("resources"); + if (child) + mResources->LoadResources(child, package); + + LOGINFO("Loading included variables...\n"); + child = parent->first_node("variables"); + if (child) + LoadVariables(child); + + LOGINFO("Loading mouse cursor...\n"); + child = parent->first_node("mousecursor"); + if(child) + PageManager::LoadCursorData(child); + + LOGINFO("Loading included pages...\n"); + // This may be NULL if no templates are present + xmltemplate = parent->first_node("templates"); + if (xmltemplate) + templates.push_back(xmltemplate); + + // Load styles if present + xmlstyle = parent->first_node("styles"); + if (xmlstyle) + styles.push_back(xmlstyle); + + child = parent->first_node("pages"); + if (child && LoadPages(child)) + { + templates.pop_back(); + doc->clear(); + delete doc; + return -1; + } + + mIncludedDocs.push_back(doc); + + if (CheckInclude(package, doc)) + return -1; + + chld = chld->next_sibling("xmlfile"); + } + + return 0; +} + +int PageSet::SetPage(std::string page) +{ + Page* tmp = FindPage(page); + if (tmp) + { + if (mCurrentPage) mCurrentPage->SetPageFocus(0); + mCurrentPage = tmp; + mCurrentPage->SetPageFocus(1); + mCurrentPage->NotifyVarChange("", ""); + return 0; + } + else + { + LOGERR("Unable to locate page (%s)\n", page.c_str()); + } + return -1; +} + +int PageSet::SetOverlay(Page* page) +{ + if (page) { + if (mOverlays.size() >= 10) { + LOGERR("Too many overlays requested, max is 10.\n"); + return -1; + } + + std::vector<Page*>::iterator iter; + for (iter = mOverlays.begin(); iter != mOverlays.end(); iter++) { + if ((*iter)->GetName() == page->GetName()) { + mOverlays.erase(iter); + // SetOverlay() is (and should stay) the only function which + // adds to mOverlays. Then, each page can appear at most once. + break; + } + } + + page->SetPageFocus(1); + page->NotifyVarChange("", ""); + + if (!mOverlays.empty()) + mOverlays.back()->SetPageFocus(0); + + mOverlays.push_back(page); + } else { + if (!mOverlays.empty()) { + mOverlays.back()->SetPageFocus(0); + mOverlays.pop_back(); + if (!mOverlays.empty()) + mOverlays.back()->SetPageFocus(1); + else if (mCurrentPage) + mCurrentPage->SetPageFocus(1); // Just in case somehow the regular page lost focus, we'll set it again + } + } + return 0; +} + +const ResourceManager* PageSet::GetResources() +{ + return mResources; +} + +Page* PageSet::FindPage(std::string name) +{ + std::vector<Page*>::iterator iter; + + for (iter = mPages.begin(); iter != mPages.end(); iter++) + { + if (name == (*iter)->GetName()) + return (*iter); + } + return NULL; +} + +int PageSet::LoadVariables(xml_node<>* vars) +{ + xml_node<>* child; + xml_attribute<> *name, *value, *persist; + int p; + + child = vars->first_node("variable"); + while (child) + { + name = child->first_attribute("name"); + value = child->first_attribute("value"); + persist = child->first_attribute("persist"); + if(name && value) + { + if (strcmp(name->value(), "tw_x_offset") == 0) { + tw_x_offset = atoi(value->value()); + child = child->next_sibling("variable"); + continue; + } + if (strcmp(name->value(), "tw_y_offset") == 0) { + tw_y_offset = atoi(value->value()); + child = child->next_sibling("variable"); + continue; + } + p = persist ? atoi(persist->value()) : 0; + string temp = value->value(); + string valstr = gui_parse_text(temp); + + if (valstr.find("+") != string::npos) { + string val1str = valstr; + val1str = val1str.substr(0, val1str.find('+')); + string val2str = valstr; + val2str = val2str.substr(val2str.find('+') + 1, string::npos); + int val1 = atoi(val1str.c_str()); + int val2 = atoi(val2str.c_str()); + int val = val1 + val2; + + DataManager::SetValue(name->value(), val, p); + } else if (valstr.find("-") != string::npos) { + string val1str = valstr; + val1str = val1str.substr(0, val1str.find('-')); + string val2str = valstr; + val2str = val2str.substr(val2str.find('-') + 1, string::npos); + int val1 = atoi(val1str.c_str()); + int val2 = atoi(val2str.c_str()); + int val = val1 - val2; + + DataManager::SetValue(name->value(), val, p); + } else { + DataManager::SetValue(name->value(), valstr, p); + } + } + + child = child->next_sibling("variable"); + } + return 0; +} + +int PageSet::LoadPages(xml_node<>* pages) +{ + xml_node<>* child; + + if (!pages) + return -1; + + child = pages->first_node("page"); + while (child != NULL) + { + Page* page = new Page(child, &templates); + if (page->GetName().empty()) + { + LOGERR("Unable to process load page\n"); + delete page; + } + else + { + mPages.push_back(page); + } + child = child->next_sibling("page"); + } + if (mPages.size() > 0) + return 0; + return -1; +} + +int PageSet::IsCurrentPage(Page* page) +{ + return ((mCurrentPage && mCurrentPage == page) ? 1 : 0); +} + +int PageSet::Render(void) +{ + int ret; + + ret = (mCurrentPage ? mCurrentPage->Render() : -1); + if (ret < 0) + return ret; + + std::vector<Page*>::iterator iter; + + for (iter = mOverlays.begin(); iter != mOverlays.end(); iter++) { + ret = ((*iter) ? (*iter)->Render() : -1); + if (ret < 0) + return ret; + } + return ret; +} + +int PageSet::Update(void) +{ + int ret; + + ret = (mCurrentPage ? mCurrentPage->Update() : -1); + if (ret < 0 || ret > 1) + return ret; + + std::vector<Page*>::iterator iter; + + for (iter = mOverlays.begin(); iter != mOverlays.end(); iter++) { + ret = ((*iter) ? (*iter)->Update() : -1); + if (ret < 0) + return ret; + } + return ret; +} + +int PageSet::NotifyTouch(TOUCH_STATE state, int x, int y) +{ + if (!mOverlays.empty()) + return mOverlays.back()->NotifyTouch(state, x, y); + + return (mCurrentPage ? mCurrentPage->NotifyTouch(state, x, y) : -1); +} + +int PageSet::NotifyKey(int key, bool down) +{ + if (!mOverlays.empty()) + return mOverlays.back()->NotifyKey(key, down); + + return (mCurrentPage ? mCurrentPage->NotifyKey(key, down) : -1); +} + +int PageSet::NotifyKeyboard(int key) +{ + if (!mOverlays.empty()) + return mOverlays.back()->NotifyKeyboard(key); + + return (mCurrentPage ? mCurrentPage->NotifyKeyboard(key) : -1); +} + +int PageSet::SetKeyBoardFocus(int inFocus) +{ + if (!mOverlays.empty()) + return mOverlays.back()->SetKeyBoardFocus(inFocus); + + return (mCurrentPage ? mCurrentPage->SetKeyBoardFocus(inFocus) : -1); +} + +int PageSet::NotifyVarChange(std::string varName, std::string value) +{ + std::vector<Page*>::iterator iter; + + for (iter = mOverlays.begin(); iter != mOverlays.end(); iter++) + (*iter)->NotifyVarChange(varName, value); + + return (mCurrentPage ? mCurrentPage->NotifyVarChange(varName, value) : -1); +} + +int PageManager::LoadPackage(std::string name, std::string package, std::string startpage) +{ + int fd; + ZipArchive zip, *pZip = NULL; + long len; + char* xmlFile = NULL; + PageSet* pageSet = NULL; + int ret; + MemMapping map; + + // Open the XML file + LOGINFO("Loading package: %s (%s)\n", name.c_str(), package.c_str()); + if (package.size() > 4 && package.substr(package.size() - 4) != ".zip") + { + LOGINFO("Load XML directly\n"); + tw_x_offset = TW_X_OFFSET; + tw_y_offset = TW_Y_OFFSET; + // We can try to load the XML directly... + struct stat st; + if(stat(package.c_str(),&st) != 0) + return -1; + + len = st.st_size; + xmlFile = (char*) malloc(len + 1); + if (!xmlFile) + return -1; + + fd = open(package.c_str(), O_RDONLY); + if (fd == -1) + goto error; + + read(fd, xmlFile, len); + close(fd); + } + else + { + LOGINFO("Loading zip theme\n"); + tw_x_offset = 0; + tw_y_offset = 0; + if (!TWFunc::Path_Exists(package)) + return -1; + if (sysMapFile(package.c_str(), &map) != 0) { + LOGERR("Failed to map '%s'\n", package.c_str()); + return -1; + } + if (mzOpenZipArchive(map.addr, map.length, &zip)) { + LOGERR("Unable to open zip archive '%s'\n", package.c_str()); + sysReleaseMap(&map); + return -1; + } + pZip = &zip; + const ZipEntry* ui_xml = mzFindZipEntry(&zip, "ui.xml"); + if (ui_xml == NULL) + { + LOGERR("Unable to locate ui.xml in zip file\n"); + goto error; + } + + // Allocate the buffer for the file + len = mzGetZipEntryUncompLen(ui_xml); + xmlFile = (char*) malloc(len + 1); + if (!xmlFile) + goto error; + + if (!mzExtractZipEntryToBuffer(&zip, ui_xml, (unsigned char*) xmlFile)) + { + LOGERR("Unable to extract ui.xml\n"); + goto error; + } + } + + // NULL-terminate the string + xmlFile[len] = 0x00; + + // Before loading, mCurrentSet must be the loading package so we can find resources + pageSet = mCurrentSet; + mCurrentSet = new PageSet(xmlFile); + + ret = mCurrentSet->Load(pZip); + if (ret == 0) + { + mCurrentSet->SetPage(startpage); + mPageSets.insert(std::pair<std::string, PageSet*>(name, mCurrentSet)); + } + else + { + LOGERR("Package %s failed to load.\n", name.c_str()); + } + + // The first successful package we loaded is the base + if (mBaseSet == NULL) + mBaseSet = mCurrentSet; + + mCurrentSet = pageSet; + + if (pZip) { + mzCloseZipArchive(pZip); + sysReleaseMap(&map); + } + return ret; + +error: + LOGERR("An internal error has occurred.\n"); + if (pZip) { + mzCloseZipArchive(pZip); + sysReleaseMap(&map); + } + if (xmlFile) + free(xmlFile); + return -1; +} + +PageSet* PageManager::FindPackage(std::string name) +{ + std::map<std::string, PageSet*>::iterator iter; + + iter = mPageSets.find(name); + if (iter != mPageSets.end()) + return (*iter).second; + + LOGERR("Unable to locate package %s\n", name.c_str()); + return NULL; +} + +PageSet* PageManager::SelectPackage(std::string name) +{ + LOGINFO("Switching packages (%s)\n", name.c_str()); + PageSet* tmp; + + tmp = FindPackage(name); + if (tmp) + { + mCurrentSet = tmp; + mCurrentSet->NotifyVarChange("", ""); + } + else + LOGERR("Unable to find package.\n"); + + return mCurrentSet; +} + +int PageManager::ReloadPackage(std::string name, std::string package) +{ + std::map<std::string, PageSet*>::iterator iter; + + iter = mPageSets.find(name); + if (iter == mPageSets.end()) + return -1; + + if(mMouseCursor) + mMouseCursor->ResetData(gr_fb_width(), gr_fb_height()); + + PageSet* set = (*iter).second; + mPageSets.erase(iter); + + if (LoadPackage(name, package, "main") != 0) + { + LOGERR("Failed to load package '%s'.\n", package.c_str()); + mPageSets.insert(std::pair<std::string, PageSet*>(name, set)); + return -1; + } + if (mCurrentSet == set) + SelectPackage(name); + if (mBaseSet == set) + mBaseSet = mCurrentSet; + delete set; + return 0; +} + +void PageManager::ReleasePackage(std::string name) +{ + std::map<std::string, PageSet*>::iterator iter; + + iter = mPageSets.find(name); + if (iter == mPageSets.end()) + return; + + PageSet* set = (*iter).second; + mPageSets.erase(iter); + delete set; + return; +} + +int PageManager::ChangePage(std::string name) +{ + DataManager::SetValue("tw_operation_state", 0); + int ret = (mCurrentSet ? mCurrentSet->SetPage(name) : -1); + return ret; +} + +int PageManager::ChangeOverlay(std::string name) +{ + if (name.empty()) + return mCurrentSet->SetOverlay(NULL); + else + { + Page* page = mBaseSet ? mBaseSet->FindPage(name) : NULL; + return mCurrentSet->SetOverlay(page); + } +} + +const ResourceManager* PageManager::GetResources() +{ + return (mCurrentSet ? mCurrentSet->GetResources() : NULL); +} + +int PageManager::SwitchToConsole(void) +{ + PageSet* console = new PageSet(NULL); + + mCurrentSet = console; + return 0; +} + +int PageManager::EndConsole(void) +{ + if (mCurrentSet && mBaseSet) { + delete mCurrentSet; + mCurrentSet = mBaseSet; + return 0; + } + return -1; +} + +int PageManager::IsCurrentPage(Page* page) +{ + return (mCurrentSet ? mCurrentSet->IsCurrentPage(page) : 0); +} + +int PageManager::Render(void) +{ + int res = (mCurrentSet ? mCurrentSet->Render() : -1); + if(mMouseCursor) + mMouseCursor->Render(); + return res; +} + +HardwareKeyboard *PageManager::GetHardwareKeyboard() +{ + if(!mHardwareKeyboard) + mHardwareKeyboard = new HardwareKeyboard(); + return mHardwareKeyboard; +} + +xml_node<>* PageManager::FindStyle(std::string name) +{ + for (std::vector<xml_node<>*>::iterator itr = mCurrentSet->styles.begin(); itr != mCurrentSet->styles.end(); itr++) { + xml_node<>* node = (*itr)->first_node("style"); + + while (node) { + if (!node->first_attribute("name")) + continue; + + if (name == node->first_attribute("name")->value()) + return node; + node = node->next_sibling("style"); + } + } + return NULL; +} + +MouseCursor *PageManager::GetMouseCursor() +{ + if(!mMouseCursor) + mMouseCursor = new MouseCursor(gr_fb_width(), gr_fb_height()); + return mMouseCursor; +} + +void PageManager::LoadCursorData(xml_node<>* node) +{ + if(!mMouseCursor) + mMouseCursor = new MouseCursor(gr_fb_width(), gr_fb_height()); + + mMouseCursor->LoadData(node); +} + +int PageManager::Update(void) +{ + if(blankTimer.isScreenOff()) + return 0; + + int res = (mCurrentSet ? mCurrentSet->Update() : -1); + + if(mMouseCursor) + { + int c_res = mMouseCursor->Update(); + if(c_res > res) + res = c_res; + } + return res; +} + +int PageManager::NotifyTouch(TOUCH_STATE state, int x, int y) +{ + return (mCurrentSet ? mCurrentSet->NotifyTouch(state, x, y) : -1); +} + +int PageManager::NotifyKey(int key, bool down) +{ + return (mCurrentSet ? mCurrentSet->NotifyKey(key, down) : -1); +} + +int PageManager::NotifyKeyboard(int key) +{ + return (mCurrentSet ? mCurrentSet->NotifyKeyboard(key) : -1); +} + +int PageManager::SetKeyBoardFocus(int inFocus) +{ + return (mCurrentSet ? mCurrentSet->SetKeyBoardFocus(inFocus) : -1); +} + +int PageManager::NotifyVarChange(std::string varName, std::string value) +{ + return (mCurrentSet ? mCurrentSet->NotifyVarChange(varName, value) : -1); +} + +extern "C" void gui_notifyVarChange(const char *name, const char* value) +{ + if (!gGuiRunning) + return; + + PageManager::NotifyVarChange(name, value); +} diff --git a/gui/pages.h b/gui/pages.h new file mode 100644 index 000000000..d407162a2 --- /dev/null +++ b/gui/pages.h @@ -0,0 +1,7 @@ +#ifndef _PAGES_HEADER +#define _PAGES_HEADER + +void gui_notifyVarChange(const char *name, const char* value); + +#endif // _PAGES_HEADER + diff --git a/gui/pages.hpp b/gui/pages.hpp new file mode 100644 index 000000000..81112f979 --- /dev/null +++ b/gui/pages.hpp @@ -0,0 +1,170 @@ +// pages.hpp - Base classes for page manager of GUI + +#ifndef _PAGES_HEADER_HPP +#define _PAGES_HEADER_HPP + +#include "../minzip/Zip.h" +#include <vector> +#include <map> +#include "rapidxml.hpp" +using namespace rapidxml; + +enum TOUCH_STATE { + TOUCH_START = 0, + TOUCH_DRAG = 1, + TOUCH_RELEASE = 2, + TOUCH_HOLD = 3, + TOUCH_REPEAT = 4 +}; + +struct COLOR { + unsigned char red; + unsigned char green; + unsigned char blue; + unsigned char alpha; + COLOR() : red(0), green(0), blue(0), alpha(0) {} + COLOR(unsigned char r, unsigned char g, unsigned char b, unsigned char a = 255) + : red(r), green(g), blue(b), alpha(a) {} +}; + +// Utility Functions +int ConvertStrToColor(std::string str, COLOR* color); +int gui_forceRender(void); +int gui_changePage(std::string newPage); +int gui_changeOverlay(std::string newPage); +std::string gui_parse_text(string inText); + +class Resource; +class ResourceManager; +class RenderObject; +class ActionObject; +class InputObject; +class MouseCursor; +class GUIObject; +class HardwareKeyboard; + +class Page +{ +public: + Page(xml_node<>* page, std::vector<xml_node<>*> *templates); + virtual ~Page(); + + std::string GetName(void) { return mName; } + +public: + virtual int Render(void); + virtual int Update(void); + virtual int NotifyTouch(TOUCH_STATE state, int x, int y); + 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); + virtual void SetPageFocus(int inFocus); + +protected: + std::string mName; + std::vector<GUIObject*> mObjects; + std::vector<RenderObject*> mRenders; + std::vector<ActionObject*> mActions; + std::vector<InputObject*> mInputs; + + ActionObject* mTouchStart; + COLOR mBackground; + +protected: + bool ProcessNode(xml_node<>* page, std::vector<xml_node<>*> *templates, int depth); +}; + +class PageSet +{ +public: + PageSet(char* xmlFile); + virtual ~PageSet(); + +public: + int Load(ZipArchive* package); + int CheckInclude(ZipArchive* package, xml_document<> *parentDoc); + + Page* FindPage(std::string name); + int SetPage(std::string page); + int SetOverlay(Page* page); + const ResourceManager* GetResources(); + + // Helper routine for identifing if we're the current page + int IsCurrentPage(Page* page); + + // These are routing routines + int Render(void); + int Update(void); + int NotifyTouch(TOUCH_STATE state, int x, int y); + int NotifyKey(int key, bool down); + int NotifyKeyboard(int key); + int SetKeyBoardFocus(int inFocus); + int NotifyVarChange(std::string varName, std::string value); + + std::vector<xml_node<>*> styles; + +protected: + int LoadPages(xml_node<>* pages); + int LoadVariables(xml_node<>* vars); + +protected: + char* mXmlFile; + xml_document<> mDoc; + ResourceManager* mResources; + std::vector<Page*> mPages; + std::vector<xml_node<>*> templates; + Page* mCurrentPage; + std::vector<Page*> mOverlays; // Special case for popup dialogs and the lock screen + std::vector<xml_document<>*> mIncludedDocs; +}; + +class PageManager +{ +public: + // Used by GUI + static int LoadPackage(std::string name, std::string package, std::string startpage); + static PageSet* SelectPackage(std::string name); + static int ReloadPackage(std::string name, std::string package); + static void ReleasePackage(std::string name); + + // Used for actions and pages + static int ChangePage(std::string name); + static int ChangeOverlay(std::string name); + static const ResourceManager* GetResources(); + + // Used for console-only mode + static int SwitchToConsole(void); + static int EndConsole(void); + + // Helper to identify if a particular page is the active page + static int IsCurrentPage(Page* page); + + // These are routing routines + static int Render(void); + static int Update(void); + static int NotifyTouch(TOUCH_STATE state, int x, int y); + 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); + + static MouseCursor *GetMouseCursor(); + static void LoadCursorData(xml_node<>* node); + + static HardwareKeyboard *GetHardwareKeyboard(); + + static xml_node<>* FindStyle(std::string name); + +protected: + static PageSet* FindPackage(std::string name); + +protected: + static std::map<std::string, PageSet*> mPageSets; + static PageSet* mCurrentSet; + static PageSet* mBaseSet; + static MouseCursor *mMouseCursor; + static HardwareKeyboard *mHardwareKeyboard; +}; + +#endif // _PAGES_HEADER_HPP diff --git a/gui/partitionlist.cpp b/gui/partitionlist.cpp new file mode 100644 index 000000000..102802d7d --- /dev/null +++ b/gui/partitionlist.cpp @@ -0,0 +1,285 @@ +/* + Copyright 2013 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <string.h> +#include <sys/stat.h> +#include <dirent.h> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" +#include "../data.hpp" +#include "../partitions.hpp" + +GUIPartitionList::GUIPartitionList(xml_node<>* node) : GUIScrollList(node) +{ + xml_attribute<>* attr; + xml_node<>* child; + + mIconSelected = mIconUnselected = NULL; + mUpdate = 0; + updateList = false; + + child = FindNode(node, "icon"); + if (child) + { + mIconSelected = LoadAttrImage(child, "selected"); + mIconUnselected = LoadAttrImage(child, "unselected"); + } + + // Handle the result variable + child = FindNode(node, "data"); + if (child) + { + attr = child->first_attribute("name"); + if (attr) + mVariable = attr->value(); + attr = child->first_attribute("selectedlist"); + if (attr) + selectedList = attr->value(); + } + + int iconWidth = std::max(mIconSelected->GetWidth(), mIconUnselected->GetWidth()); + int iconHeight = std::max(mIconSelected->GetHeight(), mIconUnselected->GetHeight()); + SetMaxIconSize(iconWidth, iconHeight); + + child = FindNode(node, "listtype"); + if (child && (attr = child->first_attribute("name"))) { + ListType = attr->value(); + updateList = true; + } else { + mList.clear(); + LOGERR("No partition listtype specified for partitionlist GUI element\n"); + return; + } +} + +GUIPartitionList::~GUIPartitionList() +{ +} + +int GUIPartitionList::Update(void) +{ + if(!isConditionTrue()) + return 0; + + // Check for changes in mount points if the list type is mount and update the list and render if needed + if (ListType == "mount") { + int listSize = mList.size(); + for (int i = 0; i < listSize; i++) { + if (PartitionManager.Is_Mounted_By_Path(mList.at(i).Mount_Point) && !mList.at(i).selected) { + mList.at(i).selected = 1; + mUpdate = 1; + } else if (!PartitionManager.Is_Mounted_By_Path(mList.at(i).Mount_Point) && mList.at(i).selected) { + mList.at(i).selected = 0; + mUpdate = 1; + } + } + } + + GUIScrollList::Update(); + + if (updateList) { + int listSize = 0; + + // Completely update the list if needed -- Used primarily for + // restore as the list for restore will change depending on what + // partitions were backed up + mList.clear(); + PartitionManager.Get_Partition_List(ListType, &mList); + SetVisibleListLocation(0); + updateList = false; + mUpdate = 1; + if (ListType == "backup" || ListType == "flashimg") + MatchList(); + } + + if (mUpdate) { + mUpdate = 0; + if (Render() == 0) + return 2; + } + + return 0; +} + +int GUIPartitionList::NotifyVarChange(const std::string& varName, const std::string& value) +{ + GUIScrollList::NotifyVarChange(varName, value); + + if(!isConditionTrue()) + return 0; + + if (varName == mVariable && !mUpdate) + { + if (ListType == "storage") { + currentValue = value; + SetPosition(); + } else if (ListType == "backup") { + MatchList(); + } else if (ListType == "restore") { + updateList = true; + SetVisibleListLocation(0); + } + + mUpdate = 1; + return 0; + } + return 0; +} + +void GUIPartitionList::SetPageFocus(int inFocus) +{ + GUIScrollList::SetPageFocus(inFocus); + if (inFocus) { + if (ListType == "storage" || ListType == "flashimg") { + DataManager::GetValue(mVariable, currentValue); + SetPosition(); + } + updateList = true; + mUpdate = 1; + } +} + +void GUIPartitionList::MatchList(void) { + int i, listSize = mList.size(); + string variablelist, searchvalue; + size_t pos; + + DataManager::GetValue(mVariable, variablelist); + + for (i = 0; i < listSize; i++) { + searchvalue = mList.at(i).Mount_Point + ";"; + pos = variablelist.find(searchvalue); + if (pos != string::npos) { + mList.at(i).selected = 1; + } else { + mList.at(i).selected = 0; + } + } +} + +void GUIPartitionList::SetPosition() { + int listSize = mList.size(); + + SetVisibleListLocation(0); + for (int i = 0; i < listSize; i++) { + if (mList.at(i).Mount_Point == currentValue) { + mList.at(i).selected = 1; + SetVisibleListLocation(i); + } else { + mList.at(i).selected = 0; + } + } +} + +size_t GUIPartitionList::GetItemCount() +{ + return mList.size(); +} + +void GUIPartitionList::RenderItem(size_t itemindex, int yPos, bool selected) +{ + // note: the "selected" parameter above is for the currently touched item + // don't confuse it with the more persistent "selected" flag per list item used below + ImageResource* icon = mList.at(itemindex).selected ? mIconSelected : mIconUnselected; + const std::string& text = mList.at(itemindex).Display_Name; + + RenderStdItem(yPos, selected, icon, text.c_str()); +} + +void GUIPartitionList::NotifySelect(size_t item_selected) +{ + if (item_selected < mList.size()) { + int listSize = mList.size(); + if (ListType == "mount") { + if (!mList.at(item_selected).selected) { + if (PartitionManager.Mount_By_Path(mList.at(item_selected).Mount_Point, true)) { + mList.at(item_selected).selected = 1; + PartitionManager.Add_MTP_Storage(mList.at(item_selected).Mount_Point); + mUpdate = 1; + } + } else { + if (PartitionManager.UnMount_By_Path(mList.at(item_selected).Mount_Point, true)) { + mList.at(item_selected).selected = 0; + mUpdate = 1; + } + } + } else if (!mVariable.empty()) { + if (ListType == "storage") { + int i; + std::string str = mList.at(item_selected).Mount_Point; + bool update_size = false; + TWPartition* Part = PartitionManager.Find_Partition_By_Path(str); + if (Part == NULL) { + LOGERR("Unable to locate partition for '%s'\n", str.c_str()); + return; + } + if (!Part->Is_Mounted() && Part->Removable) + update_size = true; + if (!Part->Mount(true)) { + // Do Nothing + } else if (update_size && !Part->Update_Size(true)) { + // Do Nothing + } else { + for (i=0; i<listSize; i++) + mList.at(i).selected = 0; + + if (update_size) { + char free_space[255]; + sprintf(free_space, "%llu", Part->Free / 1024 / 1024); + mList.at(item_selected).Display_Name = Part->Storage_Name + " ("; + mList.at(item_selected).Display_Name += free_space; + mList.at(item_selected).Display_Name += "MB)"; + } + mList.at(item_selected).selected = 1; + mUpdate = 1; + + DataManager::SetValue(mVariable, str); + } + } else { + if (ListType == "flashimg") { // only one item can be selected for flashing images + for (int i=0; i<listSize; i++) + mList.at(i).selected = 0; + } + if (mList.at(item_selected).selected) + mList.at(item_selected).selected = 0; + else + mList.at(item_selected).selected = 1; + + int i; + string variablelist; + for (i=0; i<listSize; i++) { + if (mList.at(i).selected) { + variablelist += mList.at(i).Mount_Point + ";"; + } + } + + mUpdate = 1; + if (selectedList.empty()) + DataManager::SetValue(mVariable, variablelist); + else + DataManager::SetValue(selectedList, variablelist); + } + } + } +} diff --git a/gui/patternpassword.cpp b/gui/patternpassword.cpp new file mode 100644 index 000000000..ed152851f --- /dev/null +++ b/gui/patternpassword.cpp @@ -0,0 +1,318 @@ +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/types.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" + +GUIPatternPassword::GUIPatternPassword(xml_node<>* node) + : GUIObject(node) +{ + xml_attribute<>* attr; + xml_node<>* child; + + ResetActiveDots(); + mTrackingTouch = false; + mNeedRender = true; + + ConvertStrToColor("blue", &mDotColor); + ConvertStrToColor("white", &mActiveDotColor); + ConvertStrToColor("blue", &mLineColor); + + mDotImage = mActiveDotImage = NULL; + mDotCircle = mActiveDotCircle = NULL; + mDotRadius = 50; + mLineWidth = 35; + + mAction = NULL; + mUpdate = 0; + + if (!node) + return; + + LoadPlacement(FindNode(node, "placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH, &mPlacement); + + mAction = new GUIAction(node); + + child = FindNode(node, "dot"); + if(child) + { + mDotColor = LoadAttrColor(child, "color", mDotColor); + mActiveDotColor = LoadAttrColor(child, "activecolor", mActiveDotColor); + mDotRadius = LoadAttrIntScaleX(child, "radius", mDotRadius); + + mDotImage = LoadAttrImage(child, "image"); + mActiveDotImage = LoadAttrImage(child, "activeimage"); + } + + child = FindNode(node, "line"); + if(child) + { + mLineColor = LoadAttrColor(child, "color", mLineColor); + mLineWidth = LoadAttrIntScaleX(child, "width", mLineWidth); + } + + child = FindNode(node, "data"); + if(child) + mPassVar = LoadAttrString(child, "name", ""); + + + if(!mDotImage || !mDotImage->GetResource() || !mActiveDotImage || !mActiveDotImage->GetResource()) + { + mDotCircle = gr_render_circle(mDotRadius, mDotColor.red, mDotColor.green, mDotColor.blue, mDotColor.alpha); + mActiveDotCircle = gr_render_circle(mDotRadius/2, mActiveDotColor.red, mActiveDotColor.green, mActiveDotColor.blue, mActiveDotColor.alpha); + } + else + mDotRadius = mDotImage->GetWidth()/2; + + SetRenderPos(mRenderX, mRenderY, mRenderW, mRenderH); +} + +GUIPatternPassword::~GUIPatternPassword() +{ + delete mDotImage; + delete mActiveDotImage; + delete mAction; + + if(mDotCircle) + gr_free_surface(mDotCircle); + + if(mActiveDotCircle) + gr_free_surface(mActiveDotCircle); +} + +void GUIPatternPassword::ResetActiveDots() +{ + mConnectedDotsLen = 0; + mCurLineX = mCurLineY = -1; + for(int i = 0; i < 9; ++i) + mDots[i].active = false; +} + +int GUIPatternPassword::SetRenderPos(int x, int y, int w, int h) +{ + mRenderX = x; + mRenderY = y; + + if (w || h) + { + mRenderW = w; + mRenderH = h; + + mAction->SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH); + SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH); + } + + CalculateDotPositions(); + return 0; +} + +void GUIPatternPassword::CalculateDotPositions(void) +{ + const int step_x = (mRenderW - mDotRadius*2) / 2; + const int step_y = (mRenderH - mDotRadius*2) / 2; + int x = mRenderX; + int y = mRenderY; + + for(int r = 0; r < 3; ++r) + { + for(int c = 0; c < 3; ++c) + { + mDots[3*r+c].x = x; + mDots[3*r+c].y = y; + x += step_x; + } + x = mRenderX; + y += step_y; + } +} + +int GUIPatternPassword::Render(void) +{ + if(!isConditionTrue()) + return 0; + + gr_color(mLineColor.red, mLineColor.green, mLineColor.blue, mLineColor.alpha); + for(size_t i = 1; i < mConnectedDotsLen; ++i) { + const Dot& dp = mDots[mConnectedDots[i-1]]; + const Dot& dc = mDots[mConnectedDots[i]]; + gr_line(dp.x + mDotRadius, dp.y + mDotRadius, dc.x + mDotRadius, dc.y + mDotRadius, mLineWidth); + } + + if(mConnectedDotsLen > 0 && mTrackingTouch) { + const Dot& dc = mDots[mConnectedDots[mConnectedDotsLen-1]]; + gr_line(dc.x + mDotRadius, dc.y + mDotRadius, mCurLineX, mCurLineY, mLineWidth); + } + + for(int i = 0; i < 9; ++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) { + gr_blit(mActiveDotCircle, 0, 0, gr_get_width(mActiveDotCircle), gr_get_height(mActiveDotCircle), mDots[i].x + mDotRadius/2, mDots[i].y + mDotRadius/2); + } + } else { + if(mDots[i].active) { + gr_blit(mActiveDotImage->GetResource(), 0, 0, mActiveDotImage->GetWidth(), mActiveDotImage->GetHeight(), + mDots[i].x + (mDotRadius - mActiveDotImage->GetWidth()/2), mDots[i].y + (mDotRadius - mActiveDotImage->GetHeight()/2)); + } else { + gr_blit(mDotImage->GetResource(), 0, 0, mDotImage->GetWidth(), mDotImage->GetHeight(), mDots[i].x, mDots[i].y); + } + } + } + return 0; +} + +int GUIPatternPassword::Update(void) +{ + if(!isConditionTrue()) + return 0; + + int res = mNeedRender ? 2 : 1; + mNeedRender = false; + return res; +} + +bool GUIPatternPassword::IsInRect(int x, int y, int rx, int ry, int rw, int rh) +{ + return x >= rx && y >= ry && x <= rx+rw && y <= ry+rh; +} + +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)) + return i; + } + return -1; +} + +bool GUIPatternPassword::DotUsed(int dot_idx) +{ + for(size_t i = 0; i < mConnectedDotsLen; ++i) { + if(mConnectedDots[i] == dot_idx) + return true; + } + return false; +} + +void GUIPatternPassword::ConnectDot(int dot_idx) +{ + if(mConnectedDotsLen >= 9) + { + LOGERR("mConnectedDots in GUIPatternPassword has overflown!\n"); + return; + } + + mConnectedDots[mConnectedDotsLen++] = dot_idx; + mDots[dot_idx].active = true; +} + +void GUIPatternPassword::ConnectIntermediateDots(int 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 { + return; + } + + if(!DotUsed(mid)) + ConnectDot(mid); +} + +int GUIPatternPassword::NotifyTouch(TOUCH_STATE state, int x, int y) +{ + if(!isConditionTrue()) + return -1; + + switch (state) + { + case TOUCH_START: + { + const int dot_idx = InDot(x, y); + if(dot_idx == -1) + break; + + mTrackingTouch = true; + ResetActiveDots(); + ConnectDot(dot_idx); + DataManager::Vibrate("tw_button_vibrate"); + mCurLineX = x; + mCurLineY = y; + mNeedRender = true; + break; + } + case TOUCH_DRAG: + { + if(!mTrackingTouch) + break; + + const int dot_idx = InDot(x, y); + if(dot_idx != -1 && !DotUsed(dot_idx)) + { + ConnectIntermediateDots(dot_idx); + ConnectDot(dot_idx); + DataManager::Vibrate("tw_button_vibrate"); + } + + mCurLineX = x; + mCurLineY = y; + mNeedRender = true; + break; + } + case TOUCH_RELEASE: + { + if(!mTrackingTouch) + break; + + mNeedRender = true; + mTrackingTouch = false; + PatternDrawn(); + ResetActiveDots(); + break; + } + default: + break; + } + return 0; +} + +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); + } + + if(mAction) + mAction->doActions(); +} diff --git a/gui/progressbar.cpp b/gui/progressbar.cpp new file mode 100644 index 000000000..a478a40d0 --- /dev/null +++ b/gui/progressbar.cpp @@ -0,0 +1,226 @@ +// progressbar.cpp - GUIProgressBar object + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" + +GUIProgressBar::GUIProgressBar(xml_node<>* node) : GUIObject(node) +{ + xml_attribute<>* attr; + xml_node<>* child; + + mEmptyBar = NULL; + mFullBar = NULL; + mLastPos = 0; + mSlide = 0.0; + mSlideInc = 0.0; + + if (!node) + { + LOGERR("GUIProgressBar created without XML node\n"); + return; + } + + child = FindNode(node, "resource"); + if (child) + { + mEmptyBar = LoadAttrImage(child, "empty"); + mFullBar = LoadAttrImage(child, "full"); + } + + // Load the placement + LoadPlacement(FindNode(node, "placement"), &mRenderX, &mRenderY); + + // Load the data + child = FindNode(node, "data"); + if (child) + { + mMinValVar = LoadAttrString(child, "min"); + mMaxValVar = LoadAttrString(child, "max"); + mCurValVar = LoadAttrString(child, "name"); + } + + mRenderW = mEmptyBar->GetWidth(); + mRenderH = mEmptyBar->GetHeight(); +} + +int GUIProgressBar::Render(void) +{ + if(!isConditionTrue()) + return 0; + + // This handles making sure timing updates occur + Update(); + return RenderInternal(); +} + +int GUIProgressBar::RenderInternal(void) +{ + if (!mEmptyBar || !mEmptyBar->GetResource()) + return -1; + + if (!mFullBar || !mFullBar->GetResource()) + return -1; + + gr_blit(mEmptyBar->GetResource(), 0, 0, mRenderW, mRenderH, mRenderX, mRenderY); + gr_blit(mFullBar->GetResource(), 0, 0, mLastPos, mRenderH, mRenderX, mRenderY); + return 0; +} + +int GUIProgressBar::Update(void) +{ + if(!isConditionTrue()) + return 0; + + std::string str; + int min, max, cur, pos; + + if (mMinValVar.empty()) + min = 0; + else + { + str.clear(); + if (atoi(mMinValVar.c_str()) != 0) + str = mMinValVar; + else + DataManager::GetValue(mMinValVar, str); + min = atoi(str.c_str()); + } + + if (mMaxValVar.empty()) + max = 100; + else + { + str.clear(); + if (atoi(mMaxValVar.c_str()) != 0) + str = mMaxValVar; + else + DataManager::GetValue(mMaxValVar, str); + max = atoi(str.c_str()); + } + + str.clear(); + DataManager::GetValue(mCurValVar, str); + cur = atoi(str.c_str()); + + // Do slide, if needed + if (mSlideFrames) + { + mSlide += mSlideInc; + mSlideFrames--; + if (cur != (int) mSlide) + { + cur = (int) mSlide; + DataManager::SetValue(mCurValVar, cur); + } + } + + // Normalize to 0 + max -= min; + cur -= min; + min = 0; + + if (cur < min) + cur = min; + if (cur > max) + cur = max; + + if (max == 0) + pos = 0; + else + pos = (cur * mRenderW) / max; + + if (pos == mLastPos) + return 0; + + mLastPos = pos; + + if (RenderInternal() != 0) + return -1; + return 2; +} + +int GUIProgressBar::NotifyVarChange(const std::string& varName, const std::string& value) +{ + GUIObject::NotifyVarChange(varName, value); + + if(!isConditionTrue()) + return 0; + + static int nextPush = 0; + + if (varName.empty()) + { + nextPush = 0; + mLastPos = 0; + mSlide = 0.0; + mSlideInc = 0.0; + return 0; + } + + if (varName == "ui_progress_portion" || varName == "ui_progress_frames") + { + std::string str; + int cur; + + if (mSlideFrames) + { + mSlide += (mSlideInc * mSlideFrames); + cur = (int) mSlide; + DataManager::SetValue(mCurValVar, cur); + mSlideFrames = 0; + } + + if (nextPush) + { + mSlide += nextPush; + cur = (int) mSlide; + DataManager::SetValue(mCurValVar, cur); + nextPush = 0; + } + + if (varName == "ui_progress_portion") mSlide = atof(value.c_str()); + else + { + mSlideFrames = atol(value.c_str()); + if (mSlideFrames == 0) + { + // We're just holding this progress until the next push + nextPush = mSlide; + } + } + + if (mSlide > 0 && mSlideFrames > 0) + { + // Get the current position + str.clear(); + DataManager::GetValue(mCurValVar, str); + cur = atoi(str.c_str()); + + mSlideInc = (float) mSlide / (float) mSlideFrames; + mSlide = cur; + } + } + return 0; +} diff --git a/gui/rapidxml.hpp b/gui/rapidxml.hpp new file mode 100644 index 000000000..c0a7be44e --- /dev/null +++ b/gui/rapidxml.hpp @@ -0,0 +1,2616 @@ +#ifndef RAPIDXML_HPP_INCLUDED
+#define RAPIDXML_HPP_INCLUDED
+
+#define RAPIDXML_NO_EXCEPTIONS
+
+// Copyright (C) 2006, 2009 Marcin Kalicinski
+// Version 1.13
+// Revision $DateTime: 2009/05/13 01:46:17 $
+//! \file rapidxml.hpp This file contains rapidxml parser and DOM implementation
+
+// If standard library is disabled, user must provide implementations of required functions and typedefs
+#if !defined(RAPIDXML_NO_STDLIB)
+ #include <cstdlib> // For std::size_t
+ #include <cassert> // For assert
+ #include <new> // For placement new
+#endif
+
+// On MSVC, disable "conditional expression is constant" warning (level 4).
+// This warning is almost impossible to avoid with certain types of templated code
+#ifdef _MSC_VER
+ #pragma warning(push)
+ #pragma warning(disable:4127) // Conditional expression is constant
+#endif
+
+///////////////////////////////////////////////////////////////////////////
+// RAPIDXML_PARSE_ERROR
+
+#if defined(RAPIDXML_NO_EXCEPTIONS)
+
+#define RAPIDXML_PARSE_ERROR(what, where) { parse_error_handler(what, where); assert(0); }
+
+namespace rapidxml
+{
+ //! When exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS,
+ //! this function is called to notify user about the error.
+ //! It must be defined by the user.
+ //! <br><br>
+ //! This function cannot return. If it does, the results are undefined.
+ //! <br><br>
+ //! A very simple definition might look like that:
+ //! <pre>
+ //! void %rapidxml::%parse_error_handler(const char *what, void *where)
+ //! {
+ //! std::cout << "Parse error: " << what << "\n";
+ //! std::abort();
+ //! }
+ //! </pre>
+ //! \param what Human readable description of the error.
+ //! \param where Pointer to character data where error was detected.
+ void parse_error_handler(const char *what, void *where);
+}
+
+#else
+
+#include <exception> // For std::exception
+
+#define RAPIDXML_PARSE_ERROR(what, where) throw parse_error(what, where)
+
+namespace rapidxml
+{
+
+ //! Parse error exception.
+ //! This exception is thrown by the parser when an error occurs.
+ //! Use what() function to get human-readable error message.
+ //! Use where() function to get a pointer to position within source text where error was detected.
+ //! <br><br>
+ //! If throwing exceptions by the parser is undesirable,
+ //! it can be disabled by defining RAPIDXML_NO_EXCEPTIONS macro before rapidxml.hpp is included.
+ //! This will cause the parser to call rapidxml::parse_error_handler() function instead of throwing an exception.
+ //! This function must be defined by the user.
+ //! <br><br>
+ //! This class derives from <code>std::exception</code> class.
+ class parse_error: public std::exception
+ {
+
+ public:
+
+ //! Constructs parse error
+ parse_error(const char *what, void *where)
+ : m_what(what)
+ , m_where(where)
+ {
+ }
+
+ //! Gets human readable description of error.
+ //! \return Pointer to null terminated description of the error.
+ virtual const char *what() const throw()
+ {
+ return m_what;
+ }
+
+ //! Gets pointer to character data where error happened.
+ //! Ch should be the same as char type of xml_document that produced the error.
+ //! \return Pointer to location within the parsed string where error occured.
+ template<class Ch>
+ Ch *where() const
+ {
+ return reinterpret_cast<Ch *>(m_where);
+ }
+
+ private:
+
+ const char *m_what;
+ void *m_where;
+
+ };
+}
+
+#endif
+
+///////////////////////////////////////////////////////////////////////////
+// Pool sizes
+
+#ifndef RAPIDXML_STATIC_POOL_SIZE
+ // Size of static memory block of memory_pool.
+ // Define RAPIDXML_STATIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value.
+ // No dynamic memory allocations are performed by memory_pool until static memory is exhausted.
+ #define RAPIDXML_STATIC_POOL_SIZE (64 * 1024)
+#endif
+
+#ifndef RAPIDXML_DYNAMIC_POOL_SIZE
+ // Size of dynamic memory block of memory_pool.
+ // Define RAPIDXML_DYNAMIC_POOL_SIZE before including rapidxml.hpp if you want to override the default value.
+ // After the static block is exhausted, dynamic blocks with approximately this size are allocated by memory_pool.
+ #define RAPIDXML_DYNAMIC_POOL_SIZE (64 * 1024)
+#endif
+
+#ifndef RAPIDXML_ALIGNMENT
+ // Memory allocation alignment.
+ // Define RAPIDXML_ALIGNMENT before including rapidxml.hpp if you want to override the default value, which is the size of pointer.
+ // All memory allocations for nodes, attributes and strings will be aligned to this value.
+ // This must be a power of 2 and at least 1, otherwise memory_pool will not work.
+ #define RAPIDXML_ALIGNMENT sizeof(void *)
+#endif
+
+namespace rapidxml
+{
+ // Forward declarations
+ template<class Ch> class xml_node;
+ template<class Ch> class xml_attribute;
+ template<class Ch> class xml_document;
+
+ //! Enumeration listing all node types produced by the parser.
+ //! Use xml_node::type() function to query node type.
+ enum node_type
+ {
+ node_document, //!< A document node. Name and value are empty.
+ node_element, //!< An element node. Name contains element name. Value contains text of first data node.
+ node_data, //!< A data node. Name is empty. Value contains data text.
+ node_cdata, //!< A CDATA node. Name is empty. Value contains data text.
+ node_comment, //!< A comment node. Name is empty. Value contains comment text.
+ node_declaration, //!< A declaration node. Name and value are empty. Declaration parameters (version, encoding and standalone) are in node attributes.
+ node_doctype, //!< A DOCTYPE node. Name is empty. Value contains DOCTYPE text.
+ node_pi //!< A PI node. Name contains target. Value contains instructions.
+ };
+
+ ///////////////////////////////////////////////////////////////////////
+ // Parsing flags
+
+ //! Parse flag instructing the parser to not create data nodes.
+ //! Text of first data node will still be placed in value of parent element, unless rapidxml::parse_no_element_values flag is also specified.
+ //! Can be combined with other flags by use of | operator.
+ //! <br><br>
+ //! See xml_document::parse() function.
+ const int parse_no_data_nodes = 0x1;
+
+ //! Parse flag instructing the parser to not use text of first data node as a value of parent element.
+ //! Can be combined with other flags by use of | operator.
+ //! Note that child data nodes of element node take precendence over its value when printing.
+ //! That is, if element has one or more child data nodes <em>and</em> a value, the value will be ignored.
+ //! Use rapidxml::parse_no_data_nodes flag to prevent creation of data nodes if you want to manipulate data using values of elements.
+ //! <br><br>
+ //! See xml_document::parse() function.
+ const int parse_no_element_values = 0x2;
+
+ //! Parse flag instructing the parser to not place zero terminators after strings in the source text.
+ //! By default zero terminators are placed, modifying source text.
+ //! Can be combined with other flags by use of | operator.
+ //! <br><br>
+ //! See xml_document::parse() function.
+ const int parse_no_string_terminators = 0x4;
+
+ //! Parse flag instructing the parser to not translate entities in the source text.
+ //! By default entities are translated, modifying source text.
+ //! Can be combined with other flags by use of | operator.
+ //! <br><br>
+ //! See xml_document::parse() function.
+ const int parse_no_entity_translation = 0x8;
+
+ //! Parse flag instructing the parser to disable UTF-8 handling and assume plain 8 bit characters.
+ //! By default, UTF-8 handling is enabled.
+ //! Can be combined with other flags by use of | operator.
+ //! <br><br>
+ //! See xml_document::parse() function.
+ const int parse_no_utf8 = 0x10;
+
+ //! Parse flag instructing the parser to create XML declaration node.
+ //! By default, declaration node is not created.
+ //! Can be combined with other flags by use of | operator.
+ //! <br><br>
+ //! See xml_document::parse() function.
+ const int parse_declaration_node = 0x20;
+
+ //! Parse flag instructing the parser to create comments nodes.
+ //! By default, comment nodes are not created.
+ //! Can be combined with other flags by use of | operator.
+ //! <br><br>
+ //! See xml_document::parse() function.
+ const int parse_comment_nodes = 0x40;
+
+ //! Parse flag instructing the parser to create DOCTYPE node.
+ //! By default, doctype node is not created.
+ //! Although W3C specification allows at most one DOCTYPE node, RapidXml will silently accept documents with more than one.
+ //! Can be combined with other flags by use of | operator.
+ //! <br><br>
+ //! See xml_document::parse() function.
+ const int parse_doctype_node = 0x80;
+
+ //! Parse flag instructing the parser to create PI nodes.
+ //! By default, PI nodes are not created.
+ //! Can be combined with other flags by use of | operator.
+ //! <br><br>
+ //! See xml_document::parse() function.
+ const int parse_pi_nodes = 0x100;
+
+ //! Parse flag instructing the parser to validate closing tag names.
+ //! If not set, name inside closing tag is irrelevant to the parser.
+ //! By default, closing tags are not validated.
+ //! Can be combined with other flags by use of | operator.
+ //! <br><br>
+ //! See xml_document::parse() function.
+ const int parse_validate_closing_tags = 0x200;
+
+ //! Parse flag instructing the parser to trim all leading and trailing whitespace of data nodes.
+ //! By default, whitespace is not trimmed.
+ //! This flag does not cause the parser to modify source text.
+ //! Can be combined with other flags by use of | operator.
+ //! <br><br>
+ //! See xml_document::parse() function.
+ const int parse_trim_whitespace = 0x400;
+
+ //! Parse flag instructing the parser to condense all whitespace runs of data nodes to a single space character.
+ //! Trimming of leading and trailing whitespace of data is controlled by rapidxml::parse_trim_whitespace flag.
+ //! By default, whitespace is not normalized.
+ //! If this flag is specified, source text will be modified.
+ //! Can be combined with other flags by use of | operator.
+ //! <br><br>
+ //! See xml_document::parse() function.
+ const int parse_normalize_whitespace = 0x800;
+
+ // Compound flags
+
+ //! Parse flags which represent default behaviour of the parser.
+ //! This is always equal to 0, so that all other flags can be simply ored together.
+ //! Normally there is no need to inconveniently disable flags by anding with their negated (~) values.
+ //! This also means that meaning of each flag is a <i>negation</i> of the default setting.
+ //! For example, if flag name is rapidxml::parse_no_utf8, it means that utf-8 is <i>enabled</i> by default,
+ //! and using the flag will disable it.
+ //! <br><br>
+ //! See xml_document::parse() function.
+ const int parse_default = 0;
+
+ //! A combination of parse flags that forbids any modifications of the source text.
+ //! This also results in faster parsing. However, note that the following will occur:
+ //! <ul>
+ //! <li>names and values of nodes will not be zero terminated, you have to use xml_base::name_size() and xml_base::value_size() functions to determine where name and value ends</li>
+ //! <li>entities will not be translated</li>
+ //! <li>whitespace will not be normalized</li>
+ //! </ul>
+ //! See xml_document::parse() function.
+ const int parse_non_destructive = parse_no_string_terminators | parse_no_entity_translation;
+
+ //! A combination of parse flags resulting in fastest possible parsing, without sacrificing important data.
+ //! <br><br>
+ //! See xml_document::parse() function.
+ const int parse_fastest = parse_non_destructive | parse_no_data_nodes;
+
+ //! A combination of parse flags resulting in largest amount of data being extracted.
+ //! This usually results in slowest parsing.
+ //! <br><br>
+ //! See xml_document::parse() function.
+ const int parse_full = parse_declaration_node | parse_comment_nodes | parse_doctype_node | parse_pi_nodes | parse_validate_closing_tags;
+
+ ///////////////////////////////////////////////////////////////////////
+ // Internals
+
+ //! \cond internal
+ namespace internal
+ {
+
+ // Struct that contains lookup tables for the parser
+ // It must be a template to allow correct linking (because it has static data members, which are defined in a header file).
+ template<int Dummy>
+ struct lookup_tables
+ {
+ static const unsigned char lookup_whitespace[256]; // Whitespace table
+ static const unsigned char lookup_node_name[256]; // Node name table
+ static const unsigned char lookup_text[256]; // Text table
+ static const unsigned char lookup_text_pure_no_ws[256]; // Text table
+ static const unsigned char lookup_text_pure_with_ws[256]; // Text table
+ static const unsigned char lookup_attribute_name[256]; // Attribute name table
+ static const unsigned char lookup_attribute_data_1[256]; // Attribute data table with single quote
+ static const unsigned char lookup_attribute_data_1_pure[256]; // Attribute data table with single quote
+ static const unsigned char lookup_attribute_data_2[256]; // Attribute data table with double quotes
+ static const unsigned char lookup_attribute_data_2_pure[256]; // Attribute data table with double quotes
+ static const unsigned char lookup_digits[256]; // Digits
+ static const unsigned char lookup_upcase[256]; // To uppercase conversion table for ASCII characters
+ };
+
+ // Find length of the string
+ template<class Ch>
+ inline std::size_t measure(const Ch *p)
+ {
+ const Ch *tmp = p;
+ while (*tmp)
+ ++tmp;
+ return tmp - p;
+ }
+
+ // Compare strings for equality
+ template<class Ch>
+ inline bool compare(const Ch *p1, std::size_t size1, const Ch *p2, std::size_t size2, bool case_sensitive)
+ {
+ if (size1 != size2)
+ return false;
+ if (case_sensitive)
+ {
+ for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2)
+ if (*p1 != *p2)
+ return false;
+ }
+ else
+ {
+ for (const Ch *end = p1 + size1; p1 < end; ++p1, ++p2)
+ if (lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p1)] != lookup_tables<0>::lookup_upcase[static_cast<unsigned char>(*p2)])
+ return false;
+ }
+ return true;
+ }
+ }
+ //! \endcond
+
+ ///////////////////////////////////////////////////////////////////////
+ // Memory pool
+
+ //! This class is used by the parser to create new nodes and attributes, without overheads of dynamic memory allocation.
+ //! In most cases, you will not need to use this class directly.
+ //! However, if you need to create nodes manually or modify names/values of nodes,
+ //! you are encouraged to use memory_pool of relevant xml_document to allocate the memory.
+ //! Not only is this faster than allocating them by using <code>new</code> operator,
+ //! but also their lifetime will be tied to the lifetime of document,
+ //! possibly simplyfing memory management.
+ //! <br><br>
+ //! Call allocate_node() or allocate_attribute() functions to obtain new nodes or attributes from the pool.
+ //! You can also call allocate_string() function to allocate strings.
+ //! Such strings can then be used as names or values of nodes without worrying about their lifetime.
+ //! Note that there is no <code>free()</code> function -- all allocations are freed at once when clear() function is called,
+ //! or when the pool is destroyed.
+ //! <br><br>
+ //! It is also possible to create a standalone memory_pool, and use it
+ //! to allocate nodes, whose lifetime will not be tied to any document.
+ //! <br><br>
+ //! Pool maintains <code>RAPIDXML_STATIC_POOL_SIZE</code> bytes of statically allocated memory.
+ //! Until static memory is exhausted, no dynamic memory allocations are done.
+ //! When static memory is exhausted, pool allocates additional blocks of memory of size <code>RAPIDXML_DYNAMIC_POOL_SIZE</code> each,
+ //! by using global <code>new[]</code> and <code>delete[]</code> operators.
+ //! This behaviour can be changed by setting custom allocation routines.
+ //! Use set_allocator() function to set them.
+ //! <br><br>
+ //! Allocations for nodes, attributes and strings are aligned at <code>RAPIDXML_ALIGNMENT</code> bytes.
+ //! This value defaults to the size of pointer on target architecture.
+ //! <br><br>
+ //! To obtain absolutely top performance from the parser,
+ //! it is important that all nodes are allocated from a single, contiguous block of memory.
+ //! Otherwise, cache misses when jumping between two (or more) disjoint blocks of memory can slow down parsing quite considerably.
+ //! If required, you can tweak <code>RAPIDXML_STATIC_POOL_SIZE</code>, <code>RAPIDXML_DYNAMIC_POOL_SIZE</code> and <code>RAPIDXML_ALIGNMENT</code>
+ //! to obtain best wasted memory to performance compromise.
+ //! To do it, define their values before rapidxml.hpp file is included.
+ //! \param Ch Character type of created nodes.
+ template<class Ch = char>
+ class memory_pool
+ {
+
+ public:
+
+ //! \cond internal
+ typedef void *(alloc_func)(std::size_t); // Type of user-defined function used to allocate memory
+ typedef void (free_func)(void *); // Type of user-defined function used to free memory
+ //! \endcond
+
+ //! Constructs empty pool with default allocator functions.
+ memory_pool()
+ : m_alloc_func(0)
+ , m_free_func(0)
+ {
+ init();
+ }
+
+ //! Destroys pool and frees all the memory.
+ //! This causes memory occupied by nodes allocated by the pool to be freed.
+ //! Nodes allocated from the pool are no longer valid.
+ ~memory_pool()
+ {
+ clear();
+ }
+
+ //! Allocates a new node from the pool, and optionally assigns name and value to it.
+ //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.
+ //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function
+ //! will call rapidxml::parse_error_handler() function.
+ //! \param type Type of node to create.
+ //! \param name Name to assign to the node, or 0 to assign no name.
+ //! \param value Value to assign to the node, or 0 to assign no value.
+ //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string.
+ //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string.
+ //! \return Pointer to allocated node. This pointer will never be NULL.
+ xml_node<Ch> *allocate_node(node_type type,
+ const Ch *name = 0, const Ch *value = 0,
+ std::size_t name_size = 0, std::size_t value_size = 0)
+ {
+ void *memory = allocate_aligned(sizeof(xml_node<Ch>));
+ xml_node<Ch> *node = new(memory) xml_node<Ch>(type);
+ if (name)
+ {
+ if (name_size > 0)
+ node->name(name, name_size);
+ else
+ node->name(name);
+ }
+ if (value)
+ {
+ if (value_size > 0)
+ node->value(value, value_size);
+ else
+ node->value(value);
+ }
+ return node;
+ }
+
+ //! Allocates a new attribute from the pool, and optionally assigns name and value to it.
+ //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.
+ //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function
+ //! will call rapidxml::parse_error_handler() function.
+ //! \param name Name to assign to the attribute, or 0 to assign no name.
+ //! \param value Value to assign to the attribute, or 0 to assign no value.
+ //! \param name_size Size of name to assign, or 0 to automatically calculate size from name string.
+ //! \param value_size Size of value to assign, or 0 to automatically calculate size from value string.
+ //! \return Pointer to allocated attribute. This pointer will never be NULL.
+ xml_attribute<Ch> *allocate_attribute(const Ch *name = 0, const Ch *value = 0,
+ std::size_t name_size = 0, std::size_t value_size = 0)
+ {
+ void *memory = allocate_aligned(sizeof(xml_attribute<Ch>));
+ xml_attribute<Ch> *attribute = new(memory) xml_attribute<Ch>;
+ if (name)
+ {
+ if (name_size > 0)
+ attribute->name(name, name_size);
+ else
+ attribute->name(name);
+ }
+ if (value)
+ {
+ if (value_size > 0)
+ attribute->value(value, value_size);
+ else
+ attribute->value(value);
+ }
+ return attribute;
+ }
+
+ //! Allocates a char array of given size from the pool, and optionally copies a given string to it.
+ //! If the allocation request cannot be accomodated, this function will throw <code>std::bad_alloc</code>.
+ //! If exceptions are disabled by defining RAPIDXML_NO_EXCEPTIONS, this function
+ //! will call rapidxml::parse_error_handler() function.
+ //! \param source String to initialize the allocated memory with, or 0 to not initialize it.
+ //! \param size Number of characters to allocate, or zero to calculate it automatically from source string length; if size is 0, source string must be specified and null terminated.
+ //! \return Pointer to allocated char array. This pointer will never be NULL.
+ Ch *allocate_string(const Ch *source = 0, std::size_t size = 0)
+ {
+ assert(source || size); // Either source or size (or both) must be specified
+ if (size == 0)
+ size = internal::measure(source) + 1;
+ Ch *result = static_cast<Ch *>(allocate_aligned(size * sizeof(Ch)));
+ if (source)
+ for (std::size_t i = 0; i < size; ++i)
+ result[i] = source[i];
+ return result;
+ }
+
+ //! Clones an xml_node and its hierarchy of child nodes and attributes.
+ //! Nodes and attributes are allocated from this memory pool.
+ //! Names and values are not cloned, they are shared between the clone and the source.
+ //! Result node can be optionally specified as a second parameter,
+ //! in which case its contents will be replaced with cloned source node.
+ //! This is useful when you want to clone entire document.
+ //! \param source Node to clone.
+ //! \param result Node to put results in, or 0 to automatically allocate result node
+ //! \return Pointer to cloned node. This pointer will never be NULL.
+ xml_node<Ch> *clone_node(const xml_node<Ch> *source, xml_node<Ch> *result = 0)
+ {
+ // Prepare result node
+ if (result)
+ {
+ result->remove_all_attributes();
+ result->remove_all_nodes();
+ result->type(source->type());
+ }
+ else
+ result = allocate_node(source->type());
+
+ // Clone name and value
+ result->name(source->name(), source->name_size());
+ result->value(source->value(), source->value_size());
+
+ // Clone child nodes and attributes
+ for (xml_node<Ch> *child = source->first_node(); child; child = child->next_sibling())
+ result->append_node(clone_node(child));
+ for (xml_attribute<Ch> *attr = source->first_attribute(); attr; attr = attr->next_attribute())
+ result->append_attribute(allocate_attribute(attr->name(), attr->value(), attr->name_size(), attr->value_size()));
+
+ return result;
+ }
+
+ //! Clears the pool.
+ //! This causes memory occupied by nodes allocated by the pool to be freed.
+ //! Any nodes or strings allocated from the pool will no longer be valid.
+ void clear()
+ {
+ while (m_begin != m_static_memory)
+ {
+ char *previous_begin = reinterpret_cast<header *>(align(m_begin))->previous_begin;
+ if (m_free_func)
+ m_free_func(m_begin);
+ else
+ delete[] m_begin;
+ m_begin = previous_begin;
+ }
+ init();
+ }
+
+ //! Sets or resets the user-defined memory allocation functions for the pool.
+ //! This can only be called when no memory is allocated from the pool yet, otherwise results are undefined.
+ //! Allocation function must not return invalid pointer on failure. It should either throw,
+ //! stop the program, or use <code>longjmp()</code> function to pass control to other place of program.
+ //! If it returns invalid pointer, results are undefined.
+ //! <br><br>
+ //! User defined allocation functions must have the following forms:
+ //! <br><code>
+ //! <br>void *allocate(std::size_t size);
+ //! <br>void free(void *pointer);
+ //! </code><br>
+ //! \param af Allocation function, or 0 to restore default function
+ //! \param ff Free function, or 0 to restore default function
+ void set_allocator(alloc_func *af, free_func *ff)
+ {
+ assert(m_begin == m_static_memory && m_ptr == align(m_begin)); // Verify that no memory is allocated yet
+ m_alloc_func = af;
+ m_free_func = ff;
+ }
+
+ private:
+
+ struct header
+ {
+ char *previous_begin;
+ };
+
+ void init()
+ {
+ m_begin = m_static_memory;
+ m_ptr = align(m_begin);
+ m_end = m_static_memory + sizeof(m_static_memory);
+ }
+
+ char *align(char *ptr)
+ {
+ std::size_t alignment = ((RAPIDXML_ALIGNMENT - (std::size_t(ptr) & (RAPIDXML_ALIGNMENT - 1))) & (RAPIDXML_ALIGNMENT - 1));
+ return ptr + alignment;
+ }
+
+ char *allocate_raw(std::size_t size)
+ {
+ // Allocate
+ void *memory;
+ if (m_alloc_func) // Allocate memory using either user-specified allocation function or global operator new[]
+ {
+ memory = m_alloc_func(size);
+ assert(memory); // Allocator is not allowed to return 0, on failure it must either throw, stop the program or use longjmp
+ }
+ else
+ {
+ memory = new char[size];
+#ifdef RAPIDXML_NO_EXCEPTIONS
+ if (!memory) // If exceptions are disabled, verify memory allocation, because new will not be able to throw bad_alloc
+ RAPIDXML_PARSE_ERROR("out of memory", 0);
+#endif
+ }
+ return static_cast<char *>(memory);
+ }
+
+ void *allocate_aligned(std::size_t size)
+ {
+ // Calculate aligned pointer
+ char *result = align(m_ptr);
+
+ // If not enough memory left in current pool, allocate a new pool
+ if (result + size > m_end)
+ {
+ // Calculate required pool size (may be bigger than RAPIDXML_DYNAMIC_POOL_SIZE)
+ std::size_t pool_size = RAPIDXML_DYNAMIC_POOL_SIZE;
+ if (pool_size < size)
+ pool_size = size;
+
+ // Allocate
+ std::size_t alloc_size = sizeof(header) + (2 * RAPIDXML_ALIGNMENT - 2) + pool_size; // 2 alignments required in worst case: one for header, one for actual allocation
+ char *raw_memory = allocate_raw(alloc_size);
+
+ // Setup new pool in allocated memory
+ char *pool = align(raw_memory);
+ header *new_header = reinterpret_cast<header *>(pool);
+ new_header->previous_begin = m_begin;
+ m_begin = raw_memory;
+ m_ptr = pool + sizeof(header);
+ m_end = raw_memory + alloc_size;
+
+ // Calculate aligned pointer again using new pool
+ result = align(m_ptr);
+ }
+
+ // Update pool and return aligned pointer
+ m_ptr = result + size;
+ return result;
+ }
+
+ char *m_begin; // Start of raw memory making up current pool
+ char *m_ptr; // First free byte in current pool
+ char *m_end; // One past last available byte in current pool
+ char m_static_memory[RAPIDXML_STATIC_POOL_SIZE]; // Static raw memory
+ alloc_func *m_alloc_func; // Allocator function, or 0 if default is to be used
+ free_func *m_free_func; // Free function, or 0 if default is to be used
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // XML base
+
+ //! Base class for xml_node and xml_attribute implementing common functions:
+ //! name(), name_size(), value(), value_size() and parent().
+ //! \param Ch Character type to use
+ template<class Ch = char>
+ class xml_base
+ {
+
+ public:
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Construction & destruction
+
+ // Construct a base with empty name, value and parent
+ xml_base()
+ : m_name(0)
+ , m_value(0)
+ , m_parent(0)
+ {
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Node data access
+
+ //! Gets name of the node.
+ //! Interpretation of name depends on type of node.
+ //! Note that name will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse.
+ //! <br><br>
+ //! Use name_size() function to determine length of the name.
+ //! \return Name of node, or empty string if node has no name.
+ Ch *name() const
+ {
+ return m_name ? m_name : nullstr();
+ }
+
+ //! Gets size of node name, not including terminator character.
+ //! This function works correctly irrespective of whether name is or is not zero terminated.
+ //! \return Size of node name, in characters.
+ std::size_t name_size() const
+ {
+ return m_name ? m_name_size : 0;
+ }
+
+ //! Gets value of node.
+ //! Interpretation of value depends on type of node.
+ //! Note that value will not be zero-terminated if rapidxml::parse_no_string_terminators option was selected during parse.
+ //! <br><br>
+ //! Use value_size() function to determine length of the value.
+ //! \return Value of node, or empty string if node has no value.
+ Ch *value() const
+ {
+ return m_value ? m_value : nullstr();
+ }
+
+ //! Gets size of node value, not including terminator character.
+ //! This function works correctly irrespective of whether value is or is not zero terminated.
+ //! \return Size of node value, in characters.
+ std::size_t value_size() const
+ {
+ return m_value ? m_value_size : 0;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Node modification
+
+ //! Sets name of node to a non zero-terminated string.
+ //! See \ref ownership_of_strings.
+ //! <br><br>
+ //! Note that node does not own its name or value, it only stores a pointer to it.
+ //! It will not delete or otherwise free the pointer on destruction.
+ //! It is reponsibility of the user to properly manage lifetime of the string.
+ //! The easiest way to achieve it is to use memory_pool of the document to allocate the string -
+ //! on destruction of the document the string will be automatically freed.
+ //! <br><br>
+ //! Size of name must be specified separately, because name does not have to be zero terminated.
+ //! Use name(const Ch *) function to have the length automatically calculated (string must be zero terminated).
+ //! \param name Name of node to set. Does not have to be zero terminated.
+ //! \param size Size of name, in characters. This does not include zero terminator, if one is present.
+ void name(const Ch *name, std::size_t size)
+ {
+ m_name = const_cast<Ch *>(name);
+ m_name_size = size;
+ }
+
+ //! Sets name of node to a zero-terminated string.
+ //! See also \ref ownership_of_strings and xml_node::name(const Ch *, std::size_t).
+ //! \param name Name of node to set. Must be zero terminated.
+ void name(const Ch *name)
+ {
+ this->name(name, internal::measure(name));
+ }
+
+ //! Sets value of node to a non zero-terminated string.
+ //! See \ref ownership_of_strings.
+ //! <br><br>
+ //! Note that node does not own its name or value, it only stores a pointer to it.
+ //! It will not delete or otherwise free the pointer on destruction.
+ //! It is reponsibility of the user to properly manage lifetime of the string.
+ //! The easiest way to achieve it is to use memory_pool of the document to allocate the string -
+ //! on destruction of the document the string will be automatically freed.
+ //! <br><br>
+ //! Size of value must be specified separately, because it does not have to be zero terminated.
+ //! Use value(const Ch *) function to have the length automatically calculated (string must be zero terminated).
+ //! <br><br>
+ //! If an element has a child node of type node_data, it will take precedence over element value when printing.
+ //! If you want to manipulate data of elements using values, use parser flag rapidxml::parse_no_data_nodes to prevent creation of data nodes by the parser.
+ //! \param value value of node to set. Does not have to be zero terminated.
+ //! \param size Size of value, in characters. This does not include zero terminator, if one is present.
+ void value(const Ch *value, std::size_t size)
+ {
+ m_value = const_cast<Ch *>(value);
+ m_value_size = size;
+ }
+
+ //! Sets value of node to a zero-terminated string.
+ //! See also \ref ownership_of_strings and xml_node::value(const Ch *, std::size_t).
+ //! \param value Vame of node to set. Must be zero terminated.
+ void value(const Ch *value)
+ {
+ this->value(value, internal::measure(value));
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Related nodes access
+
+ //! Gets node parent.
+ //! \return Pointer to parent node, or 0 if there is no parent.
+ xml_node<Ch> *parent() const
+ {
+ return m_parent;
+ }
+
+ protected:
+
+ // Return empty string
+ static Ch *nullstr()
+ {
+ static Ch zero = Ch('\0');
+ return &zero;
+ }
+
+ Ch *m_name; // Name of node, or 0 if no name
+ Ch *m_value; // Value of node, or 0 if no value
+ std::size_t m_name_size; // Length of node name, or undefined of no name
+ std::size_t m_value_size; // Length of node value, or undefined if no value
+ xml_node<Ch> *m_parent; // Pointer to parent node, or 0 if none
+
+ };
+
+ //! Class representing attribute node of XML document.
+ //! Each attribute has name and value strings, which are available through name() and value() functions (inherited from xml_base).
+ //! Note that after parse, both name and value of attribute will point to interior of source text used for parsing.
+ //! Thus, this text must persist in memory for the lifetime of attribute.
+ //! \param Ch Character type to use.
+ template<class Ch = char>
+ class xml_attribute: public xml_base<Ch>
+ {
+
+ friend class xml_node<Ch>;
+
+ public:
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Construction & destruction
+
+ //! Constructs an empty attribute with the specified type.
+ //! Consider using memory_pool of appropriate xml_document if allocating attributes manually.
+ xml_attribute()
+ {
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Related nodes access
+
+ //! Gets document of which attribute is a child.
+ //! \return Pointer to document that contains this attribute, or 0 if there is no parent document.
+ xml_document<Ch> *document() const
+ {
+ if (xml_node<Ch> *node = this->parent())
+ {
+ while (node->parent())
+ node = node->parent();
+ return node->type() == node_document ? static_cast<xml_document<Ch> *>(node) : 0;
+ }
+ else
+ return 0;
+ }
+
+ //! Gets previous attribute, optionally matching attribute name.
+ //! \param name Name of attribute to find, or 0 to return previous attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+ //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+ //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+ //! \return Pointer to found attribute, or 0 if not found.
+ xml_attribute<Ch> *previous_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const
+ {
+ if (name)
+ {
+ if (name_size == 0)
+ name_size = internal::measure(name);
+ for (xml_attribute<Ch> *attribute = m_prev_attribute; attribute; attribute = attribute->m_prev_attribute)
+ if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive))
+ return attribute;
+ return 0;
+ }
+ else
+ return this->m_parent ? m_prev_attribute : 0;
+ }
+
+ //! Gets next attribute, optionally matching attribute name.
+ //! \param name Name of attribute to find, or 0 to return next attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+ //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+ //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+ //! \return Pointer to found attribute, or 0 if not found.
+ xml_attribute<Ch> *next_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const
+ {
+ if (name)
+ {
+ if (name_size == 0)
+ name_size = internal::measure(name);
+ for (xml_attribute<Ch> *attribute = m_next_attribute; attribute; attribute = attribute->m_next_attribute)
+ if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive))
+ return attribute;
+ return 0;
+ }
+ else
+ return this->m_parent ? m_next_attribute : 0;
+ }
+
+ private:
+
+ xml_attribute<Ch> *m_prev_attribute; // Pointer to previous sibling of attribute, or 0 if none; only valid if parent is non-zero
+ xml_attribute<Ch> *m_next_attribute; // Pointer to next sibling of attribute, or 0 if none; only valid if parent is non-zero
+
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // XML node
+
+ //! Class representing a node of XML document.
+ //! Each node may have associated name and value strings, which are available through name() and value() functions.
+ //! Interpretation of name and value depends on type of the node.
+ //! Type of node can be determined by using type() function.
+ //! <br><br>
+ //! Note that after parse, both name and value of node, if any, will point interior of source text used for parsing.
+ //! Thus, this text must persist in the memory for the lifetime of node.
+ //! \param Ch Character type to use.
+ template<class Ch = char>
+ class xml_node: public xml_base<Ch>
+ {
+
+ public:
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Construction & destruction
+
+ //! Constructs an empty node with the specified type.
+ //! Consider using memory_pool of appropriate document to allocate nodes manually.
+ //! \param type Type of node to construct.
+ xml_node(node_type type)
+ : m_type(type)
+ , m_first_node(0)
+ , m_first_attribute(0)
+ {
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Node data access
+
+ //! Gets type of node.
+ //! \return Type of node.
+ node_type type() const
+ {
+ return m_type;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Related nodes access
+
+ //! Gets document of which node is a child.
+ //! \return Pointer to document that contains this node, or 0 if there is no parent document.
+ xml_document<Ch> *document() const
+ {
+ xml_node<Ch> *node = const_cast<xml_node<Ch> *>(this);
+ while (node->parent())
+ node = node->parent();
+ return node->type() == node_document ? static_cast<xml_document<Ch> *>(node) : 0;
+ }
+
+ //! Gets first child node, optionally matching node name.
+ //! \param name Name of child to find, or 0 to return first child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+ //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+ //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+ //! \return Pointer to found child, or 0 if not found.
+ xml_node<Ch> *first_node(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const
+ {
+ if (name)
+ {
+ if (name_size == 0)
+ name_size = internal::measure(name);
+ for (xml_node<Ch> *child = m_first_node; child; child = child->next_sibling())
+ if (internal::compare(child->name(), child->name_size(), name, name_size, case_sensitive))
+ return child;
+ return 0;
+ }
+ else
+ return m_first_node;
+ }
+
+ //! Gets last child node, optionally matching node name.
+ //! Behaviour is undefined if node has no children.
+ //! Use first_node() to test if node has children.
+ //! \param name Name of child to find, or 0 to return last child regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+ //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+ //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+ //! \return Pointer to found child, or 0 if not found.
+ xml_node<Ch> *last_node(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const
+ {
+ assert(m_first_node); // Cannot query for last child if node has no children
+ if (name)
+ {
+ if (name_size == 0)
+ name_size = internal::measure(name);
+ for (xml_node<Ch> *child = m_last_node; child; child = child->previous_sibling())
+ if (internal::compare(child->name(), child->name_size(), name, name_size, case_sensitive))
+ return child;
+ return 0;
+ }
+ else
+ return m_last_node;
+ }
+
+ //! Gets previous sibling node, optionally matching node name.
+ //! Behaviour is undefined if node has no parent.
+ //! Use parent() to test if node has a parent.
+ //! \param name Name of sibling to find, or 0 to return previous sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+ //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+ //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+ //! \return Pointer to found sibling, or 0 if not found.
+ xml_node<Ch> *previous_sibling(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const
+ {
+ assert(this->m_parent); // Cannot query for siblings if node has no parent
+ if (name)
+ {
+ if (name_size == 0)
+ name_size = internal::measure(name);
+ for (xml_node<Ch> *sibling = m_prev_sibling; sibling; sibling = sibling->m_prev_sibling)
+ if (internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive))
+ return sibling;
+ return 0;
+ }
+ else
+ return m_prev_sibling;
+ }
+
+ //! Gets next sibling node, optionally matching node name.
+ //! Behaviour is undefined if node has no parent.
+ //! Use parent() to test if node has a parent.
+ //! \param name Name of sibling to find, or 0 to return next sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+ //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+ //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+ //! \return Pointer to found sibling, or 0 if not found.
+ xml_node<Ch> *next_sibling(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const
+ {
+ assert(this->m_parent); // Cannot query for siblings if node has no parent
+ if (name)
+ {
+ if (name_size == 0)
+ name_size = internal::measure(name);
+ for (xml_node<Ch> *sibling = m_next_sibling; sibling; sibling = sibling->m_next_sibling)
+ if (internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive))
+ return sibling;
+ return 0;
+ }
+ else
+ return m_next_sibling;
+ }
+
+ //! Gets first attribute of node, optionally matching attribute name.
+ //! \param name Name of attribute to find, or 0 to return first attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+ //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+ //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+ //! \return Pointer to found attribute, or 0 if not found.
+ xml_attribute<Ch> *first_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const
+ {
+ if (name)
+ {
+ if (name_size == 0)
+ name_size = internal::measure(name);
+ for (xml_attribute<Ch> *attribute = m_first_attribute; attribute; attribute = attribute->m_next_attribute)
+ if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive))
+ return attribute;
+ return 0;
+ }
+ else
+ return m_first_attribute;
+ }
+
+ //! Gets last attribute of node, optionally matching attribute name.
+ //! \param name Name of attribute to find, or 0 to return last attribute regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
+ //! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
+ //! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
+ //! \return Pointer to found attribute, or 0 if not found.
+ xml_attribute<Ch> *last_attribute(const Ch *name = 0, std::size_t name_size = 0, bool case_sensitive = true) const
+ {
+ if (name)
+ {
+ if (name_size == 0)
+ name_size = internal::measure(name);
+ for (xml_attribute<Ch> *attribute = m_last_attribute; attribute; attribute = attribute->m_prev_attribute)
+ if (internal::compare(attribute->name(), attribute->name_size(), name, name_size, case_sensitive))
+ return attribute;
+ return 0;
+ }
+ else
+ return m_first_attribute ? m_last_attribute : 0;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Node modification
+
+ //! Sets type of node.
+ //! \param type Type of node to set.
+ void type(node_type type)
+ {
+ m_type = type;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Node manipulation
+
+ //! Prepends a new child node.
+ //! The prepended child becomes the first child, and all existing children are moved one position back.
+ //! \param child Node to prepend.
+ void prepend_node(xml_node<Ch> *child)
+ {
+ assert(child && !child->parent() && child->type() != node_document);
+ if (first_node())
+ {
+ child->m_next_sibling = m_first_node;
+ m_first_node->m_prev_sibling = child;
+ }
+ else
+ {
+ child->m_next_sibling = 0;
+ m_last_node = child;
+ }
+ m_first_node = child;
+ child->m_parent = this;
+ child->m_prev_sibling = 0;
+ }
+
+ //! Appends a new child node.
+ //! The appended child becomes the last child.
+ //! \param child Node to append.
+ void append_node(xml_node<Ch> *child)
+ {
+ assert(child && !child->parent() && child->type() != node_document);
+ if (first_node())
+ {
+ child->m_prev_sibling = m_last_node;
+ m_last_node->m_next_sibling = child;
+ }
+ else
+ {
+ child->m_prev_sibling = 0;
+ m_first_node = child;
+ }
+ m_last_node = child;
+ child->m_parent = this;
+ child->m_next_sibling = 0;
+ }
+
+ //! Inserts a new child node at specified place inside the node.
+ //! All children after and including the specified node are moved one position back.
+ //! \param where Place where to insert the child, or 0 to insert at the back.
+ //! \param child Node to insert.
+ void insert_node(xml_node<Ch> *where, xml_node<Ch> *child)
+ {
+ assert(!where || where->parent() == this);
+ assert(child && !child->parent() && child->type() != node_document);
+ if (where == m_first_node)
+ prepend_node(child);
+ else if (where == 0)
+ append_node(child);
+ else
+ {
+ child->m_prev_sibling = where->m_prev_sibling;
+ child->m_next_sibling = where;
+ where->m_prev_sibling->m_next_sibling = child;
+ where->m_prev_sibling = child;
+ child->m_parent = this;
+ }
+ }
+
+ //! Removes first child node.
+ //! If node has no children, behaviour is undefined.
+ //! Use first_node() to test if node has children.
+ void remove_first_node()
+ {
+ assert(first_node());
+ xml_node<Ch> *child = m_first_node;
+ m_first_node = child->m_next_sibling;
+ if (child->m_next_sibling)
+ child->m_next_sibling->m_prev_sibling = 0;
+ else
+ m_last_node = 0;
+ child->m_parent = 0;
+ }
+
+ //! Removes last child of the node.
+ //! If node has no children, behaviour is undefined.
+ //! Use first_node() to test if node has children.
+ void remove_last_node()
+ {
+ assert(first_node());
+ xml_node<Ch> *child = m_last_node;
+ if (child->m_prev_sibling)
+ {
+ m_last_node = child->m_prev_sibling;
+ child->m_prev_sibling->m_next_sibling = 0;
+ }
+ else
+ m_first_node = 0;
+ child->m_parent = 0;
+ }
+
+ //! Removes specified child from the node
+ // \param where Pointer to child to be removed.
+ void remove_node(xml_node<Ch> *where)
+ {
+ assert(where && where->parent() == this);
+ assert(first_node());
+ if (where == m_first_node)
+ remove_first_node();
+ else if (where == m_last_node)
+ remove_last_node();
+ else
+ {
+ where->m_prev_sibling->m_next_sibling = where->m_next_sibling;
+ where->m_next_sibling->m_prev_sibling = where->m_prev_sibling;
+ where->m_parent = 0;
+ }
+ }
+
+ //! Removes all child nodes (but not attributes).
+ void remove_all_nodes()
+ {
+ for (xml_node<Ch> *node = first_node(); node; node = node->m_next_sibling)
+ node->m_parent = 0;
+ m_first_node = 0;
+ }
+
+ //! Prepends a new attribute to the node.
+ //! \param attribute Attribute to prepend.
+ void prepend_attribute(xml_attribute<Ch> *attribute)
+ {
+ assert(attribute && !attribute->parent());
+ if (first_attribute())
+ {
+ attribute->m_next_attribute = m_first_attribute;
+ m_first_attribute->m_prev_attribute = attribute;
+ }
+ else
+ {
+ attribute->m_next_attribute = 0;
+ m_last_attribute = attribute;
+ }
+ m_first_attribute = attribute;
+ attribute->m_parent = this;
+ attribute->m_prev_attribute = 0;
+ }
+
+ //! Appends a new attribute to the node.
+ //! \param attribute Attribute to append.
+ void append_attribute(xml_attribute<Ch> *attribute)
+ {
+ assert(attribute && !attribute->parent());
+ if (first_attribute())
+ {
+ attribute->m_prev_attribute = m_last_attribute;
+ m_last_attribute->m_next_attribute = attribute;
+ }
+ else
+ {
+ attribute->m_prev_attribute = 0;
+ m_first_attribute = attribute;
+ }
+ m_last_attribute = attribute;
+ attribute->m_parent = this;
+ attribute->m_next_attribute = 0;
+ }
+
+ //! Inserts a new attribute at specified place inside the node.
+ //! All attributes after and including the specified attribute are moved one position back.
+ //! \param where Place where to insert the attribute, or 0 to insert at the back.
+ //! \param attribute Attribute to insert.
+ void insert_attribute(xml_attribute<Ch> *where, xml_attribute<Ch> *attribute)
+ {
+ assert(!where || where->parent() == this);
+ assert(attribute && !attribute->parent());
+ if (where == m_first_attribute)
+ prepend_attribute(attribute);
+ else if (where == 0)
+ append_attribute(attribute);
+ else
+ {
+ attribute->m_prev_attribute = where->m_prev_attribute;
+ attribute->m_next_attribute = where;
+ where->m_prev_attribute->m_next_attribute = attribute;
+ where->m_prev_attribute = attribute;
+ attribute->m_parent = this;
+ }
+ }
+
+ //! Removes first attribute of the node.
+ //! If node has no attributes, behaviour is undefined.
+ //! Use first_attribute() to test if node has attributes.
+ void remove_first_attribute()
+ {
+ assert(first_attribute());
+ xml_attribute<Ch> *attribute = m_first_attribute;
+ if (attribute->m_next_attribute)
+ {
+ attribute->m_next_attribute->m_prev_attribute = 0;
+ }
+ else
+ m_last_attribute = 0;
+ attribute->m_parent = 0;
+ m_first_attribute = attribute->m_next_attribute;
+ }
+
+ //! Removes last attribute of the node.
+ //! If node has no attributes, behaviour is undefined.
+ //! Use first_attribute() to test if node has attributes.
+ void remove_last_attribute()
+ {
+ assert(first_attribute());
+ xml_attribute<Ch> *attribute = m_last_attribute;
+ if (attribute->m_prev_attribute)
+ {
+ attribute->m_prev_attribute->m_next_attribute = 0;
+ m_last_attribute = attribute->m_prev_attribute;
+ }
+ else
+ m_first_attribute = 0;
+ attribute->m_parent = 0;
+ }
+
+ //! Removes specified attribute from node.
+ //! \param where Pointer to attribute to be removed.
+ void remove_attribute(xml_attribute<Ch> *where)
+ {
+ assert(first_attribute() && where->parent() == this);
+ if (where == m_first_attribute)
+ remove_first_attribute();
+ else if (where == m_last_attribute)
+ remove_last_attribute();
+ else
+ {
+ where->m_prev_attribute->m_next_attribute = where->m_next_attribute;
+ where->m_next_attribute->m_prev_attribute = where->m_prev_attribute;
+ where->m_parent = 0;
+ }
+ }
+
+ //! Removes all attributes of node.
+ void remove_all_attributes()
+ {
+ for (xml_attribute<Ch> *attribute = first_attribute(); attribute; attribute = attribute->m_next_attribute)
+ attribute->m_parent = 0;
+ m_first_attribute = 0;
+ }
+
+ private:
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Restrictions
+
+ // No copying
+ xml_node(const xml_node &);
+ void operator =(const xml_node &);
+
+ ///////////////////////////////////////////////////////////////////////////
+ // Data members
+
+ // Note that some of the pointers below have UNDEFINED values if certain other pointers are 0.
+ // This is required for maximum performance, as it allows the parser to omit initialization of
+ // unneded/redundant values.
+ //
+ // The rules are as follows:
+ // 1. first_node and first_attribute contain valid pointers, or 0 if node has no children/attributes respectively
+ // 2. last_node and last_attribute are valid only if node has at least one child/attribute respectively, otherwise they contain garbage
+ // 3. prev_sibling and next_sibling are valid only if node has a parent, otherwise they contain garbage
+
+ node_type m_type; // Type of node; always valid
+ xml_node<Ch> *m_first_node; // Pointer to first child node, or 0 if none; always valid
+ xml_node<Ch> *m_last_node; // Pointer to last child node, or 0 if none; this value is only valid if m_first_node is non-zero
+ xml_attribute<Ch> *m_first_attribute; // Pointer to first attribute of node, or 0 if none; always valid
+ xml_attribute<Ch> *m_last_attribute; // Pointer to last attribute of node, or 0 if none; this value is only valid if m_first_attribute is non-zero
+ xml_node<Ch> *m_prev_sibling; // Pointer to previous sibling of node, or 0 if none; this value is only valid if m_parent is non-zero
+ xml_node<Ch> *m_next_sibling; // Pointer to next sibling of node, or 0 if none; this value is only valid if m_parent is non-zero
+
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+ // XML document
+
+ //! This class represents root of the DOM hierarchy.
+ //! It is also an xml_node and a memory_pool through public inheritance.
+ //! Use parse() function to build a DOM tree from a zero-terminated XML text string.
+ //! parse() function allocates memory for nodes and attributes by using functions of xml_document,
+ //! which are inherited from memory_pool.
+ //! To access root node of the document, use the document itself, as if it was an xml_node.
+ //! \param Ch Character type to use.
+ template<class Ch = char>
+ class xml_document: public xml_node<Ch>, public memory_pool<Ch>
+ {
+
+ public:
+
+ //! Constructs empty XML document
+ xml_document()
+ : xml_node<Ch>(node_document)
+ {
+ }
+
+ //! Parses zero-terminated XML string according to given flags.
+ //! Passed string will be modified by the parser, unless rapidxml::parse_non_destructive flag is used.
+ //! The string must persist for the lifetime of the document.
+ //! In case of error, rapidxml::parse_error exception will be thrown.
+ //! <br><br>
+ //! If you want to parse contents of a file, you must first load the file into the memory, and pass pointer to its beginning.
+ //! Make sure that data is zero-terminated.
+ //! <br><br>
+ //! Document can be parsed into multiple times.
+ //! Each new call to parse removes previous nodes and attributes (if any), but does not clear memory pool.
+ //! \param text XML data to parse; pointer is non-const to denote fact that this data may be modified by the parser.
+ template<int Flags>
+ void parse(Ch *text)
+ {
+ assert(text);
+
+ // Remove current contents
+ this->remove_all_nodes();
+ this->remove_all_attributes();
+
+ // Parse BOM, if any
+ parse_bom<Flags>(text);
+
+ // Parse children
+ while (1)
+ {
+ // Skip whitespace before node
+ skip<whitespace_pred, Flags>(text);
+ if (*text == 0)
+ break;
+
+ // Parse and append new child
+ if (*text == Ch('<'))
+ {
+ ++text; // Skip '<'
+ if (xml_node<Ch> *node = parse_node<Flags>(text))
+ this->append_node(node);
+ }
+ else
+ RAPIDXML_PARSE_ERROR("expected <", text);
+ }
+
+ }
+
+ //! Clears the document by deleting all nodes and clearing the memory pool.
+ //! All nodes owned by document pool are destroyed.
+ void clear()
+ {
+ this->remove_all_nodes();
+ this->remove_all_attributes();
+ memory_pool<Ch>::clear();
+ }
+
+ private:
+
+ ///////////////////////////////////////////////////////////////////////
+ // Internal character utility functions
+
+ // Detect whitespace character
+ struct whitespace_pred
+ {
+ static unsigned char test(Ch ch)
+ {
+ return internal::lookup_tables<0>::lookup_whitespace[static_cast<unsigned char>(ch)];
+ }
+ };
+
+ // Detect node name character
+ struct node_name_pred
+ {
+ static unsigned char test(Ch ch)
+ {
+ return internal::lookup_tables<0>::lookup_node_name[static_cast<unsigned char>(ch)];
+ }
+ };
+
+ // Detect attribute name character
+ struct attribute_name_pred
+ {
+ static unsigned char test(Ch ch)
+ {
+ return internal::lookup_tables<0>::lookup_attribute_name[static_cast<unsigned char>(ch)];
+ }
+ };
+
+ // Detect text character (PCDATA)
+ struct text_pred
+ {
+ static unsigned char test(Ch ch)
+ {
+ return internal::lookup_tables<0>::lookup_text[static_cast<unsigned char>(ch)];
+ }
+ };
+
+ // Detect text character (PCDATA) that does not require processing
+ struct text_pure_no_ws_pred
+ {
+ static unsigned char test(Ch ch)
+ {
+ return internal::lookup_tables<0>::lookup_text_pure_no_ws[static_cast<unsigned char>(ch)];
+ }
+ };
+
+ // Detect text character (PCDATA) that does not require processing
+ struct text_pure_with_ws_pred
+ {
+ static unsigned char test(Ch ch)
+ {
+ return internal::lookup_tables<0>::lookup_text_pure_with_ws[static_cast<unsigned char>(ch)];
+ }
+ };
+
+ // Detect attribute value character
+ template<Ch Quote>
+ struct attribute_value_pred
+ {
+ static unsigned char test(Ch ch)
+ {
+ if (Quote == Ch('\''))
+ return internal::lookup_tables<0>::lookup_attribute_data_1[static_cast<unsigned char>(ch)];
+ if (Quote == Ch('\"'))
+ return internal::lookup_tables<0>::lookup_attribute_data_2[static_cast<unsigned char>(ch)];
+ return 0; // Should never be executed, to avoid warnings on Comeau
+ }
+ };
+
+ // Detect attribute value character
+ template<Ch Quote>
+ struct attribute_value_pure_pred
+ {
+ static unsigned char test(Ch ch)
+ {
+ if (Quote == Ch('\''))
+ return internal::lookup_tables<0>::lookup_attribute_data_1_pure[static_cast<unsigned char>(ch)];
+ if (Quote == Ch('\"'))
+ return internal::lookup_tables<0>::lookup_attribute_data_2_pure[static_cast<unsigned char>(ch)];
+ return 0; // Should never be executed, to avoid warnings on Comeau
+ }
+ };
+
+ // Insert coded character, using UTF8 or 8-bit ASCII
+ template<int Flags>
+ static void insert_coded_character(Ch *&text, unsigned long code)
+ {
+ if (Flags & parse_no_utf8)
+ {
+ // Insert 8-bit ASCII character
+ // Todo: possibly verify that code is less than 256 and use replacement char otherwise?
+ text[0] = static_cast<unsigned char>(code);
+ text += 1;
+ }
+ else
+ {
+ // Insert UTF8 sequence
+ if (code < 0x80) // 1 byte sequence
+ {
+ text[0] = static_cast<unsigned char>(code);
+ text += 1;
+ }
+ else if (code < 0x800) // 2 byte sequence
+ {
+ text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
+ text[0] = static_cast<unsigned char>(code | 0xC0);
+ text += 2;
+ }
+ else if (code < 0x10000) // 3 byte sequence
+ {
+ text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
+ text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
+ text[0] = static_cast<unsigned char>(code | 0xE0);
+ text += 3;
+ }
+ else if (code < 0x110000) // 4 byte sequence
+ {
+ text[3] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
+ text[2] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
+ text[1] = static_cast<unsigned char>((code | 0x80) & 0xBF); code >>= 6;
+ text[0] = static_cast<unsigned char>(code | 0xF0);
+ text += 4;
+ }
+ else // Invalid, only codes up to 0x10FFFF are allowed in Unicode
+ {
+ RAPIDXML_PARSE_ERROR("invalid numeric character entity", text);
+ }
+ }
+ }
+
+ // Skip characters until predicate evaluates to true
+ template<class StopPred, int Flags>
+ static void skip(Ch *&text)
+ {
+ Ch *tmp = text;
+ while (StopPred::test(*tmp))
+ ++tmp;
+ text = tmp;
+ }
+
+ // Skip characters until predicate evaluates to true while doing the following:
+ // - replacing XML character entity references with proper characters (' & " < > &#...;)
+ // - condensing whitespace sequences to single space character
+ template<class StopPred, class StopPredPure, int Flags>
+ static Ch *skip_and_expand_character_refs(Ch *&text)
+ {
+ // If entity translation, whitespace condense and whitespace trimming is disabled, use plain skip
+ if (Flags & parse_no_entity_translation &&
+ !(Flags & parse_normalize_whitespace) &&
+ !(Flags & parse_trim_whitespace))
+ {
+ skip<StopPred, Flags>(text);
+ return text;
+ }
+
+ // Use simple skip until first modification is detected
+ skip<StopPredPure, Flags>(text);
+
+ // Use translation skip
+ Ch *src = text;
+ Ch *dest = src;
+ while (StopPred::test(*src))
+ {
+ // If entity translation is enabled
+ if (!(Flags & parse_no_entity_translation))
+ {
+ // Test if replacement is needed
+ if (src[0] == Ch('&'))
+ {
+ switch (src[1])
+ {
+
+ // & '
+ case Ch('a'):
+ if (src[2] == Ch('m') && src[3] == Ch('p') && src[4] == Ch(';'))
+ {
+ *dest = Ch('&');
+ ++dest;
+ src += 5;
+ continue;
+ }
+ if (src[2] == Ch('p') && src[3] == Ch('o') && src[4] == Ch('s') && src[5] == Ch(';'))
+ {
+ *dest = Ch('\'');
+ ++dest;
+ src += 6;
+ continue;
+ }
+ break;
+
+ // "
+ case Ch('q'):
+ if (src[2] == Ch('u') && src[3] == Ch('o') && src[4] == Ch('t') && src[5] == Ch(';'))
+ {
+ *dest = Ch('"');
+ ++dest;
+ src += 6;
+ continue;
+ }
+ break;
+
+ // >
+ case Ch('g'):
+ if (src[2] == Ch('t') && src[3] == Ch(';'))
+ {
+ *dest = Ch('>');
+ ++dest;
+ src += 4;
+ continue;
+ }
+ break;
+
+ // <
+ case Ch('l'):
+ if (src[2] == Ch('t') && src[3] == Ch(';'))
+ {
+ *dest = Ch('<');
+ ++dest;
+ src += 4;
+ continue;
+ }
+ break;
+
+ // &#...; - assumes ASCII
+ case Ch('#'):
+ if (src[2] == Ch('x'))
+ {
+ unsigned long code = 0;
+ src += 3; // Skip &#x
+ while (1)
+ {
+ unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];
+ if (digit == 0xFF)
+ break;
+ code = code * 16 + digit;
+ ++src;
+ }
+ insert_coded_character<Flags>(dest, code); // Put character in output
+ }
+ else
+ {
+ unsigned long code = 0;
+ src += 2; // Skip &#
+ while (1)
+ {
+ unsigned char digit = internal::lookup_tables<0>::lookup_digits[static_cast<unsigned char>(*src)];
+ if (digit == 0xFF)
+ break;
+ code = code * 10 + digit;
+ ++src;
+ }
+ insert_coded_character<Flags>(dest, code); // Put character in output
+ }
+ if (*src == Ch(';'))
+ ++src;
+ else
+ RAPIDXML_PARSE_ERROR("expected ;", src);
+ continue;
+
+ // Something else
+ default:
+ // Ignore, just copy '&' verbatim
+ break;
+
+ }
+ }
+ }
+
+ // If whitespace condensing is enabled
+ if (Flags & parse_normalize_whitespace)
+ {
+ // Test if condensing is needed
+ if (whitespace_pred::test(*src))
+ {
+ *dest = Ch(' '); ++dest; // Put single space in dest
+ ++src; // Skip first whitespace char
+ // Skip remaining whitespace chars
+ while (whitespace_pred::test(*src))
+ ++src;
+ continue;
+ }
+ }
+
+ // No replacement, only copy character
+ *dest++ = *src++;
+
+ }
+
+ // Return new end
+ text = src;
+ return dest;
+
+ }
+
+ ///////////////////////////////////////////////////////////////////////
+ // Internal parsing functions
+
+ // Parse BOM, if any
+ template<int Flags>
+ void parse_bom(Ch *&text)
+ {
+ // UTF-8?
+ if (static_cast<unsigned char>(text[0]) == 0xEF &&
+ static_cast<unsigned char>(text[1]) == 0xBB &&
+ static_cast<unsigned char>(text[2]) == 0xBF)
+ {
+ text += 3; // Skup utf-8 bom
+ }
+ }
+
+ // Parse XML declaration (<?xml...)
+ template<int Flags>
+ xml_node<Ch> *parse_xml_declaration(Ch *&text)
+ {
+ // If parsing of declaration is disabled
+ if (!(Flags & parse_declaration_node))
+ {
+ // Skip until end of declaration
+ while (text[0] != Ch('?') || text[1] != Ch('>'))
+ {
+ if (!text[0]) {
+ RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+ return 0;
+ }
+ ++text;
+ }
+ text += 2; // Skip '?>'
+ return 0;
+ }
+
+ // Create declaration
+ xml_node<Ch> *declaration = this->allocate_node(node_declaration);
+
+ // Skip whitespace before attributes or ?>
+ skip<whitespace_pred, Flags>(text);
+
+ // Parse declaration attributes
+ parse_node_attributes<Flags>(text, declaration);
+
+ // Skip ?>
+ if (text[0] != Ch('?') || text[1] != Ch('>'))
+ RAPIDXML_PARSE_ERROR("expected ?>", text);
+ text += 2;
+
+ return declaration;
+ }
+
+ // Parse XML comment (<!--...)
+ template<int Flags>
+ xml_node<Ch> *parse_comment(Ch *&text)
+ {
+ // If parsing of comments is disabled
+ if (!(Flags & parse_comment_nodes))
+ {
+ // Skip until end of comment
+ while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>'))
+ {
+ if (!text[0]) {
+ RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+ return 0;
+ }
+ ++text;
+ }
+ text += 3; // Skip '-->'
+ return 0; // Do not produce comment node
+ }
+
+ // Remember value start
+ Ch *value = text;
+
+ // Skip until end of comment
+ while (text[0] != Ch('-') || text[1] != Ch('-') || text[2] != Ch('>'))
+ {
+ if (!text[0]) {
+ RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+ return 0;
+ }
+ ++text;
+ }
+
+ // Create comment node
+ xml_node<Ch> *comment = this->allocate_node(node_comment);
+ comment->value(value, text - value);
+
+ // Place zero terminator after comment value
+ if (!(Flags & parse_no_string_terminators))
+ *text = Ch('\0');
+
+ text += 3; // Skip '-->'
+ return comment;
+ }
+
+ // Parse DOCTYPE
+ template<int Flags>
+ xml_node<Ch> *parse_doctype(Ch *&text)
+ {
+ // Remember value start
+ Ch *value = text;
+
+ // Skip to >
+ while (*text != Ch('>'))
+ {
+ // Determine character type
+ switch (*text)
+ {
+
+ // If '[' encountered, scan for matching ending ']' using naive algorithm with depth
+ // This works for all W3C test files except for 2 most wicked
+ case Ch('['):
+ {
+ ++text; // Skip '['
+ int depth = 1;
+ while (depth > 0)
+ {
+ switch (*text)
+ {
+ case Ch('['): ++depth; break;
+ case Ch(']'): --depth; break;
+ case 0: RAPIDXML_PARSE_ERROR("unexpected end of data", text); return 0;
+ }
+ ++text;
+ }
+ break;
+ }
+
+ // Error on end of text
+ case Ch('\0'):
+ RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+ return 0;
+
+ // Other character, skip it
+ default:
+ ++text;
+
+ }
+ }
+
+ // If DOCTYPE nodes enabled
+ if (Flags & parse_doctype_node)
+ {
+ // Create a new doctype node
+ xml_node<Ch> *doctype = this->allocate_node(node_doctype);
+ doctype->value(value, text - value);
+
+ // Place zero terminator after value
+ if (!(Flags & parse_no_string_terminators))
+ *text = Ch('\0');
+
+ text += 1; // skip '>'
+ return doctype;
+ }
+ else
+ {
+ text += 1; // skip '>'
+ return 0;
+ }
+
+ }
+
+ // Parse PI
+ template<int Flags>
+ xml_node<Ch> *parse_pi(Ch *&text)
+ {
+ // If creation of PI nodes is enabled
+ if (Flags & parse_pi_nodes)
+ {
+ // Create pi node
+ xml_node<Ch> *pi = this->allocate_node(node_pi);
+
+ // Extract PI target name
+ Ch *name = text;
+ skip<node_name_pred, Flags>(text);
+ if (text == name)
+ RAPIDXML_PARSE_ERROR("expected PI target", text);
+ pi->name(name, text - name);
+
+ // Skip whitespace between pi target and pi
+ skip<whitespace_pred, Flags>(text);
+
+ // Remember start of pi
+ Ch *value = text;
+
+ // Skip to '?>'
+ while (text[0] != Ch('?') || text[1] != Ch('>'))
+ {
+ if (*text == Ch('\0')) {
+ RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+ return 0;
+ }
+ ++text;
+ }
+
+ // Set pi value (verbatim, no entity expansion or whitespace normalization)
+ pi->value(value, text - value);
+
+ // Place zero terminator after name and value
+ if (!(Flags & parse_no_string_terminators))
+ {
+ pi->name()[pi->name_size()] = Ch('\0');
+ pi->value()[pi->value_size()] = Ch('\0');
+ }
+
+ text += 2; // Skip '?>'
+ return pi;
+ }
+ else
+ {
+ // Skip to '?>'
+ while (text[0] != Ch('?') || text[1] != Ch('>'))
+ {
+ if (*text == Ch('\0')) {
+ RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+ return 0;
+ }
+ ++text;
+ }
+ text += 2; // Skip '?>'
+ return 0;
+ }
+ }
+
+ // Parse and append data
+ // Return character that ends data.
+ // This is necessary because this character might have been overwritten by a terminating 0
+ template<int Flags>
+ Ch parse_and_append_data(xml_node<Ch> *node, Ch *&text, Ch *contents_start)
+ {
+ // Backup to contents start if whitespace trimming is disabled
+ if (!(Flags & parse_trim_whitespace))
+ text = contents_start;
+
+ // Skip until end of data
+ Ch *value = text, *end;
+ if (Flags & parse_normalize_whitespace)
+ end = skip_and_expand_character_refs<text_pred, text_pure_with_ws_pred, Flags>(text);
+ else
+ end = skip_and_expand_character_refs<text_pred, text_pure_no_ws_pred, Flags>(text);
+
+ // Trim trailing whitespace if flag is set; leading was already trimmed by whitespace skip after >
+ if (Flags & parse_trim_whitespace)
+ {
+ if (Flags & parse_normalize_whitespace)
+ {
+ // Whitespace is already condensed to single space characters by skipping function, so just trim 1 char off the end
+ if (*(end - 1) == Ch(' '))
+ --end;
+ }
+ else
+ {
+ // Backup until non-whitespace character is found
+ while (whitespace_pred::test(*(end - 1)))
+ --end;
+ }
+ }
+
+ // If characters are still left between end and value (this test is only necessary if normalization is enabled)
+ // Create new data node
+ if (!(Flags & parse_no_data_nodes))
+ {
+ xml_node<Ch> *data = this->allocate_node(node_data);
+ data->value(value, end - value);
+ node->append_node(data);
+ }
+
+ // Add data to parent node if no data exists yet
+ if (!(Flags & parse_no_element_values))
+ if (*node->value() == Ch('\0'))
+ node->value(value, end - value);
+
+ // Place zero terminator after value
+ if (!(Flags & parse_no_string_terminators))
+ {
+ Ch ch = *text;
+ *end = Ch('\0');
+ return ch; // Return character that ends data; this is required because zero terminator overwritten it
+ }
+
+ // Return character that ends data
+ return *text;
+ }
+
+ // Parse CDATA
+ template<int Flags>
+ xml_node<Ch> *parse_cdata(Ch *&text)
+ {
+ // If CDATA is disabled
+ if (Flags & parse_no_data_nodes)
+ {
+ // Skip until end of cdata
+ while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>'))
+ {
+ if (!text[0]) {
+ RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+ return 0;
+ }
+ ++text;
+ }
+ text += 3; // Skip ]]>
+ return 0; // Do not produce CDATA node
+ }
+
+ // Skip until end of cdata
+ Ch *value = text;
+ while (text[0] != Ch(']') || text[1] != Ch(']') || text[2] != Ch('>'))
+ {
+ if (!text[0]) {
+ RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+ return 0;
+ }
+ ++text;
+ }
+
+ // Create new cdata node
+ xml_node<Ch> *cdata = this->allocate_node(node_cdata);
+ cdata->value(value, text - value);
+
+ // Place zero terminator after value
+ if (!(Flags & parse_no_string_terminators))
+ *text = Ch('\0');
+
+ text += 3; // Skip ]]>
+ return cdata;
+ }
+
+ // Parse element node
+ template<int Flags>
+ xml_node<Ch> *parse_element(Ch *&text)
+ {
+ // Create element node
+ xml_node<Ch> *element = this->allocate_node(node_element);
+
+ // Extract element name
+ Ch *name = text;
+ skip<node_name_pred, Flags>(text);
+ if (text == name)
+ RAPIDXML_PARSE_ERROR("expected element name", text);
+ element->name(name, text - name);
+
+ // Skip whitespace between element name and attributes or >
+ skip<whitespace_pred, Flags>(text);
+
+ // Parse attributes, if any
+ parse_node_attributes<Flags>(text, element);
+
+ // Determine ending type
+ if (*text == Ch('>'))
+ {
+ ++text;
+ parse_node_contents<Flags>(text, element);
+ }
+ else if (*text == Ch('/'))
+ {
+ ++text;
+ if (*text != Ch('>'))
+ RAPIDXML_PARSE_ERROR("expected >", text);
+ ++text;
+ }
+ else
+ RAPIDXML_PARSE_ERROR("expected >", text);
+
+ // Place zero terminator after name
+ if (!(Flags & parse_no_string_terminators))
+ element->name()[element->name_size()] = Ch('\0');
+
+ // Return parsed element
+ return element;
+ }
+
+ // Determine node type, and parse it
+ template<int Flags>
+ xml_node<Ch> *parse_node(Ch *&text)
+ {
+ // Parse proper node type
+ switch (text[0])
+ {
+
+ // <...
+ default:
+ // Parse and append element node
+ return parse_element<Flags>(text);
+
+ // <?...
+ case Ch('?'):
+ ++text; // Skip ?
+ if ((text[0] == Ch('x') || text[0] == Ch('X')) &&
+ (text[1] == Ch('m') || text[1] == Ch('M')) &&
+ (text[2] == Ch('l') || text[2] == Ch('L')) &&
+ whitespace_pred::test(text[3]))
+ {
+ // '<?xml ' - xml declaration
+ text += 4; // Skip 'xml '
+ return parse_xml_declaration<Flags>(text);
+ }
+ else
+ {
+ // Parse PI
+ return parse_pi<Flags>(text);
+ }
+
+ // <!...
+ case Ch('!'):
+
+ // Parse proper subset of <! node
+ switch (text[1])
+ {
+
+ // <!-
+ case Ch('-'):
+ if (text[2] == Ch('-'))
+ {
+ // '<!--' - xml comment
+ text += 3; // Skip '!--'
+ return parse_comment<Flags>(text);
+ }
+ break;
+
+ // <![
+ case Ch('['):
+ if (text[2] == Ch('C') && text[3] == Ch('D') && text[4] == Ch('A') &&
+ text[5] == Ch('T') && text[6] == Ch('A') && text[7] == Ch('['))
+ {
+ // '<![CDATA[' - cdata
+ text += 8; // Skip '![CDATA['
+ return parse_cdata<Flags>(text);
+ }
+ break;
+
+ // <!D
+ case Ch('D'):
+ if (text[2] == Ch('O') && text[3] == Ch('C') && text[4] == Ch('T') &&
+ text[5] == Ch('Y') && text[6] == Ch('P') && text[7] == Ch('E') &&
+ whitespace_pred::test(text[8]))
+ {
+ // '<!DOCTYPE ' - doctype
+ text += 9; // skip '!DOCTYPE '
+ return parse_doctype<Flags>(text);
+ }
+
+ } // switch
+
+ // Attempt to skip other, unrecognized node types starting with <!
+ ++text; // Skip !
+ while (*text != Ch('>'))
+ {
+ if (*text == 0) {
+ RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+ return 0;
+ }
+ ++text;
+ }
+ ++text; // Skip '>'
+ return 0; // No node recognized
+
+ }
+ }
+
+ // Parse contents of the node - children, data etc.
+ template<int Flags>
+ void parse_node_contents(Ch *&text, xml_node<Ch> *node)
+ {
+ // For all children and text
+ while (1)
+ {
+ // Skip whitespace between > and node contents
+ Ch *contents_start = text; // Store start of node contents before whitespace is skipped
+ skip<whitespace_pred, Flags>(text);
+ Ch next_char = *text;
+
+ // After data nodes, instead of continuing the loop, control jumps here.
+ // This is because zero termination inside parse_and_append_data() function
+ // would wreak havoc with the above code.
+ // Also, skipping whitespace after data nodes is unnecessary.
+ after_data_node:
+
+ // Determine what comes next: node closing, child node, data node, or 0?
+ switch (next_char)
+ {
+
+ // Node closing or child node
+ case Ch('<'):
+ if (text[1] == Ch('/'))
+ {
+ // Node closing
+ text += 2; // Skip '</'
+ if (Flags & parse_validate_closing_tags)
+ {
+ // Skip and validate closing tag name
+ Ch *closing_name = text;
+ skip<node_name_pred, Flags>(text);
+ if (!internal::compare(node->name(), node->name_size(), closing_name, text - closing_name, true))
+ RAPIDXML_PARSE_ERROR("invalid closing tag name", text);
+ }
+ else
+ {
+ // No validation, just skip name
+ skip<node_name_pred, Flags>(text);
+ }
+ // Skip remaining whitespace after node name
+ skip<whitespace_pred, Flags>(text);
+ if (*text != Ch('>'))
+ RAPIDXML_PARSE_ERROR("expected >", text);
+ ++text; // Skip '>'
+ return; // Node closed, finished parsing contents
+ }
+ else
+ {
+ // Child node
+ ++text; // Skip '<'
+ if (xml_node<Ch> *child = parse_node<Flags>(text))
+ node->append_node(child);
+ }
+ break;
+
+ // End of data - error
+ case Ch('\0'):
+ RAPIDXML_PARSE_ERROR("unexpected end of data", text);
+ return;
+
+ // Data node
+ default:
+ next_char = parse_and_append_data<Flags>(node, text, contents_start);
+ goto after_data_node; // Bypass regular processing after data nodes
+
+ }
+ }
+ }
+
+ // Parse XML attributes of the node
+ template<int Flags>
+ void parse_node_attributes(Ch *&text, xml_node<Ch> *node)
+ {
+ // For all attributes
+ while (attribute_name_pred::test(*text))
+ {
+ // Extract attribute name
+ Ch *name = text;
+ ++text; // Skip first character of attribute name
+ skip<attribute_name_pred, Flags>(text);
+ if (text == name)
+ RAPIDXML_PARSE_ERROR("expected attribute name", name);
+
+ // Create new attribute
+ xml_attribute<Ch> *attribute = this->allocate_attribute();
+ attribute->name(name, text - name);
+ node->append_attribute(attribute);
+
+ // Skip whitespace after attribute name
+ skip<whitespace_pred, Flags>(text);
+
+ // Skip =
+ if (*text != Ch('='))
+ RAPIDXML_PARSE_ERROR("expected =", text);
+ ++text;
+
+ // Add terminating zero after name
+ if (!(Flags & parse_no_string_terminators))
+ attribute->name()[attribute->name_size()] = 0;
+
+ // Skip whitespace after =
+ skip<whitespace_pred, Flags>(text);
+
+ // Skip quote and remember if it was ' or "
+ Ch quote = *text;
+ if (quote != Ch('\'') && quote != Ch('"'))
+ RAPIDXML_PARSE_ERROR("expected ' or \"", text);
+ ++text;
+
+ // Extract attribute value and expand char refs in it
+ Ch *value = text, *end;
+ const int AttFlags = Flags & ~parse_normalize_whitespace; // No whitespace normalization in attributes
+ if (quote == Ch('\''))
+ end = skip_and_expand_character_refs<attribute_value_pred<Ch('\'')>, attribute_value_pure_pred<Ch('\'')>, AttFlags>(text);
+ else
+ end = skip_and_expand_character_refs<attribute_value_pred<Ch('"')>, attribute_value_pure_pred<Ch('"')>, AttFlags>(text);
+
+ // Set attribute value
+ attribute->value(value, end - value);
+
+ // Make sure that end quote is present
+ if (*text != quote)
+ RAPIDXML_PARSE_ERROR("expected ' or \"", text);
+ ++text; // Skip quote
+
+ // Add terminating zero after value
+ if (!(Flags & parse_no_string_terminators))
+ attribute->value()[attribute->value_size()] = 0;
+
+ // Skip whitespace after attribute value
+ skip<whitespace_pred, Flags>(text);
+ }
+ }
+
+ };
+
+ //! \cond internal
+ namespace internal
+ {
+
+ // Whitespace (space \n \r \t)
+ template<int Dummy>
+ const unsigned char lookup_tables<Dummy>::lookup_whitespace[256] =
+ {
+ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, // 0
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // F
+ };
+
+ // Node name (anything but space \n \r \t / > ? \0)
+ template<int Dummy>
+ const unsigned char lookup_tables<Dummy>::lookup_node_name[256] =
+ {
+ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 2
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, // 3
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
+ };
+
+ // Text (i.e. PCDATA) (anything but < \0)
+ template<int Dummy>
+ const unsigned char lookup_tables<Dummy>::lookup_text[256] =
+ {
+ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
+ };
+
+ // Text (i.e. PCDATA) that does not require processing when ws normalization is disabled
+ // (anything but < \0 &)
+ template<int Dummy>
+ const unsigned char lookup_tables<Dummy>::lookup_text_pure_no_ws[256] =
+ {
+ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
+ 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
+ };
+
+ // Text (i.e. PCDATA) that does not require processing when ws normalizationis is enabled
+ // (anything but < \0 & space \n \r \t)
+ template<int Dummy>
+ const unsigned char lookup_tables<Dummy>::lookup_text_pure_with_ws[256] =
+ {
+ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
+ 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, // 3
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
+ };
+
+ // Attribute name (anything but space \n \r \t / < > = ? ! \0)
+ template<int Dummy>
+ const unsigned char lookup_tables<Dummy>::lookup_attribute_name[256] =
+ {
+ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, // 0
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, // 2
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, // 3
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
+ };
+
+ // Attribute data with single quote (anything but ' \0)
+ template<int Dummy>
+ const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1[256] =
+ {
+ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
+ 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, // 2
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
+ };
+
+ // Attribute data with single quote that does not require processing (anything but ' \0 &)
+ template<int Dummy>
+ const unsigned char lookup_tables<Dummy>::lookup_attribute_data_1_pure[256] =
+ {
+ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
+ 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, // 2
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
+ };
+
+ // Attribute data with double quote (anything but " \0)
+ template<int Dummy>
+ const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2[256] =
+ {
+ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
+ 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
+ };
+
+ // Attribute data with double quote that does not require processing (anything but " \0 &)
+ template<int Dummy>
+ const unsigned char lookup_tables<Dummy>::lookup_attribute_data_2_pure[256] =
+ {
+ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 1
+ 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 3
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 4
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 5
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 6
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 7
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 8
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 9
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // A
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // B
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // C
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // D
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // E
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // F
+ };
+
+ // Digits (dec and hex, 255 denotes end of numeric character reference)
+ template<int Dummy>
+ const unsigned char lookup_tables<Dummy>::lookup_digits[256] =
+ {
+ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 0
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 1
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 2
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,255,255,255,255,255,255, // 3
+ 255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255, // 4
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 5
+ 255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255, // 6
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 7
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 8
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // 9
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // A
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // B
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // C
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // D
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, // E
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 // F
+ };
+
+ // Upper case conversion
+ template<int Dummy>
+ const unsigned char lookup_tables<Dummy>::lookup_upcase[256] =
+ {
+ // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A B C D E F
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, // 0
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, // 1
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, // 2
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, // 3
+ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 4
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, // 5
+ 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, // 6
+ 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 123,124,125,126,127, // 7
+ 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, // 8
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, // 9
+ 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, // A
+ 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, // B
+ 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, // C
+ 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, // D
+ 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239, // E
+ 240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 // F
+ };
+ }
+ //! \endcond
+
+}
+
+// Undefine internal macros
+#undef RAPIDXML_PARSE_ERROR
+
+// On MSVC, restore warnings state
+#ifdef _MSC_VER
+ #pragma warning(pop)
+#endif
+
+#endif
diff --git a/gui/remaining.txt b/gui/remaining.txt new file mode 100644 index 000000000..298ee90ad --- /dev/null +++ b/gui/remaining.txt @@ -0,0 +1,4 @@ +* Confirmation of action +* Multi-String Variables +* String Box + diff --git a/gui/resources.cpp b/gui/resources.cpp new file mode 100644 index 000000000..41655c376 --- /dev/null +++ b/gui/resources.cpp @@ -0,0 +1,377 @@ +// resource.cpp - Source to manage GUI resources + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <string> +#include <sstream> +#include <iostream> +#include <iomanip> + +#include "../minzip/Zip.h" +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +#include "gui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" + +#define TMP_RESOURCE_NAME "/tmp/extract.bin" + +Resource::Resource(xml_node<>* node, ZipArchive* pZip) +{ + if (node && node->first_attribute("name")) + mName = node->first_attribute("name")->value(); +} + +int Resource::ExtractResource(ZipArchive* pZip, std::string folderName, std::string fileName, std::string fileExtn, std::string destFile) +{ + if (!pZip) + return -1; + + std::string src = folderName + "/" + fileName + fileExtn; + + const ZipEntry* binary = mzFindZipEntry(pZip, src.c_str()); + if (binary == NULL) { + return -1; + } + + unlink(destFile.c_str()); + int fd = creat(destFile.c_str(), 0666); + if (fd < 0) + return -1; + + int ret = 0; + if (!mzExtractZipEntryToFile(pZip, binary, fd)) + ret = -1; + + close(fd); + return ret; +} + +void Resource::LoadImage(ZipArchive* pZip, std::string file, gr_surface* source) +{ + if (ExtractResource(pZip, "images", file, ".png", TMP_RESOURCE_NAME) == 0) + { + res_create_surface(TMP_RESOURCE_NAME, source); + unlink(TMP_RESOURCE_NAME); + } + else if (ExtractResource(pZip, "images", file, "", TMP_RESOURCE_NAME) == 0) + { + // JPG includes the .jpg extension in the filename so extension should be blank + res_create_surface(TMP_RESOURCE_NAME, source); + unlink(TMP_RESOURCE_NAME); + } + else if (!pZip) + { + // File name in xml may have included .png so try without adding .png + res_create_surface(file.c_str(), source); + } +} + +void Resource::CheckAndScaleImage(gr_surface source, gr_surface* destination, int retain_aspect) +{ + if (!source) { + *destination = NULL; + return; + } + if (get_scale_w() != 0 && get_scale_h() != 0) { + float scale_w = get_scale_w(), scale_h = get_scale_h(); + if (retain_aspect) { + if (scale_w < scale_h) + scale_h = scale_w; + else + scale_w = scale_h; + } + if (res_scale_surface(source, destination, scale_w, scale_h)) { + LOGINFO("Error scaling image, using regular size.\n"); + *destination = source; + } + } else { + *destination = source; + } +} + +FontResource::FontResource(xml_node<>* node, ZipArchive* pZip) + : Resource(node, pZip) +{ + std::string file; + xml_attribute<>* attr; + + mFont = NULL; + if (!node) + return; + + attr = node->first_attribute("filename"); + if (!attr) + return; + + file = attr->value(); + +#ifndef TW_DISABLE_TTF + if(file.size() >= 4 && file.compare(file.size()-4, 4, ".ttf") == 0) + { + m_type = TYPE_TTF; + + attr = node->first_attribute("size"); + if(!attr) + return; + + int size = scale_theme_min(atoi(attr->value())); + int dpi = 300; + + attr = node->first_attribute("dpi"); + if(attr) + dpi = atoi(attr->value()); + + if (ExtractResource(pZip, "fonts", file, "", TMP_RESOURCE_NAME) == 0) + { + mFont = gr_ttf_loadFont(TMP_RESOURCE_NAME, size, dpi); + unlink(TMP_RESOURCE_NAME); + } + else + { + file = std::string(TWRES "fonts/") + file; + mFont = gr_ttf_loadFont(file.c_str(), size, dpi); + } + } + else +#endif + { + m_type = TYPE_TWRP; + + if(file.size() >= 4 && file.compare(file.size()-4, 4, ".ttf") == 0) + { + attr = node->first_attribute("fallback"); + if (!attr) + return; + + file = attr->value(); + } + + if (ExtractResource(pZip, "fonts", file, ".dat", TMP_RESOURCE_NAME) == 0) + { + mFont = gr_loadFont(TMP_RESOURCE_NAME); + unlink(TMP_RESOURCE_NAME); + } + else + { + mFont = gr_loadFont(file.c_str()); + } + } +} + +FontResource::~FontResource() +{ + if(mFont) + { +#ifndef TW_DISABLE_TTF + if(m_type == TYPE_TTF) + gr_ttf_freeFont(mFont); + else +#endif + gr_freeFont(mFont); + } +} + +ImageResource::ImageResource(xml_node<>* node, ZipArchive* pZip) + : Resource(node, pZip) +{ + std::string file; + gr_surface temp_surface = NULL; + + mSurface = NULL; + if (!node) { + LOGERR("ImageResource node is NULL\n"); + return; + } + + if (node->first_attribute("filename")) + file = node->first_attribute("filename")->value(); + else { + LOGERR("No filename specified for image resource.\n"); + return; + } + + bool retain_aspect = (node->first_attribute("retainaspect") != NULL); + // the value does not matter, if retainaspect is present, we assume that we want to retain it + LoadImage(pZip, file, &temp_surface); + CheckAndScaleImage(temp_surface, &mSurface, retain_aspect); +} + +ImageResource::~ImageResource() +{ + if (mSurface) + res_free_surface(mSurface); +} + +AnimationResource::AnimationResource(xml_node<>* node, ZipArchive* pZip) + : Resource(node, pZip) +{ + std::string file; + int fileNum = 1; + + if (!node) + return; + + if (node->first_attribute("filename")) + file = node->first_attribute("filename")->value(); + else { + LOGERR("No filename specified for image resource.\n"); + return; + } + + bool retain_aspect = (node->first_attribute("retainaspect") != NULL); + // the value does not matter, if retainaspect is present, we assume that we want to retain it + for (;;) + { + std::ostringstream fileName; + fileName << file << std::setfill ('0') << std::setw (3) << fileNum; + + gr_surface surface, temp_surface = NULL; + LoadImage(pZip, fileName.str(), &temp_surface); + CheckAndScaleImage(temp_surface, &surface, retain_aspect); + if (surface) { + mSurfaces.push_back(surface); + fileNum++; + } else + break; // Done loading animation images + } +} + +AnimationResource::~AnimationResource() +{ + std::vector<gr_surface>::iterator it; + + for (it = mSurfaces.begin(); it != mSurfaces.end(); ++it) + res_free_surface(*it); + + mSurfaces.clear(); +} + +FontResource* ResourceManager::FindFont(const std::string& name) const +{ + for (std::vector<FontResource*>::const_iterator it = mFonts.begin(); it != mFonts.end(); ++it) + if (name == (*it)->GetName()) + return *it; + return NULL; +} + +ImageResource* ResourceManager::FindImage(const std::string& name) const +{ + for (std::vector<ImageResource*>::const_iterator it = mImages.begin(); it != mImages.end(); ++it) + if (name == (*it)->GetName()) + return *it; + return NULL; +} + +AnimationResource* ResourceManager::FindAnimation(const std::string& name) const +{ + for (std::vector<AnimationResource*>::const_iterator it = mAnimations.begin(); it != mAnimations.end(); ++it) + if (name == (*it)->GetName()) + return *it; + return NULL; +} + +std::string ResourceManager::FindString(const std::string& name) const +{ + std::map<std::string, std::string>::const_iterator it = mStrings.find(name); + if (it != mStrings.end()) + return it->second; + return "[" + name + ("]"); +} + +ResourceManager::ResourceManager() +{ +} + +void ResourceManager::LoadResources(xml_node<>* resList, ZipArchive* pZip) +{ + if (!resList) + return; + + for (xml_node<>* child = resList->first_node(); child; child = child->next_sibling()) + { + std::string type = child->name(); + if (type == "resource") { + // legacy format : <resource type="..."> + xml_attribute<>* attr = child->first_attribute("type"); + type = attr ? attr->value() : "*unspecified*"; + } + + bool error = false; + if (type == "font") + { + FontResource* res = new FontResource(child, pZip); + if (res->GetResource()) + mFonts.push_back(res); + else { + error = true; + delete res; + } + } + else if (type == "image") + { + ImageResource* res = new ImageResource(child, pZip); + if (res->GetResource()) + mImages.push_back(res); + else { + error = true; + delete res; + } + } + else if (type == "animation") + { + AnimationResource* res = new AnimationResource(child, pZip); + if (res->GetResourceCount()) + mAnimations.push_back(res); + else { + error = true; + delete res; + } + } + else if (type == "string") + { + if (xml_attribute<>* attr = child->first_attribute("name")) + mStrings[attr->value()] = child->value(); + else + error = true; + } + else + { + LOGERR("Resource type (%s) not supported.\n", type.c_str()); + error = true; + } + + if (error) + { + std::string res_name; + if (child->first_attribute("name")) + res_name = child->first_attribute("name")->value(); + if (res_name.empty() && child->first_attribute("filename")) + res_name = child->first_attribute("filename")->value(); + + if (!res_name.empty()) { + LOGERR("Resource (%s)-(%s) failed to load\n", type.c_str(), res_name.c_str()); + } else + LOGERR("Resource type (%s) failed to load\n", type.c_str()); + } + } +} + +ResourceManager::~ResourceManager() +{ + for (std::vector<FontResource*>::iterator it = mFonts.begin(); it != mFonts.end(); ++it) + delete *it; + + for (std::vector<ImageResource*>::iterator it = mImages.begin(); it != mImages.end(); ++it) + delete *it; + + for (std::vector<AnimationResource*>::iterator it = mAnimations.begin(); it != mAnimations.end(); ++it) + delete *it; +} diff --git a/gui/resources.hpp b/gui/resources.hpp new file mode 100644 index 000000000..0eb32674d --- /dev/null +++ b/gui/resources.hpp @@ -0,0 +1,110 @@ +// resources.hpp - Base classes for resource management of GUI + +#ifndef _RESOURCE_HEADER +#define _RESOURCE_HEADER + +#include <string> +#include <vector> +#include <map> + +struct ZipArchive; + +extern "C" { +#include "../minuitwrp/minui.h" +} + +// Base Objects +class Resource +{ +public: + Resource(xml_node<>* node, ZipArchive* pZip); + virtual ~Resource() {} + +public: + std::string GetName() { return mName; } + +private: + std::string mName; + +protected: + static int ExtractResource(ZipArchive* pZip, std::string folderName, std::string fileName, std::string fileExtn, std::string destFile); + static void LoadImage(ZipArchive* pZip, std::string file, gr_surface* source); + static void CheckAndScaleImage(gr_surface source, gr_surface* destination, int retain_aspect); +}; + +class FontResource : public Resource +{ +public: + enum Type + { + TYPE_TWRP, +#ifndef TW_DISABLE_TTF + TYPE_TTF, +#endif + }; + + FontResource(xml_node<>* node, ZipArchive* pZip); + virtual ~FontResource(); + +public: + void* GetResource() { return this ? mFont : NULL; } + int GetHeight() { return gr_getMaxFontHeight(this ? mFont : NULL); } + +protected: + void* mFont; + Type m_type; +}; + +class ImageResource : public Resource +{ +public: + ImageResource(xml_node<>* node, ZipArchive* pZip); + virtual ~ImageResource(); + +public: + gr_surface GetResource() { return this ? mSurface : NULL; } + int GetWidth() { return gr_get_width(this ? mSurface : NULL); } + int GetHeight() { return gr_get_height(this ? mSurface : NULL); } + +protected: + gr_surface mSurface; +}; + +class AnimationResource : public Resource +{ +public: + AnimationResource(xml_node<>* node, ZipArchive* pZip); + virtual ~AnimationResource(); + +public: + gr_surface GetResource() { return (!this || mSurfaces.empty()) ? NULL : mSurfaces.at(0); } + gr_surface GetResource(int entry) { return (!this || mSurfaces.empty()) ? NULL : mSurfaces.at(entry); } + int GetWidth() { return gr_get_width(this ? GetResource() : NULL); } + int GetHeight() { return gr_get_height(this ? GetResource() : NULL); } + int GetResourceCount() { return mSurfaces.size(); } + +protected: + std::vector<gr_surface> mSurfaces; +}; + +class ResourceManager +{ +public: + ResourceManager(); + virtual ~ResourceManager(); + void LoadResources(xml_node<>* resList, ZipArchive* pZip); + +public: + FontResource* FindFont(const std::string& name) const; + ImageResource* FindImage(const std::string& name) const; + AnimationResource* FindAnimation(const std::string& name) const; + std::string FindString(const std::string& name) const; + +private: + std::vector<FontResource*> mFonts; + std::vector<ImageResource*> mImages; + std::vector<AnimationResource*> mAnimations; + std::map<std::string, std::string> mStrings; +}; + +#endif // _RESOURCE_HEADER diff --git a/gui/scrolllist.cpp b/gui/scrolllist.cpp new file mode 100644 index 000000000..ec42fe6c0 --- /dev/null +++ b/gui/scrolllist.cpp @@ -0,0 +1,609 @@ +/* + Copyright 2013 bigbiff/Dees_Troy TeamWin + This file is part of TWRP/TeamWin Recovery Project. + + TWRP is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + TWRP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with TWRP. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <string.h> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" +#include "../data.hpp" + +const float SCROLLING_SPEED_DECREMENT = 0.9; // friction +const int SCROLLING_FLOOR = 2; // minimum pixels for scrolling to stop + +GUIScrollList::GUIScrollList(xml_node<>* node) : GUIObject(node) +{ + xml_attribute<>* attr; + xml_node<>* child; + + firstDisplayedItem = mItemSpacing = mFontHeight = mSeparatorH = y_offset = scrollingSpeed = 0; + maxIconWidth = maxIconHeight = mHeaderIconHeight = mHeaderIconWidth = 0; + mHeaderSeparatorH = mHeaderH = actualItemHeight = 0; + mHeaderIsStatic = false; + mBackground = mHeaderIcon = NULL; + mFont = NULL; + mFastScrollW = mFastScrollLineW = mFastScrollRectW = mFastScrollRectH = 0; + mFastScrollRectCurrentY = mFastScrollRectCurrentH = mFastScrollRectTouchY = 0; + lastY = last2Y = fastScroll = 0; + mUpdate = 0; + touchDebounce = 6; + ConvertStrToColor("black", &mBackgroundColor); + ConvertStrToColor("black", &mHeaderBackgroundColor); + ConvertStrToColor("black", &mSeparatorColor); + ConvertStrToColor("black", &mHeaderSeparatorColor); + ConvertStrToColor("white", &mFontColor); + ConvertStrToColor("white", &mHeaderFontColor); + ConvertStrToColor("white", &mFastScrollLineColor); + ConvertStrToColor("white", &mFastScrollRectColor); + hasHighlightColor = false; + allowSelection = true; + selectedItem = NO_ITEM; + + // Load header text + // note: node can be NULL for the emergency console + child = node ? node->first_node("text") : NULL; + if (child) mHeaderText = child->value(); + // Simple way to check for static state + mLastHeaderValue = gui_parse_text(mHeaderText); + mHeaderIsStatic = (mLastHeaderValue == mHeaderText); + + mHighlightColor = LoadAttrColor(FindNode(node, "highlight"), "color", &hasHighlightColor); + + child = FindNode(node, "background"); + if (child) + { + mBackground = LoadAttrImage(child, "resource"); + mBackgroundColor = LoadAttrColor(child, "color"); + } + + // Load the placement + LoadPlacement(FindNode(node, "placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH); + SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH); + + // Load the font, and possibly override the color + child = FindNode(node, "font"); + if (child) + { + mFont = LoadAttrFont(child, "resource"); + mFontColor = LoadAttrColor(child, "color"); + mFontHighlightColor = LoadAttrColor(child, "highlightcolor", mFontColor); + mItemSpacing = LoadAttrIntScaleY(child, "spacing"); + } + + // Load the separator if it exists + child = FindNode(node, "separator"); + if (child) + { + mSeparatorColor = LoadAttrColor(child, "color"); + mSeparatorH = LoadAttrIntScaleY(child, "height"); + } + + // Fast scroll + child = FindNode(node, "fastscroll"); + if (child) + { + mFastScrollLineColor = LoadAttrColor(child, "linecolor"); + mFastScrollRectColor = LoadAttrColor(child, "rectcolor"); + + mFastScrollW = LoadAttrIntScaleX(child, "w"); + mFastScrollLineW = LoadAttrIntScaleX(child, "linew"); + mFastScrollRectW = LoadAttrIntScaleX(child, "rectw"); + mFastScrollRectH = LoadAttrIntScaleY(child, "recth"); + } + + // Retrieve the line height + mFontHeight = mFont->GetHeight(); + actualItemHeight = mFontHeight + mItemSpacing + mSeparatorH; + + // Load the header if it exists + child = FindNode(node, "header"); + if (child) + { + mHeaderH = mFontHeight; + mHeaderIcon = LoadAttrImage(child, "icon"); + mHeaderBackgroundColor = LoadAttrColor(child, "background", mBackgroundColor); + mHeaderFontColor = LoadAttrColor(child, "textcolor", mFontColor); + mHeaderSeparatorColor = LoadAttrColor(child, "separatorcolor", mSeparatorColor); + mHeaderSeparatorH = LoadAttrIntScaleY(child, "separatorheight", mSeparatorH); + + if (mHeaderIcon && mHeaderIcon->GetResource()) + { + mHeaderIconWidth = mHeaderIcon->GetWidth(); + mHeaderIconHeight = mHeaderIcon->GetHeight(); + if (mHeaderIconHeight > mHeaderH) + mHeaderH = mHeaderIconHeight; + if (mHeaderIconWidth > maxIconWidth) + maxIconWidth = mHeaderIconWidth; + } + + mHeaderH += mItemSpacing + mHeaderSeparatorH; + if (mHeaderH < actualItemHeight) + mHeaderH = actualItemHeight; + } + + if (actualItemHeight / 3 > 6) + touchDebounce = actualItemHeight / 3; +} + +GUIScrollList::~GUIScrollList() +{ +} + +void GUIScrollList::SetMaxIconSize(int w, int h) +{ + if (w > maxIconWidth) + maxIconWidth = w; + if (h > maxIconHeight) + maxIconHeight = h; + if (maxIconHeight > mFontHeight) { + actualItemHeight = maxIconHeight + mItemSpacing + mSeparatorH; + if (mHeaderH > 0 && actualItemHeight > mHeaderH) + mHeaderH = actualItemHeight; + } +} + +void GUIScrollList::SetVisibleListLocation(size_t list_index) +{ + // This will make sure that the item indicated by list_index is visible on the screen + size_t lines = GetDisplayItemCount(); + + if (list_index <= (unsigned)firstDisplayedItem) { + // list_index is above the currently displayed items, put the selected item at the very top + firstDisplayedItem = list_index; + y_offset = 0; + } else if (list_index >= firstDisplayedItem + lines) { + // list_index is below the currently displayed items, put the selected item at the very bottom + firstDisplayedItem = list_index - lines + 1; + if (GetDisplayRemainder() != 0) { + // There's a partial row displayed, set the scrolling offset so that the selected item really is at the very bottom + firstDisplayedItem--; + y_offset = GetDisplayRemainder() - actualItemHeight; + } else { + // There's no partial row so zero out the offset + y_offset = 0; + } + if (firstDisplayedItem < 0) + firstDisplayedItem = 0; + } + scrollingSpeed = 0; // stop kinetic scrolling on setting visible location + mUpdate = 1; +} + +int GUIScrollList::Render(void) +{ + if(!isConditionTrue()) + return 0; + + // First step, fill background + gr_color(mBackgroundColor.red, mBackgroundColor.green, mBackgroundColor.blue, mBackgroundColor.alpha); + gr_fill(mRenderX, mRenderY + mHeaderH, mRenderW, mRenderH - mHeaderH); + + // don't paint outside of the box + gr_clip(mRenderX, mRenderY, mRenderW, mRenderH); + + // Next, render the background resource (if it exists) + if (mBackground && mBackground->GetResource()) + { + int BackgroundW = mBackground->GetWidth(); + int BackgroundH = mBackground->GetHeight(); + int BackgroundX = mRenderX + ((mRenderW - BackgroundW) / 2); + int BackgroundY = mRenderY + ((mRenderH - BackgroundH) / 2); + gr_blit(mBackground->GetResource(), 0, 0, BackgroundW, BackgroundH, BackgroundX, BackgroundY); + } + + // This tells us how many full lines we can actually render + size_t lines = GetDisplayItemCount(); + + size_t listSize = GetItemCount(); + int listW = mRenderW; // this is only used for the separators - the list items are rendered in the full width of the list + + if (listSize <= lines) { + hasScroll = false; + scrollingSpeed = 0; + lines = listSize; + y_offset = 0; + } else { + hasScroll = true; + listW -= mFastScrollW; // space for fast scroll + lines++; + if (lines < listSize) + lines++; + } + + int yPos = mRenderY + mHeaderH + y_offset; + + // render all visible items + for (size_t line = 0; line < lines; line++) + { + size_t itemindex = line + firstDisplayedItem; + if (itemindex >= listSize) + break; + + RenderItem(itemindex, yPos, itemindex == selectedItem); + + // Add the separator + gr_color(mSeparatorColor.red, mSeparatorColor.green, mSeparatorColor.blue, mSeparatorColor.alpha); + gr_fill(mRenderX, yPos + actualItemHeight - mSeparatorH, listW, mSeparatorH); + + // Move the yPos + yPos += actualItemHeight; + } + + // Render the Header (last so that it overwrites the top most row for per pixel scrolling) + yPos = mRenderY; + if (mHeaderH > 0) { + // First step, fill background + gr_color(mHeaderBackgroundColor.red, mHeaderBackgroundColor.green, mHeaderBackgroundColor.blue, mHeaderBackgroundColor.alpha); + gr_fill(mRenderX, mRenderY, mRenderW, mHeaderH); + + int IconOffsetX = 0; + + // render the icon if it exists + if (mHeaderIcon && mHeaderIcon->GetResource()) + { + gr_blit(mHeaderIcon->GetResource(), 0, 0, mHeaderIconWidth, mHeaderIconHeight, mRenderX + ((mHeaderIconWidth - maxIconWidth) / 2), (yPos + (int)((mHeaderH - mHeaderIconHeight) / 2))); + IconOffsetX = maxIconWidth; + } + + // render the text + gr_color(mHeaderFontColor.red, mHeaderFontColor.green, mHeaderFontColor.blue, mHeaderFontColor.alpha); + gr_textEx(mRenderX + IconOffsetX + 5, yPos + (int)((mHeaderH - mFontHeight) / 2), mLastHeaderValue.c_str(), mFont->GetResource()); + + // Add the separator + gr_color(mHeaderSeparatorColor.red, mHeaderSeparatorColor.green, mHeaderSeparatorColor.blue, mHeaderSeparatorColor.alpha); + gr_fill(mRenderX, yPos + mHeaderH - mHeaderSeparatorH, mRenderW, mHeaderSeparatorH); + } + + // reset clipping + gr_noclip(); + + // render fast scroll + if (hasScroll) { + int fWidth = mRenderW - listW; + int fHeight = mRenderH - mHeaderH; + int centerX = listW + mRenderX + fWidth / 2; + + // first determine the total list height and where we are in the list + int totalHeight = GetItemCount() * actualItemHeight; // total height of the full list in pixels + int topPos = firstDisplayedItem * actualItemHeight - y_offset; + + // now scale it proportionally to the scrollbar height + int boxH = fHeight * fHeight / totalHeight; // proportional height of the displayed portion + boxH = std::max(boxH, mFastScrollRectH); // but keep a minimum height + int boxY = (fHeight - boxH) * topPos / (totalHeight - fHeight); // pixels relative to top of list + int boxW = mFastScrollRectW; + + int x = centerX - boxW / 2; + int y = mRenderY + mHeaderH + boxY; + + // line above and below box (needs to be split because box can be transparent) + gr_color(mFastScrollLineColor.red, mFastScrollLineColor.green, mFastScrollLineColor.blue, mFastScrollLineColor.alpha); + gr_fill(centerX - mFastScrollLineW / 2, mRenderY + mHeaderH, mFastScrollLineW, boxY); + gr_fill(centerX - mFastScrollLineW / 2, y + boxH, mFastScrollLineW, fHeight - boxY - boxH); + + // box + gr_color(mFastScrollRectColor.red, mFastScrollRectColor.green, mFastScrollRectColor.blue, mFastScrollRectColor.alpha); + gr_fill(x, y, boxW, boxH); + + mFastScrollRectCurrentY = boxY; + mFastScrollRectCurrentH = boxH; + } + mUpdate = 0; + return 0; +} + +void GUIScrollList::RenderItem(size_t itemindex, int yPos, bool selected) +{ + RenderStdItem(yPos, selected, NULL, "implement RenderItem!"); +} + +void GUIScrollList::RenderStdItem(int yPos, bool selected, ImageResource* icon, const char* text, int iconAndTextH) +{ + if (hasHighlightColor && selected) { + // Highlight the item background of the selected item + gr_color(mHighlightColor.red, mHighlightColor.green, mHighlightColor.blue, mHighlightColor.alpha); + gr_fill(mRenderX, yPos, mRenderW, actualItemHeight); + } + + if (selected) { + // Use the highlight color for the font + gr_color(mFontHighlightColor.red, mFontHighlightColor.green, mFontHighlightColor.blue, mFontHighlightColor.alpha); + } else { + // Set the color for the font + gr_color(mFontColor.red, mFontColor.green, mFontColor.blue, mFontColor.alpha); + } + + if (!iconAndTextH) + iconAndTextH = actualItemHeight; + + // render icon + if (icon && icon->GetResource()) { + int iconH = icon->GetHeight(); + int iconW = icon->GetWidth(); + int iconY = yPos + (iconAndTextH - iconH) / 2; + int iconX = mRenderX + (maxIconWidth - iconW) / 2; + gr_blit(icon->GetResource(), 0, 0, iconW, iconH, iconX, iconY); + } + + // render label text + int textX = mRenderX + maxIconWidth + 5; + int textY = yPos + (iconAndTextH - mFontHeight) / 2; + gr_textEx(textX, textY, text, mFont->GetResource()); +} + +int GUIScrollList::Update(void) +{ + if(!isConditionTrue()) + return 0; + + if (!mHeaderIsStatic) { + std::string newValue = gui_parse_text(mHeaderText); + if (mLastHeaderValue != newValue) { + mLastHeaderValue = newValue; + mUpdate = 1; + } + } + + // Handle kinetic scrolling + // maximum number of items to scroll per update + float maxItemsScrolledPerFrame = std::max(2.5, float(GetDisplayItemCount() / 4) + 0.5); + + int maxScrollDistance = actualItemHeight * maxItemsScrolledPerFrame; + int oldScrollingSpeed = scrollingSpeed; + if (scrollingSpeed == 0) { + // Do nothing + return 0; + } else if (scrollingSpeed > 0) { + if (scrollingSpeed < maxScrollDistance) + y_offset += scrollingSpeed; + else + y_offset += maxScrollDistance; + scrollingSpeed *= SCROLLING_SPEED_DECREMENT; + if (scrollingSpeed == oldScrollingSpeed) + --scrollingSpeed; + } else if (scrollingSpeed < 0) { + if (abs(scrollingSpeed) < maxScrollDistance) + y_offset += scrollingSpeed; + else + y_offset -= maxScrollDistance; + scrollingSpeed *= SCROLLING_SPEED_DECREMENT; + if (scrollingSpeed == oldScrollingSpeed) + ++scrollingSpeed; + } + if (abs(scrollingSpeed) < SCROLLING_FLOOR) + scrollingSpeed = 0; + HandleScrolling(); + mUpdate = 1; + + return 0; +} + +size_t GUIScrollList::HitTestItem(int x, int y) +{ + // We only care about y position + if (y < mRenderY || y - mRenderY <= mHeaderH || y - mRenderY > mRenderH) + return NO_ITEM; + + int startSelection = (y - mRenderY - mHeaderH); + + // Locate the correct item + size_t actualSelection = firstDisplayedItem; + int selectY = y_offset; + while (selectY + actualItemHeight < startSelection) { + selectY += actualItemHeight; + actualSelection++; + } + + if (actualSelection < GetItemCount()) + return actualSelection; + + return NO_ITEM; +} + +int GUIScrollList::NotifyTouch(TOUCH_STATE state, int x, int y) +{ + if(!isConditionTrue()) + return -1; + + switch (state) + { + case TOUCH_START: + if (hasScroll && x >= mRenderX + mRenderW - mFastScrollW) { + fastScroll = 1; // Initial touch is in the fast scroll region + int fastScrollBoxTop = mFastScrollRectCurrentY + mRenderY + mHeaderH; + int fastScrollBoxBottom = fastScrollBoxTop + mFastScrollRectCurrentH; + if (y >= fastScrollBoxTop && y < fastScrollBoxBottom) + // user grabbed the fastscroll bar + // try to keep the initially touched part of the scrollbar under the finger + mFastScrollRectTouchY = y - fastScrollBoxTop; + else + // user tapped outside the fastscroll bar + // center fastscroll rect on the initial touch position + mFastScrollRectTouchY = mFastScrollRectCurrentH / 2; + } + + if (scrollingSpeed != 0) { + selectedItem = NO_ITEM; // this allows the user to tap the list to stop the scrolling without selecting the item they tap + scrollingSpeed = 0; // stop scrolling on a new touch + } else if (!fastScroll && allowSelection) { + // find out which item the user touched + selectedItem = HitTestItem(x, y); + } + if (selectedItem != NO_ITEM) + mUpdate = 1; + lastY = last2Y = y; + break; + + case TOUCH_DRAG: + if (fastScroll) + { + int relY = y - mRenderY - mHeaderH; // touch position relative to window + int windowH = mRenderH - mHeaderH; + int totalHeight = GetItemCount() * actualItemHeight; // total height of the full list in pixels + + // calculate new top position of the fastscroll bar relative to window + int newY = relY - mFastScrollRectTouchY; + // keep it fully inside the list + newY = std::min(std::max(newY, 0), windowH - mFastScrollRectCurrentH); + + // now compute the new scroll position for the list + int newTopPos = newY * (totalHeight - windowH) / (windowH - mFastScrollRectCurrentH); // new top pixel of list + newTopPos = std::min(newTopPos, totalHeight - windowH); // account for rounding errors + firstDisplayedItem = newTopPos / actualItemHeight; + y_offset = - newTopPos % actualItemHeight; + + selectedItem = NO_ITEM; + mUpdate = 1; + scrollingSpeed = 0; // prevent kinetic scrolling when using fast scroll + break; + } + + // Provide some debounce on initial touches + if (selectedItem != NO_ITEM && abs(y - lastY) < touchDebounce) { + mUpdate = 1; + break; + } + + selectedItem = NO_ITEM; // nothing is selected because we dragged too far + // Handle scrolling + if (hasScroll) { + y_offset += y - lastY; // adjust the scrolling offset based on the difference between the starting touch and the current touch + last2Y = lastY; // keep track of previous y locations so that we can tell how fast to scroll for kinetic scrolling + lastY = y; // update last touch to the current touch so we can tell how far and what direction we scroll for the next touch event + + HandleScrolling(); + } else + y_offset = 0; + mUpdate = 1; + break; + + case TOUCH_RELEASE: + if (fastScroll) + mUpdate = 1; // get rid of touch effects on the fastscroll bar + fastScroll = 0; + if (selectedItem != NO_ITEM) { + // We've selected an item! + NotifySelect(selectedItem); + mUpdate = 1; + + DataManager::Vibrate("tw_button_vibrate"); + selectedItem = NO_ITEM; + } else { + // Start kinetic scrolling + scrollingSpeed = lastY - last2Y; + if (abs(scrollingSpeed) < touchDebounce) + scrollingSpeed = 0; + } + case TOUCH_REPEAT: + case TOUCH_HOLD: + break; + } + return 0; +} + +void GUIScrollList::HandleScrolling() +{ + // handle dragging downward, scrolling upward + // the offset should always be <= 0 and > -actualItemHeight, adjust the first display row and offset as needed + while(firstDisplayedItem && y_offset > 0) { + firstDisplayedItem--; + y_offset -= actualItemHeight; + } + if (firstDisplayedItem == 0 && y_offset > 0) { + y_offset = 0; // user kept dragging downward past the top of the list, so always reset the offset to 0 since we can't scroll any further in this direction + scrollingSpeed = 0; // stop kinetic scrolling + } + + // handle dragging upward, scrolling downward + int totalSize = GetItemCount(); + int lines = GetDisplayItemCount(); // number of full lines our list can display at once + int bottom_offset = GetDisplayRemainder() - actualItemHeight; // extra display area that can display a partial line for per pixel scrolling + + // the offset should always be <= 0 and > -actualItemHeight, adjust the first display row and offset as needed + while (firstDisplayedItem + lines + (bottom_offset ? 1 : 0) < totalSize && abs(y_offset) > actualItemHeight) { + firstDisplayedItem++; + y_offset += actualItemHeight; + } + // Check if we dragged too far, set the list at the bottom and adjust offset as needed + if (bottom_offset != 0 && firstDisplayedItem + lines + 1 >= totalSize && y_offset <= bottom_offset) { + firstDisplayedItem = totalSize - lines - 1; + y_offset = bottom_offset; + scrollingSpeed = 0; // stop kinetic scrolling + } else if (firstDisplayedItem + lines >= totalSize && y_offset < 0) { + firstDisplayedItem = totalSize - lines; + y_offset = 0; + scrollingSpeed = 0; // stop kinetic scrolling + } +} + +int GUIScrollList::GetDisplayItemCount() +{ + return (mRenderH - mHeaderH) / (actualItemHeight); +} + +int GUIScrollList::GetDisplayRemainder() +{ + return (mRenderH - mHeaderH) % actualItemHeight; +} + +int GUIScrollList::NotifyVarChange(const std::string& varName, const std::string& value) +{ + GUIObject::NotifyVarChange(varName, value); + + if(!isConditionTrue()) + return 0; + + if (!mHeaderIsStatic) { + std::string newValue = gui_parse_text(mHeaderText); + if (mLastHeaderValue != newValue) { + mLastHeaderValue = newValue; + firstDisplayedItem = 0; + y_offset = 0; + scrollingSpeed = 0; // stop kinetic scrolling on variable changes + mUpdate = 1; + } + } + return 0; +} + +int GUIScrollList::SetRenderPos(int x, int y, int w /* = 0 */, int h /* = 0 */) +{ + mRenderX = x; + mRenderY = y; + if (w || h) + { + mRenderW = w; + mRenderH = h; + } + SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH); + mUpdate = 1; + return 0; +} + +void GUIScrollList::SetPageFocus(int inFocus) +{ + if (inFocus) { + NotifyVarChange("", ""); // This forces a check for the header text + scrollingSpeed = 0; // stop kinetic scrolling on page changes + mUpdate = 1; + } +} diff --git a/gui/slider.cpp b/gui/slider.cpp new file mode 100644 index 000000000..a3884474b --- /dev/null +++ b/gui/slider.cpp @@ -0,0 +1,201 @@ +// slider.cpp - GUISlider object +// Pulled & ported from https://raw.github.com/agrabren/RecoverWin/master/gui/slider.cpp + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> +#include "../data.hpp" + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" + +GUISlider::GUISlider(xml_node<>* node) : GUIObject(node) +{ + xml_attribute<>* attr; + xml_node<>* child; + + sAction = NULL; + sSliderLabel = NULL; + sSlider = NULL; + sSliderUsed = NULL; + sTouch = NULL; + sTouchW = 20; + + if (!node) + { + LOGERR("GUISlider created without XML node\n"); + return; + } + + // Load the resources + child = FindNode(node, "resource"); + if (child) + { + sSlider = LoadAttrImage(child, "base"); + sSliderUsed = LoadAttrImage(child, "used"); + sTouch = LoadAttrImage(child, "touch"); + } + + // Load the text label + sSliderLabel = new GUIText(node); + if (sSliderLabel->Render() < 0) + { + delete sSliderLabel; + sSliderLabel = NULL; + } + + // Load the placement + Placement TextPlacement = CENTER; + LoadPlacement(FindNode(node, "placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH, &TextPlacement); + + mRenderW = sSlider->GetWidth(); + mRenderH = sSlider->GetHeight(); + if (TextPlacement == CENTER || TextPlacement == CENTER_X_ONLY) { + mRenderX = mRenderX - (mRenderW / 2); + if (TextPlacement == CENTER) { + mRenderY = mRenderY - (mRenderH / 2); + } + } + if (sSliderLabel) { + int sTextX = mRenderX + (mRenderW / 2); + int w, h; + sSliderLabel->GetCurrentBounds(w, h); + int sTextY = mRenderY + ((mRenderH - h) / 2); + sSliderLabel->SetRenderPos(sTextX, sTextY); + } + if (sTouch && sTouch->GetResource()) + { + sTouchW = sTouch->GetWidth(); // Width of the "touch image" that follows the touch (arrow) + sTouchH = sTouch->GetHeight(); // Height of the "touch image" that follows the touch (arrow) + } + + //LOGINFO("mRenderW: %i mTouchW: %i\n", mRenderW, mTouchW); + mActionX = mRenderX; + mActionY = mRenderY; + mActionW = mRenderW; + mActionH = mRenderH; + + sAction = new GUIAction(node); + + sCurTouchX = mRenderX; + sUpdate = 1; +} + +GUISlider::~GUISlider() +{ + delete sAction; + delete sSliderLabel; +} + +int GUISlider::Render(void) +{ + if(!isConditionTrue()) + return 0; + + if (!sSlider || !sSlider->GetResource()) + return -1; + + // Draw the slider + gr_blit(sSlider->GetResource(), 0, 0, mRenderW, mRenderH, mRenderX, mRenderY); + + // Draw the used + if (sSliderUsed && sSliderUsed->GetResource() && sCurTouchX > mRenderX) + gr_blit(sSliderUsed->GetResource(), 0, 0, sCurTouchX - mRenderX, mRenderH, mRenderX, mRenderY); + + // Draw the touch icon + if (sTouch && sTouch->GetResource()) + gr_blit(sTouch->GetResource(), 0, 0, sTouchW, sTouchH, sCurTouchX, (mRenderY + ((mRenderH - sTouchH) / 2))); + + if (sSliderLabel) { + int ret = sSliderLabel->Render(); + if (ret < 0) return ret; + } + + sUpdate = 0; + return 0; +} + +int GUISlider::Update(void) +{ + if(!isConditionTrue()) + return 0; + + if (sUpdate) + return 2; + return 0; +} + +int GUISlider::NotifyTouch(TOUCH_STATE state, int x, int y) +{ + if(!isConditionTrue()) + return -1; + + static bool dragging = false; + + switch (state) + { + case TOUCH_START: + if (x >= mRenderX && x <= mRenderX + sTouchW && + y >= mRenderY && y <= mRenderY + mRenderH) + { + sCurTouchX = x - (sTouchW / 2); + if (sCurTouchX < mRenderX) + sCurTouchX = mRenderX; + dragging = true; + } + break; + + case TOUCH_DRAG: + if (!dragging) + return 0; + if (y < mRenderY - sTouchH || y > mRenderY + (sTouchH * 2)) + { + sCurTouchX = mRenderX; + dragging = false; + sUpdate = 1; + break; + } + sCurTouchX = x - (sTouchW / 2); + if (sCurTouchX < mRenderX) + sCurTouchX = mRenderX; + if (sCurTouchX > mRenderX + mRenderW - sTouchW) + sCurTouchX = mRenderX + mRenderW - sTouchW; + sUpdate = 1; + break; + + case TOUCH_RELEASE: + if (!dragging) + return 0; + + if (sCurTouchX >= mRenderX + mRenderW - sTouchW) { + DataManager::Vibrate("tw_button_vibrate"); + sAction->doActions(); + } + + sCurTouchX = mRenderX; + dragging = false; + sUpdate = 1; + case TOUCH_REPEAT: + case TOUCH_HOLD: + break; + } + return 0; +} diff --git a/gui/slidervalue.cpp b/gui/slidervalue.cpp new file mode 100644 index 000000000..3974c37d0 --- /dev/null +++ b/gui/slidervalue.cpp @@ -0,0 +1,422 @@ +// slidervalue.cpp - GUISliderValue object + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" + +GUISliderValue::GUISliderValue(xml_node<>* node) : GUIObject(node) +{ + xml_attribute<>* attr; + xml_node<>* child; + + mMin = 0; + mMax = 100; + mValue = 0; + mLineH = 2; + mLinePadding = 10; + mSliderW = 5; + mSliderH = 30; + mLineX = 0; + mLineY = 0; + mValueStr = NULL; + mAction = NULL; + mShowCurr = true; + mShowRange = false; + mChangeOnDrag = false; + mRendered = false; + mBackgroundImage = NULL; + mHandleImage = NULL; + mHandleHoverImage = NULL; + mDragging = false; + + mLabel = NULL; + ConvertStrToColor("white", &mTextColor); + ConvertStrToColor("white", &mLineColor); + ConvertStrToColor("blue", &mSliderColor); + + if (!node) + { + LOGERR("GUISliderValue created without XML node\n"); + return; + } + + mLabel = new GUIText(node); + if(mLabel->Render() < 0) + { + delete mLabel; + mLabel = NULL; + } + + mAction = new GUIAction(node); + + child = FindNode(node, "font"); + if (child) + { + mFont = LoadAttrFont(child, "resource"); + mTextColor = LoadAttrColor(child, "color", mTextColor); + } + + // Load the placement + LoadPlacement(FindNode(node, "placement"), &mRenderX, &mRenderY, &mRenderW); + + child = FindNode(node, "colors"); + if (child) + { + mLineColor = LoadAttrColor(child, "line"); + mSliderColor = LoadAttrColor(child, "slider"); + } + + child = FindNode(node, "resource"); + if (child) + { + mBackgroundImage = LoadAttrImage(child, "background"); + mHandleImage = LoadAttrImage(child, "handle"); + mHandleHoverImage = LoadAttrImage(child, "handlehover"); + } + + child = FindNode(node, "data"); + if (child) + { + attr = child->first_attribute("variable"); + if (attr) + mVariable = attr->value(); + + attr = child->first_attribute("min"); + if (attr) + { + mMinStr = gui_parse_text(attr->value()); + mMin = atoi(mMinStr.c_str()); + } + + attr = child->first_attribute("max"); + if (attr) + { + mMaxStr = gui_parse_text(attr->value()); + mMax = atoi(mMaxStr.c_str()); + } + + if (mMin > mMax) + mMin = mMax; + + attr = child->first_attribute("default"); + if (attr) + { + string parsevalue = gui_parse_text(attr->value()); + int def = atoi(parsevalue.c_str()); + + if (def < mMin) + def = mMin; + else if (def > mMax) + def = mMax; + DataManager::SetValue(mVariable, def); + } + + attr = child->first_attribute("showrange"); + if (attr) + mShowRange = atoi(attr->value()); + + attr = child->first_attribute("showcurr"); + if (attr) + mShowCurr = atoi(attr->value()); + + attr = child->first_attribute("changeondrag"); + if (attr) + mChangeOnDrag = atoi(attr->value()); + } + + child = FindNode(node, "dimensions"); + if (child) + { + mLineH = LoadAttrIntScaleY(child, "lineh", mLineH); + mLinePadding = LoadAttrIntScaleX(child, "linepadding", mLinePadding); + mSliderW = LoadAttrIntScaleX(child, "sliderw", mSliderW); + mSliderH = LoadAttrIntScaleY(child, "sliderh", mSliderH); + } + + mFontHeight = mFont->GetHeight(); + + if(mShowCurr) + { + int maxLen = std::max(strlen(mMinStr.c_str()), strlen(mMaxStr.c_str())); + mValueStr = new char[maxLen+1]; + } + + loadValue(true); + + if (mShowRange) + { + int textW = std::max(measureText(mMaxStr), measureText(mMinStr)); + mLinePadding += textW; + } + + SetRenderPos(mRenderX, mRenderY, mRenderW); +} + +GUISliderValue::~GUISliderValue() +{ + delete mLabel; + delete mAction; + delete[] mValueStr; +} + +void GUISliderValue::loadValue(bool force) +{ + if(!mVariable.empty()) + { + int value = DataManager::GetIntValue(mVariable); + if(mValue == value && !force) + return; + + mValue = value; + } + + mValue = std::max(mValue, mMin); + mValue = std::min(mValue, mMax); + mValuePct = pctFromValue(mValue); + mRendered = false; +} + +int GUISliderValue::SetRenderPos(int x, int y, int w, int h) +{ + mRenderX = x; + mRenderY = y; + if (w || h) + { + mRenderW = w; + mRenderH = h; + } + + mRenderH = mSliderH; + if(mShowCurr) + mRenderH += mFontHeight; + + if (mLabel) + { + int lw, lh; + mLabel->GetCurrentBounds(lw, lh); + int textX = mRenderX + (mRenderW/2 - lw/2); + + mLabel->SetRenderPos(textX, mRenderY); + + y += lh; + mRenderH += lh; + } + + mSliderY = y; + + mActionX = mRenderX; + mActionY = mRenderY; + mActionW = mRenderW; + mActionH = mRenderH; + + if(mBackgroundImage && mBackgroundImage->GetResource()) + { + mLineW = mBackgroundImage->GetWidth(); + mLineH = mBackgroundImage->GetHeight(); + } + else + mLineW = mRenderW - (mLinePadding * 2); + + mLineY = y + (mSliderH/2 - mLineH/2); + mLineX = mRenderX + (mRenderW/2 - mLineW/2); + + return 0; +} + +int GUISliderValue::measureText(const std::string& str) +{ + void* fontResource = NULL; + if (mFont) fontResource = mFont->GetResource(); + + return gr_measureEx(str.c_str(), fontResource); +} + +int GUISliderValue::Render(void) +{ + if (!isConditionTrue()) + { + mRendered = false; + return 0; + } + + if(mLabel) + { + int w, h; + mLabel->GetCurrentBounds(w, h); + if (w != mLabelW) { + mLabelW = w; + int textX = mRenderX + (mRenderW/2 - mLabelW/2); + mLabel->SetRenderPos(textX, mRenderY); + } + int res = mLabel->Render(); + if(res < 0) + return res; + } + + // line + if(mBackgroundImage && mBackgroundImage->GetResource()) + { + gr_blit(mBackgroundImage->GetResource(), 0, 0, mLineW, mLineH, mLineX, mLineY); + } + else + { + gr_color(mLineColor.red, mLineColor.green, mLineColor.blue, mLineColor.alpha); + gr_fill(mLineX, mLineY, mLineW, mLineH); + } + + // slider + uint32_t sliderX = mLineX + (mValuePct*(mLineW - mSliderW))/100; + + if(mHandleImage && mHandleImage->GetResource()) + { + gr_surface s = mHandleImage->GetResource(); + if(mDragging && mHandleHoverImage && mHandleHoverImage->GetResource()) + s = mHandleHoverImage->GetResource(); + gr_blit(s, 0, 0, mSliderW, mSliderH, sliderX, mLineY + (mLineH/2 - mSliderH/2)); + } + else + { + gr_color(mSliderColor.red, mSliderColor.green, mSliderColor.blue, mSliderColor.alpha); + gr_fill(sliderX, mSliderY, mSliderW, mSliderH); + } + + void *fontResource = NULL; + if(mFont) fontResource = mFont->GetResource(); + gr_color(mTextColor.red, mTextColor.green, mTextColor.blue, mTextColor.alpha); + if(mShowRange) + { + int rangeY = (mLineY - mLineH/2) - mFontHeight/2; + gr_textEx(mRenderX + mPadding/2, rangeY, mMinStr.c_str(), fontResource); + gr_textEx(mLineX + mLineW + mPadding/2, rangeY, mMaxStr.c_str(), fontResource); + } + + if(mValueStr && mShowCurr) + { + sprintf(mValueStr, "%d", mValue); + int textW = measureText(mValueStr); + gr_textEx(mRenderX + (mRenderW/2 - textW/2), mSliderY+mSliderH, mValueStr, fontResource); + } + + mRendered = true; + return 0; +} + +int GUISliderValue::Update(void) +{ + if (!isConditionTrue()) + return mRendered ? 2 : 0; + if (!mRendered) + return 2; + + if(mLabel) + return mLabel->Update(); + return 0; +} + +int GUISliderValue::valueFromPct(float pct) +{ + int range = abs(mMax - mMin); + return mMin + (pct * range) / 100; +} + +float GUISliderValue::pctFromValue(int value) +{ + return float((value - mMin) * 100) / abs(mMax - mMin); +} + +int GUISliderValue::NotifyTouch(TOUCH_STATE state, int x, int y) +{ + if (!isConditionTrue()) + return -1; + + switch (state) + { + case TOUCH_START: + if (x >= mLineX && x <= mLineX + mLineW && + y >= mRenderY && y <= mRenderY + mRenderH) + { + mDragging = true; + } + // no break + case TOUCH_DRAG: + { + if (!mDragging) return 0; + + x = std::max(mLineX + mSliderW/2, x); + x = std::min(mLineX + mLineW - mSliderW/2, x); + + mValuePct = float(((x - (mLineX + mSliderW/2)) * 100) / (mLineW - mSliderW)); + int newVal = valueFromPct(mValuePct); + if (newVal != mValue) { + mRendered = false; + mValue = newVal; + if (mChangeOnDrag) { + if (!mVariable.empty()) + DataManager::SetValue(mVariable, mValue); + if (mAction) + mAction->doActions(); + } + } + break; + } + case TOUCH_RELEASE: + { + if (!mDragging) return 0; + mDragging = false; + + if (!mVariable.empty()) + DataManager::SetValue(mVariable, mValue); + if (mAction) + mAction->doActions(); + break; + } + case TOUCH_REPEAT: + case TOUCH_HOLD: + break; + } + return 0; +} + +int GUISliderValue::NotifyVarChange(const std::string& varName, const std::string& value) +{ + GUIObject::NotifyVarChange(varName, value); + + if (mLabel) + mLabel->NotifyVarChange(varName, value); + if (varName == mVariable) { + int newVal = atoi(value.c_str()); + if(newVal != mValue) { + mValue = newVal; + mValuePct = pctFromValue(mValue); + mRendered = false; + } + } + return 0; +} + +void GUISliderValue::SetPageFocus(int inFocus) +{ + if (inFocus) + loadValue(); +} diff --git a/gui/text.cpp b/gui/text.cpp new file mode 100644 index 000000000..effb9359b --- /dev/null +++ b/gui/text.cpp @@ -0,0 +1,170 @@ +// text.cpp - GUIText object + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/reboot.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/ioctl.h> +#include <time.h> +#include <unistd.h> +#include <stdlib.h> + +#include <string> + +extern "C" { +#include "../twcommon.h" +#include "../minuitwrp/minui.h" +} + +#include "rapidxml.hpp" +#include "objects.hpp" + +GUIText::GUIText(xml_node<>* node) + : GUIObject(node) +{ + mFont = NULL; + mIsStatic = 1; + mVarChanged = 0; + mFontHeight = 0; + maxWidth = 0; + charSkip = 0; + isHighlighted = false; + + if (!node) + return; + + // Load colors + mColor = LoadAttrColor(node, "color", COLOR(0,0,0,255)); + mHighlightColor = LoadAttrColor(node, "highlightcolor", mColor); + + // Load the font, and possibly override the color + mFont = LoadAttrFont(FindNode(node, "font"), "resource"); + mColor = LoadAttrColor(FindNode(node, "font"), "color", mColor); + mHighlightColor = LoadAttrColor(FindNode(node, "font"), "highlightcolor", mColor); + + // Load the placement + LoadPlacement(FindNode(node, "placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH, &mPlacement); + + xml_node<>* child = FindNode(node, "text"); + if (child) mText = child->value(); + + // Simple way to check for static state + mLastValue = gui_parse_text(mText); + if (mLastValue != mText) mIsStatic = 0; + + mFontHeight = mFont->GetHeight(); +} + +int GUIText::Render(void) +{ + if (!isConditionTrue()) + return 0; + + void* fontResource = NULL; + if (mFont) + fontResource = mFont->GetResource(); + + mLastValue = gui_parse_text(mText); + string displayValue = mLastValue; + + if (charSkip) + displayValue.erase(0, charSkip); + + mVarChanged = 0; + + int x = mRenderX, y = mRenderY; + int width = gr_measureEx(displayValue.c_str(), fontResource); + + if (mPlacement != TOP_LEFT && mPlacement != BOTTOM_LEFT) + { + if (mPlacement == CENTER || mPlacement == CENTER_X_ONLY) + x -= (width / 2); + else + x -= width; + } + if (mPlacement != TOP_LEFT && mPlacement != TOP_RIGHT) + { + if (mPlacement == CENTER) + y -= (mFontHeight / 2); + else if (mPlacement == BOTTOM_LEFT || mPlacement == BOTTOM_RIGHT) + y -= mFontHeight; + } + + if (isHighlighted) + gr_color(mHighlightColor.red, mHighlightColor.green, mHighlightColor.blue, mHighlightColor.alpha); + else + gr_color(mColor.red, mColor.green, mColor.blue, mColor.alpha); + + if (maxWidth) + gr_textExW(x, y, displayValue.c_str(), fontResource, maxWidth + x); + else + gr_textEx(x, y, displayValue.c_str(), fontResource); + return 0; +} + +int GUIText::Update(void) +{ + if (!isConditionTrue()) + return 0; + + static int updateCounter = 3; + + // This hack just makes sure we update at least once a minute for things like clock and battery + if (updateCounter) updateCounter--; + else + { + mVarChanged = 1; + updateCounter = 3; + } + + if (mIsStatic || !mVarChanged) + return 0; + + std::string newValue = gui_parse_text(mText); + if (mLastValue == newValue) + return 0; + else + mLastValue = newValue; + return 2; +} + +int GUIText::GetCurrentBounds(int& w, int& h) +{ + void* fontResource = NULL; + + if (mFont) + fontResource = mFont->GetResource(); + + h = mFontHeight; + mLastValue = gui_parse_text(mText); + w = gr_measureEx(mLastValue.c_str(), fontResource); + return 0; +} + +int GUIText::NotifyVarChange(const std::string& varName, const std::string& value) +{ + GUIObject::NotifyVarChange(varName, value); + + mVarChanged = 1; + return 0; +} + +int GUIText::SetMaxWidth(unsigned width) +{ + maxWidth = width; + mVarChanged = 1; + return 0; +} + +int GUIText::SkipCharCount(unsigned skip) +{ + charSkip = skip; + mVarChanged = 1; + return 0; +} diff --git a/gui/twrp b/gui/twrp new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/gui/twrp |