diff --git a/gui/listbox.cpp b/gui/listbox.cpp
new file mode 100644
index 0000000..888947b
--- /dev/null
+++ b/gui/listbox.cpp
@@ -0,0 +1,381 @@
+// ListBox.cpp - GUIListBox 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 <dirent.h>
+#include <ctype.h>
+
+#include <algorithm>
+
+extern "C" {
+#include "../common.h"
+#include "../roots.h"
+#include "../minuitwrp/minui.h"
+#include "../recovery_ui.h"
+}
+
+#include "rapidxml.hpp"
+#include "objects.hpp"
+#include "../data.hpp"
+
+GUIListBox::GUIListBox(xml_node<>* node)
+{
+    xml_attribute<>* attr;
+    xml_node<>* child;
+
+    mStart = mLineSpacing = mIconWidth = mIconHeight = 0;
+    mIconSelected = mIconUnselected = mBackground = mFont = NULL;
+    mBackgroundX = mBackgroundY = mBackgroundW = mBackgroundH = 0;
+    mUpdate = 0;
+    ConvertStrToColor("black", &mBackgroundColor);
+    ConvertStrToColor("white", &mFontColor);
+    
+    child = node->first_node("icon");
+    if (child)
+    {
+        attr = child->first_attribute("selected");
+        if (attr)
+            mIconSelected = PageManager::FindResource(attr->value());
+        attr = child->first_attribute("unselected");
+        if (attr)
+            mIconUnselected = PageManager::FindResource(attr->value());
+    }
+    child = node->first_node("background");
+    if (child)
+    {
+        attr = child->first_attribute("resource");
+        if (attr)
+            mBackground = PageManager::FindResource(attr->value());
+        attr = child->first_attribute("color");
+        if (attr)
+        {
+            std::string color = attr->value();
+            ConvertStrToColor(color, &mBackgroundColor);
+        }
+    }
+
+    // Load the placement
+    LoadPlacement(node->first_node("placement"), &mRenderX, &mRenderY, &mRenderW, &mRenderH);
+    SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH);
+
+    // Load the font, and possibly override the color
+    child = node->first_node("font");
+    if (child)
+    {
+        attr = child->first_attribute("resource");
+        if (attr)
+            mFont = PageManager::FindResource(attr->value());
+
+        attr = child->first_attribute("color");
+        if (attr)
+        {
+            std::string color = attr->value();
+            ConvertStrToColor(color, &mFontColor);
+        }
+
+        attr = child->first_attribute("spacing");
+        if (attr) {
+			string parsevalue = gui_parse_text(attr->value());
+            mLineSpacing = atoi(parsevalue.c_str());
+		}
+    }
+
+    // Handle the result variable
+    child = node->first_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());
+    }
+
+    // Retrieve the line height
+    gr_getFontDetails(mFont ? mFont->GetResource() : NULL, &mFontHeight, NULL);
+    mLineHeight = mFontHeight;
+    if (mIconSelected && mIconSelected->GetResource())
+    {
+        if (gr_get_height(mIconSelected->GetResource()) > mLineHeight)
+            mLineHeight = gr_get_height(mIconSelected->GetResource());
+        mIconWidth = gr_get_width(mIconSelected->GetResource());
+        mIconHeight = gr_get_height(mIconSelected->GetResource());
+    }
+    if (mIconUnselected && mIconUnselected->GetResource())
+    {
+        if (gr_get_height(mIconUnselected->GetResource()) > mLineHeight)
+            mLineHeight = gr_get_height(mIconUnselected->GetResource());
+        mIconWidth = gr_get_width(mIconUnselected->GetResource());
+        mIconHeight = gr_get_height(mIconUnselected->GetResource());
+    }
+        
+    if (mBackground && mBackground->GetResource())
+    {
+        mBackgroundW = gr_get_width(mBackground->GetResource());
+        mBackgroundH = gr_get_height(mBackground->GetResource());
+    }
+	
+	// Get the currently selected value for the list
+	DataManager::GetValue(mVariable, currentValue);
+
+	// Get the data for the list
+	child = node->first_node("listitem");
+    if (!child) return;
+	
+	while (child)
+    {
+        ListData data;
+
+		attr = child->first_attribute("name");
+        if (!attr) return;
+        data.displayName = attr->value();
+
+		data.variableValue = child->value();
+		if (child->value() == currentValue)
+			data.selected = 1;
+		else
+			data.selected = 0;
+
+        mList.push_back(data);
+
+        child = child->next_sibling("listitem");
+    }
+
+	// Call this to get the selected item to be shown in the list on first render
+	NotifyVarChange(mVariable, currentValue);
+}
+
+GUIListBox::~GUIListBox()
+{
+}
+
+int GUIListBox::Render(void)
+{	
+	// 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);
+    }
+
+    // Now, we need the lines (icon + text)
+    gr_color(mFontColor.red, mFontColor.green, mFontColor.blue, mFontColor.alpha);
+
+    // This tells us how many lines we can actually render
+    int lines = mRenderH / (mLineHeight + mLineSpacing);
+    int line;
+
+    int listSize = mList.size();
+
+    if (listSize < lines)  lines = listSize;
+
+    void* fontResource = NULL;
+    if (mFont)  fontResource = mFont->GetResource();
+
+    int yPos = mRenderY + (mLineSpacing / 2);
+    for (line = 0; line < lines; line++)
+    {
+        Resource* icon;
+        std::string label;
+
+        label = mList.at(line + mStart).displayName;
+		if (mList.at(line + mStart).selected != 0)
+        {
+            icon = mIconSelected;
+        }
+        else
+        {
+            icon = mIconUnselected;
+        }
+
+        if (icon && icon->GetResource())
+        {
+            gr_blit(icon->GetResource(), 0, 0, mIconWidth, mIconHeight, mRenderX, (yPos + (int)((mLineHeight - mIconHeight) / 2)));
+        }
+        gr_textExW(mRenderX + mIconWidth + 5, yPos, label.c_str(), fontResource, mRenderX + mRenderW - mIconWidth - 5);
+
+        // Move the yPos
+        yPos += mLineHeight + mLineSpacing;
+    }
+
+    mUpdate = 0;
+    return 0;
+}
+
+int GUIListBox::Update(void)
+{
+    if (mUpdate)
+    {
+        mUpdate = 0;
+        if (Render() == 0)
+			return 2;
+    }
+    return 0;
+}
+
+int GUIListBox::GetSelection(int x, int y)
+{
+    // We only care about y position
+    return (y - mRenderY) / (mLineHeight + mLineSpacing);
+}
+
+int GUIListBox::NotifyTouch(TOUCH_STATE state, int x, int y)
+{
+    static int startSelection = -1;
+    static int startY = 0;
+    int selection = 0;
+
+    switch (state)
+    {
+    case TOUCH_START:
+        startSelection = GetSelection(x,y);
+        startY = y;
+        break;
+
+    case TOUCH_DRAG:
+        // Check if we dragged out of the selection window
+        selection = GetSelection(x,y);
+        if (startSelection != selection)
+        {
+            startSelection = -1;
+
+            // Handle scrolling
+            if (y > (int) (startY + (mLineHeight + mLineSpacing)))
+            {
+                if (mStart)     mStart--;
+                mUpdate = 1;
+                startY = y;
+            }
+            else if (y < (int) (startY - (mLineHeight + mLineSpacing)))
+            {
+                int listSize = mList.size();
+                int lines = mRenderH / (mLineHeight + mLineSpacing);
+
+                if (mStart + lines < listSize)     mStart++;
+                mUpdate = 1;
+                startY = y;
+            }
+        }
+        break;
+
+    case TOUCH_RELEASE:
+        if (startSelection >= 0)
+        {
+            // We've selected an item!
+            std::string str;
+
+            int listSize = mList.size();
+
+            // Move the selection to the proper place in the array
+            startSelection += mStart;
+
+            if (startSelection < listSize)
+            {
+                if (!mVariable.empty())
+                {
+                    int i;
+					for (i=0; i<listSize; i++)
+						mList.at(i).selected = 0;
+
+					str = mList.at(startSelection).variableValue;
+					mList.at(startSelection).selected = 1;
+                    DataManager::SetValue(mVariable, str);
+					mUpdate = 1;
+                }
+            }
+        }
+	case TOUCH_HOLD:
+	case TOUCH_REPEAT:
+        break;
+    }
+    return 0;
+}
+
+int GUIListBox::NotifyVarChange(std::string varName, std::string value)
+{
+    string checkValue;
+	int var_changed = 0;
+
+	if (varName.empty())
+    {
+		DataManager::GetValue(mVariable, checkValue);
+		if (checkValue != currentValue) {
+			varName = mVariable;
+			value = checkValue;
+			currentValue = checkValue;
+			var_changed = 1;
+		}
+    }
+    if (varName == mVariable || var_changed != 0)
+    {
+        int i, listSize = mList.size(), selected_index = 0;
+
+		currentValue = value;
+
+		for (i=0; i<listSize; i++) {
+			if (mList.at(i).variableValue == currentValue) {
+				mList.at(i).selected = 1;
+				selected_index = i;
+			} else
+				mList.at(i).selected = 0;
+		}
+
+		int lines = mRenderH / (mLineHeight + mLineSpacing);
+		int line;
+
+		if (selected_index > mStart + lines - 1)
+			mStart = selected_index;
+		if (mStart > listSize - lines) {
+			mStart = listSize - lines;
+		} else if (selected_index < mStart) {
+			mStart = selected_index;
+		}
+
+		mUpdate = 1;
+        return 0;
+    }
+    return 0;
+}
+
+int GUIListBox::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 GUIListBox::SetPageFocus(int inFocus)
+{
+    if (inFocus)
+    {
+        mUpdate = 1;
+    }
+}
+
