瀏覽代碼

Changes mainly for the GUI.

RuneOptimizer:
 - Compiler optimization, way faster now
 - Fixed GUI output for optimize and update commands.

RuneOptimizerGUI:
 - Calls to the CLI are now async and don't block the UI. Added progress indicator and messages.
 - Beter current set detection in the optimizer view.
 - Button to go to the optimizer from the unit view.
 - Redirect to results once the optimization is complete.
 - Code clean up.
Iñigo Valentin 4 年之前
父節點
當前提交
ac5d1ca4b1

+ 1 - 1
src/Makefile

@@ -1,7 +1,7 @@
 CC=gcc
 CC=gcc
 CFLAGS=
 CFLAGS=
 OPTS_DEBUG=-Wall -g -fsanitize=address
 OPTS_DEBUG=-Wall -g -fsanitize=address
-OPTS=
+OPTS=-O3
 LIBS=-lsqlite3 -lm -ljson-c
 LIBS=-lsqlite3 -lm -ljson-c
 OUT=../RuneOptimizer
 OUT=../RuneOptimizer
 compile :
 compile :

+ 23 - 11
src/RuneOptimizer/optimize/optimize.c

@@ -1340,10 +1340,10 @@ int gui_output(Result results[5000], int result_count){
     char tmp[300];
     char tmp[300];
     strcpy(tmp, "");
     strcpy(tmp, "");
     char json[300];
     char json[300];
-    printf("{\"result_count\":%d,\"results\":[\n", result_count);
+    printf("{\"result_count\":%d,\"results\":[", result_count);
     int result_limit = 100;
     int result_limit = 100;
     for (int i = 0; i < result_count && i < result_limit; i++){
     for (int i = 0; i < result_count && i < result_limit; i++){
-        //printf("RES LOOP %d\n", i);
+        //printf("RES LOOP %d", i);
         sprintf(tmp, "{\"id\":%d,\"rating\":%d,", i, results[i].rating);
         sprintf(tmp, "{\"id\":%d,\"rating\":%d,", i, results[i].rating);
         strcpy(json, tmp);
         strcpy(json, tmp);
         sprintf(tmp, "\"hp\":%d,", results[i].stats.hp);
         sprintf(tmp, "\"hp\":%d,", results[i].stats.hp);
@@ -1368,13 +1368,13 @@ int gui_output(Result results[5000], int result_count){
         sprintf(tmp, "\"dmg\":%d,", results[i].stats.dmg);
         sprintf(tmp, "\"dmg\":%d,", results[i].stats.dmg);
         strcat(json, tmp);
         strcat(json, tmp);
         strcat(json, "\"runes\":[");
         strcat(json, "\"runes\":[");
-        //printf("    A %s\n", json);
+        //printf("    A %s", json);
         for (int j = 0; j < 5; j++){
         for (int j = 0; j < 5; j++){
-            //printf("    RUNE LOOP %d\n", j);
+            //printf("    RUNE LOOP %d", j);
             sprintf(tmp, "\"%s\",", results[i].rune_ids[j]);
             sprintf(tmp, "\"%s\",", results[i].rune_ids[j]);
             strcat(json, tmp);
             strcat(json, tmp);
         }
         }
-        //printf("    B %s\n", json);
+        //printf("    B %s", json);
         sprintf(tmp, "\"%s\"", results[i].rune_ids[5]);
         sprintf(tmp, "\"%s\"", results[i].rune_ids[5]);
         strcat(json, tmp);
         strcat(json, tmp);
         strcat(json, "]},");
         strcat(json, "]},");
@@ -1385,7 +1385,7 @@ int gui_output(Result results[5000], int result_count){
         }
         }
 
 
         printf(json);
         printf(json);
-        printf("\n");
+        printf("");
     }
     }
     // Remove last comma
     // Remove last comma
     //json[strlen(json) - 1] = '\0';
     //json[strlen(json) - 1] = '\0';
@@ -1393,10 +1393,10 @@ int gui_output(Result results[5000], int result_count){
 
 
     // End and print
     // End and print
     printf("]}\n");
     printf("]}\n");
-    //printf("STRLEN JSON %d\n", strlen(json));
+    //printf("STRLEN JSON %d", strlen(json));
     //printf("%s", json);
     //printf("%s", json);
     //free(*json);
     //free(*json);
-    //printf("\n\nEND\n\n");
+    //printf("END");
     return SUCCESS;
     return SUCCESS;
 }
 }
 
 
@@ -1531,6 +1531,10 @@ int optimize(int argc, char *argv[]){
     if (gui != 1){
     if (gui != 1){
         printf("\n\n__Optimization progress___________________________\n");
         printf("\n\n__Optimization progress___________________________\n");
     }
     }
+    else{
+        printf("Total combinations: %d\n", max_combinations);
+        fflush(stdout);
+    }
 
 
     // Initialize arrys and some counters
     // Initialize arrys and some counters
     int index[7] = {0, 0, 0, 0, 0, 0};
     int index[7] = {0, 0, 0, 0, 0, 0};
@@ -1550,12 +1554,20 @@ int optimize(int argc, char *argv[]){
     ){
     ){
         // Progress bar, 50 characters to 100%
         // Progress bar, 50 characters to 100%
         if (
         if (
-          gui != 1 &&
           (tested_combinations + 1) %
           (tested_combinations + 1) %
           (unsigned long)(max_combinations / 50)
           (unsigned long)(max_combinations / 50)
           == 0
           == 0
         ){
         ){
-            printf("#");
+            if (gui != 1){
+                printf("#");
+            }
+            else{
+                // For GUI flushing, newlines are required
+                printf(
+                  "%d\n",
+                  (unsigned long)( (tested_combinations + 1) /
+                  (unsigned long)(max_combinations / 20)));
+            }
             // Line buffered! need to flush after every char.
             // Line buffered! need to flush after every char.
             fflush(stdout);
             fflush(stdout);
         }
         }
@@ -1864,7 +1876,7 @@ int optimize(int argc, char *argv[]){
             printf("No results found\n");
             printf("No results found\n");
         }
         }
         else{
         else{
-            fprintf(stderr, "No results found\n");
+            printf("{\"result_count\":0,\"results\":[]}\n");
         }
         }
     }
     }
     return SUCCESS;
     return SUCCESS;

+ 141 - 40
src/RuneOptimizerGUI/classes/DialogUpdateJson.py

@@ -22,20 +22,58 @@ class DialogUpdateJson(wx.Dialog):
 
 
     Parameters
     Parameters
     ----------
     ----------
+    formSizer : wx.BoxSizer
+        Sizer with the file selector and options.
+    progressSizer : wx.BoxSizer
+        Sizer with the progress image. Hidden on class creation.
+    messageSizer : wx.BoxSizer
+        Sizer with the progress message box. Hidden on class creation.
+    buttonSizer : wx.BoxSizer
+        Contains the accept button.
     fileSelector : wxFilePickerCtrl.
     fileSelector : wxFilePickerCtrl.
         File selector
         File selector
-    unitsStars : wx.Checkbox.
+    starsCheck : wx.Checkbox.
         Checkbox to indicate to save only units with 6 stars.
         Checkbox to indicate to save only units with 6 stars.
-    unitsStars : wx.Checkbox.
+    runesCheck : wx.Checkbox.
         Checkbox to indicate to save only units with runes.
         Checkbox to indicate to save only units with runes.
-    clearTeams : wx.Checkbox.
+    teamsCheck : wx.Checkbox.
         Checkbox to indicate team deletion.
         Checkbox to indicate team deletion.
+    updateDone : boolean
+        Indicates if the update process has been run (default False)
+    updateError : boolean
+        Indicates if the update process has been run with errors (default False)
+    messageLabel : wx.StaticText
+        Label wich shows the output of the update process.
+    timer : wx.Timer
+        Timer to check the update process for new output to display.
+    process : wx.Process
+        The update process.
+
+    Methods
+    -------
+    checkProcess(event)
+        Checks the update process for new output.
+    updateComplete(event)
+        Called at process end, cleans the dialog and set status variables.
+    accept(event)
+        Checks from accept button. Starts the update process.
 
 
     """
     """
 
 
+    formSizer = None
+    progressSizer = None
+    messageSizer = None
+    buttonSizer = None
     fileSelector = None
     fileSelector = None
+    starsCheck = None
+    runesCheck = None
+    teamsCheck = None
     updateDone = False
     updateDone = False
     updateError = False
     updateError = False
+    messageLabel = None
+    timer = None
+    process = None
+    process = None
 
 
     def __init__(self, parent, id=wx.ID_ANY):
     def __init__(self, parent, id=wx.ID_ANY):
         """Initializes the panel.
         """Initializes the panel.
@@ -49,37 +87,37 @@ class DialogUpdateJson(wx.Dialog):
           self, parent=parent, id=id, pos=(50, 50), size=(400, 290)
           self, parent=parent, id=id, pos=(50, 50), size=(400, 290)
         )
         )
 
 
-        self.form = wx.BoxSizer(wx.VERTICAL)
-        self.progress = wx.BoxSizer(wx.VERTICAL)
-        self.messages = wx.BoxSizer(wx.VERTICAL)
+        self.formSizer = wx.BoxSizer(wx.VERTICAL)
+        self.progressSizer = wx.BoxSizer(wx.VERTICAL)
+        self.messageSizer = wx.BoxSizer(wx.VERTICAL)
         self.buttonSizer = wx.BoxSizer(wx.VERTICAL)
         self.buttonSizer = wx.BoxSizer(wx.VERTICAL)
 
 
         fileSelectorLabel = wx.StaticText(
         fileSelectorLabel = wx.StaticText(
             parent=self,  id=wx.ID_ANY, label="Select a JSON file",
             parent=self,  id=wx.ID_ANY, label="Select a JSON file",
             pos=(30, 30), size=(130, 30)
             pos=(30, 30), size=(130, 30)
           )
           )
-        self.form.Add(fileSelectorLabel)
+        self.formSizer.Add(fileSelectorLabel)
         self.fileSelector = wx.FilePickerCtrl(parent=self,
         self.fileSelector = wx.FilePickerCtrl(parent=self,
           id=wx.ID_ANY, path="",
           id=wx.ID_ANY, path="",
           message="Select JSON file", wildcard="JSON files (*.json)|*.json",
           message="Select JSON file", wildcard="JSON files (*.json)|*.json",
           style=wx.FC_DEFAULT_STYLE, pos=(140, 20), size=(250, 40)
           style=wx.FC_DEFAULT_STYLE, pos=(140, 20), size=(250, 40)
         )
         )
-        self.form.Add(self.fileSelector)
-        self.unitsStars = wx.CheckBox(
+        self.formSizer.Add(self.fileSelector)
+        self.starsCheck = wx.CheckBox(
           parent=self, id=wx.ID_ANY, label="Only import units at with 6 stars.",
           parent=self, id=wx.ID_ANY, label="Only import units at with 6 stars.",
           pos=(30, 80), size=(230, 20)
           pos=(30, 80), size=(230, 20)
         )
         )
-        self.form.Add(self.unitsStars)
-        self.unitsRunes = wx.CheckBox(
+        self.formSizer.Add(self.starsCheck)
+        self.runesCheck = wx.CheckBox(
           parent=self, id=wx.ID_ANY, label="Only import units with runes.",
           parent=self, id=wx.ID_ANY, label="Only import units with runes.",
           pos=(30, 110), size=(230, 20)
           pos=(30, 110), size=(230, 20)
         )
         )
-        self.form.Add(self.unitsRunes)
+        self.formSizer.Add(self.runesCheck)
         self.clearTeams = wx.CheckBox(
         self.clearTeams = wx.CheckBox(
           parent=self, id=wx.ID_ANY, label="Clear team data",
           parent=self, id=wx.ID_ANY, label="Clear team data",
           pos=(30, 140), size=(230, 20)
           pos=(30, 140), size=(230, 20)
         )
         )
-        self.form.Add(self.clearTeams)
+        self.formSizer.Add(self.clearTeams)
 
 
         self.btAccept = wx.Button(
         self.btAccept = wx.Button(
           parent=self, id=wx.ID_ANY, pos=(100, 180),
           parent=self, id=wx.ID_ANY, pos=(100, 180),
@@ -92,22 +130,96 @@ class DialogUpdateJson(wx.Dialog):
         self.buttonSizer.Add(self.btAccept)
         self.buttonSizer.Add(self.btAccept)
         self.Bind(wx.EVT_BUTTON, self.accept, self.btAccept)
         self.Bind(wx.EVT_BUTTON, self.accept, self.btAccept)
 
 
+        anim = wx.adv.Animation(
+          os.path.dirname(os.path.realpath(__file__)) + '/res/icon/progress.gif'
+        )
+        progressCtrl = wx.adv.AnimationCtrl(
+          parent=self, id=wx.ID_ANY, anim=anim, pos=(126, 176), size=(48, 48)
+        )
+        progressCtrl.Play()
+        self.progressSizer.Add(progressCtrl)
+
         # Progress message
         # Progress message
-        self.message = wx.StaticText(
+        self.messageLabel = wx.StaticText(
           parent=self,  id=wx.ID_ANY, label="",
           parent=self,  id=wx.ID_ANY, label="",
           pos=(20, 20), size=(340, 460)
           pos=(20, 20), size=(340, 460)
         )
         )
-        self.messages.Add(self.message)
+        self.messageSizer.Add(self.messageLabel)
+
+        # Hide progress bar and messages
+        self.progressSizer.ShowItems(False)
+        self.messageSizer.ShowItems(False)
+
+    def checkProcess(self, event):
+        """Checks the process output and updates the progress message.
+
+        Parameters
+        ----------
+        event : wxEvent, optional
+            The event that triggered the call.
+
+        """
+
+        if self.process is not None:
+            stream = self.process.GetInputStream()
+            if stream.CanRead():
+                text = bytes.decode(stream.read())
+                #text = text[:-1] # Remove the last newline
+                self.messageLabel.SetLabel(text)
+        else:
+            self.timer.Stop()
+
+    def updateComplete(self, event):
+        """Called when the update process is complete.
+
+        Hiddes the progress image, checks for errors in the output, prints a
+        message annd sets self.updateDone and self.updateError.
+
+        Parameters
+        ----------
+        event : wxEvent, optional
+            The event that triggered the call.
+
+        """
+
+        self.timer.Stop()
+        self.progressSizer.ShowItems(False)
+        errStream = bytes.decode(self.process.GetErrorStream().read())
+        if errStream == "":
+            self.messageLabel.SetLabel(
+              self.messageLabel.GetLabel() + "\nAll done!"
+            )
+            self.updateDone = True
+            self.updateError = False
+        else:
+            self.messageLabel.SetLabel(
+              self.messageLabel.GetLabel() +
+              "\nUpdate didnt' complete succesfully"
+            )
+            self.updateDone = True
+            self.updateError = True
 
 
     def accept(self, event):
     def accept(self, event):
-        self.form.ShowItems(False)
+        """Called when the accept button is clicked.
+
+        Hiddes the form and shows the progress image and message box, composes
+        the command and launchs it
+
+        Parameters
+        ----------
+        event : wxEvent, optional
+            The event that triggered the call.
+
+        """
+        self.formSizer.ShowItems(False)
+        self.progressSizer.ShowItems(True)
+        self.messageSizer.ShowItems(True)
         self.buttonSizer.ShowItems(False)
         self.buttonSizer.ShowItems(False)
-        self.Update()
         command = "RuneOptimizer update "
         command = "RuneOptimizer update "
         command += pipes.quote(self.fileSelector.GetPath())
         command += pipes.quote(self.fileSelector.GetPath())
-        if self.unitsStars.GetValue():
+        if self.starsCheck.GetValue():
             command += " --six-stars"
             command += " --six-stars"
-        if self.unitsRunes.GetValue():
+        if self.runesCheck.GetValue():
             command += " --with-runes"
             command += " --with-runes"
         if self.clearTeams.GetValue():
         if self.clearTeams.GetValue():
             command += " --clear-teams"
             command += " --clear-teams"
@@ -115,25 +227,14 @@ class DialogUpdateJson(wx.Dialog):
         command = \
         command = \
           os.path.dirname(os.path.realpath(__file__)) + "/../../" + command
           os.path.dirname(os.path.realpath(__file__)) + "/../../" + command
         print("Command: " + command)
         print("Command: " + command)
-        process = \
-          subprocess.Popen(command.split(),shell=False,stdout=subprocess.PIPE)
-
-        # Poll process.stdout to show stdout live
-        while True:
-            output = process.stdout.readline()
-            if process.poll() is not None:
-                break
-            if output:
-                self.message.SetLabel(self.message.GetLabel() + bytes.decode(output.strip()) + "\n")
-            self.Update()
-        self.Update()
-        rc = process.poll()
-
-        if process.returncode == 0:
-            self.message.SetLabel(self.message.GetLabel() + "\nAll done!")
-            self.updateDone = True
-            self.updateError = False
-        else:
-            self.updateDone = True
-            self.updateError = True
 
 
+        # Timer ot periodically check on the process
+        self.timer = wx.Timer(self)
+        self.timer.Start(1000)
+        self.Bind(wx.EVT_TIMER, self.checkProcess)
+
+        # Create the process
+        self.Bind(wx.EVT_END_PROCESS, self.updateComplete)
+        self.process = wx.Process(self)
+        self.process.Redirect()
+        wx.Execute(command, wx.EXEC_ASYNC, self.process)

+ 321 - 155
src/RuneOptimizerGUI/classes/PanelOptimizer.py

@@ -24,49 +24,62 @@ class PanelOptimizer(wx.Panel):
     ----------
     ----------
     unitId : string
     unitId : string
         Currently selected unit ID (default None)
         Currently selected unit ID (default None)
-    optimizationOptions : wx.BoxSizer
-        Holds every widget that is hidden until a unit is selected.
-    unitInfo : wx.StaticBox
-        Box containig the non-editable elements with a unit info.
+    unitStats : int[10]
+        The current stats of the selected unit (HP, ATK, DEF, SPD, CRR, CRD,
+        RES, ACC). (default is [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).
+    teamIds : string[]
+        IDs of all teams, indexed by the order they appear in the team selector.
     unitIdSelectorIndex : int[]
     unitIdSelectorIndex : int[]
         Array with the IDs of all units, in the same order as displayed in
         Array with the IDs of all units, in the same order as displayed in
-        unitSelector, so an ID can be retrived knowing the choice
+        unitChoice, so an ID can be retrived knowing the choice
         selected index.
         selected index.
-    unitSelector : wx.Choice
+    optionsSizer : wx.BoxSizer
+        Holds every widget that is hidden until a unit is selected.
+    unitInfoBox : wx.StaticBox
+        Box containig the non-editable elements with a unit info.
+    unitChoice : wx.Choice
         Unit selecctor. Choosing a unit triggers selectUnit.
         Unit selecctor. Choosing a unit triggers selectUnit.
     statGrid : wx.Grid.grid
     statGrid : wx.Grid.grid
         Table with the unit base and current stats.
         Table with the unit base and current stats.
-    runeList : wx.StaticText[6]
+    runeLabelList : wx.StaticText[6]
         Labels with all the info about the currently equipped runes.
         Labels with all the info about the currently equipped runes.
-    minStatSlid : wx.Slider[6]
+    minStatSlidList : wx.Slider[6]
         List of sliders for the minimum selectors for each stat.
         List of sliders for the minimum selectors for each stat.
-    minStatText : wx.StaticText[6]
+    minStatTextList : wx.StaticText[6]
         List of text inputs for the minimum selectors for each stat.
         List of text inputs for the minimum selectors for each stat.
-    stats : wx.CheckListBox[2]
+    statCheckListList : wx.CheckListBox[2]
         Tho selctors to choose stats allowed in optimization.
         Tho selctors to choose stats allowed in optimization.
-    runeSets : wx.Choice[3]
+    setChoiceList : wx.Choice[3]
         List of selector to pik rune sets.
         List of selector to pik rune sets.
-    level : wx.Choice
+    levelChoice : wx.Choice
         Selector to pick the level for the rune optimization.
         Selector to pick the level for the rune optimization.
-    inventory : wx.Checkbox
+    inventoryCheck : wx.Checkbox
         Checkbox to use only runes in the inventory
         Checkbox to use only runes in the inventory
-    teams : wx.CheckboxList :
+    teamCheckList : wx.CheckboxList :
         List of selectable teams to exclude from the optimization.
         List of selectable teams to exclude from the optimization.
-    unitStats : int[10]
-        The current stats of the selected unit. (default is
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).
-    teamIds : string[]
-        IDs of all teams, indexed by the order they appear in the team selector.
+    progressGauge : wx.Gauge
+        A progress bar
+    timer : wx.Timer
+        Timer to check the update process for new output to display.
+    process : wx.Process
+        The update process.
 
 
     Methods
     Methods
     -------
     -------
+    selectAllTeams(event)
+        Selects all teams in the list.
+    deselectAllTeams(event)
+        Deselects all teams in the list.
     selectUnit(event)
     selectUnit(event)
         Loads a unit info and enables optimizaton options.
         Loads a unit info and enables optimizaton options.
     processResults(jsonData)
     processResults(jsonData)
         Processes data obtained from RuneOptimizer.
         Processes data obtained from RuneOptimizer.
-
     startOptimization(event)
     startOptimization(event)
         Prepares and runs a command optimization.
         Prepares and runs a command optimization.
+    checkProcess(event)
+        Checks the process and update the progress bar.
+    updateComplete(event)
+        Called at process end, rediresct to the result view.
     minStatChangeBySlider(event)
     minStatChangeBySlider(event)
         Changes text when a slider is changed.
         Changes text when a slider is changed.
     minStatChangeByTExt(event)
     minStatChangeByTExt(event)
@@ -75,21 +88,24 @@ class PanelOptimizer(wx.Panel):
     """
     """
 
 
     unitId = None
     unitId = None
-    optimizationOptions = None
-    unitInfo = None
-    unidIdSelectorIndex = []
-    unitSelector = None
-    statGrid = None
-    runeList = None
-    minStatSlid = None
-    minStatText = None
-    stats = None
-    runeSets = None
-    level = None
-    inventory = None
-    teams = None
     unitStats = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
     unitStats = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
     teamIds = []
     teamIds = []
+    unidIdSelectorIndex = []
+    optionsSizer = None
+    unitInfoBox = None
+    unitChoice = None
+    statGrid = None
+    runeLabelList = None
+    minStatSlidList = None
+    minStatTextList = None
+    statCheckListList = None
+    setChoiceList = None
+    levelChoice = None
+    inventoryCheck = None
+    teamCheckList = None
+    progressGauge = None
+    timer = None
+    process = None
 
 
     def __init__(self, parent, id=wx.ID_ANY):
     def __init__(self, parent, id=wx.ID_ANY):
         """Initializes the panel.
         """Initializes the panel.
@@ -109,10 +125,10 @@ class PanelOptimizer(wx.Panel):
 
 
         # Sizer for all optimization options. Will be hidden until a unit is
         # Sizer for all optimization options. Will be hidden until a unit is
         # selected.
         # selected.
-        self.optimizationOptions = wx.BoxSizer(wx.VERTICAL)
+        self.optionsSizer = wx.BoxSizer(wx.VERTICAL)
 
 
         # Unit info box
         # Unit info box
-        self.unitInfo = wx.StaticBox(
+        self.unitInfoBox = wx.StaticBox(
           self, label="Select unit:", id=wx.ID_ANY, pos=(10, 0), size=(450, 300)
           self, label="Select unit:", id=wx.ID_ANY, pos=(10, 0), size=(450, 300)
         )
         )
 
 
@@ -122,15 +138,15 @@ class PanelOptimizer(wx.Panel):
         for row in cursor:
         for row in cursor:
             names.append(row[1])
             names.append(row[1])
             self.unidIdSelectorIndex.append(row[0])
             self.unidIdSelectorIndex.append(row[0])
-        self.unitSelector =wx.Choice(
-          parent=self.unitInfo, id=wx.ID_ANY, pos=(10, 0),
+        self.unitChoice =wx.Choice(
+          parent=self.unitInfoBox, id=wx.ID_ANY, pos=(10, 0),
           size=(200, 30), choices=names
           size=(200, 30), choices=names
         )
         )
-        self.Bind(wx.EVT_CHOICE, self.selectUnit, self.unitSelector)
+        self.Bind(wx.EVT_CHOICE, self.selectUnit, self.unitChoice)
 
 
         # Stats table
         # Stats table
         self.statGrid = wx.grid.Grid(
         self.statGrid = wx.grid.Grid(
-          parent=self.unitInfo, id=wx.ID_ANY, pos=(0, 30), size=(165, 220)
+          parent=self.unitInfoBox, id=wx.ID_ANY, pos=(0, 30), size=(165, 220)
         )
         )
         self.statGrid.CreateGrid(
         self.statGrid.CreateGrid(
           numRows=10, numCols=2,
           numRows=10, numCols=2,
@@ -170,61 +186,61 @@ class PanelOptimizer(wx.Panel):
         #self.unitContent.Add(self.statGrid)
         #self.unitContent.Add(self.statGrid)
 
 
         #Rune set list
         #Rune set list
-        runeListBox = [
+        runeBoxList = [
           wx.StaticBox(
           wx.StaticBox(
-            parent=self.unitInfo, label="Slot1:", id=wx.ID_ANY,
+            parent=self.unitInfoBox, label="Slot1:", id=wx.ID_ANY,
             pos=(265, 30), size=(80, 115)
             pos=(265, 30), size=(80, 115)
           ),
           ),
           wx.StaticBox(
           wx.StaticBox(
-            parent=self.unitInfo, label="Slot2:", id=wx.ID_ANY,
+            parent=self.unitInfoBox, label="Slot2:", id=wx.ID_ANY,
             pos=(350, 30), size=(80, 115)
             pos=(350, 30), size=(80, 115)
           ),
           ),
           wx.StaticBox(
           wx.StaticBox(
-            parent=self.unitInfo, label="Slot3:", id=wx.ID_ANY,
+            parent=self.unitInfoBox, label="Slot3:", id=wx.ID_ANY,
             pos=(350, 150), size=(80, 115)
             pos=(350, 150), size=(80, 115)
           ),
           ),
           wx.StaticBox(
           wx.StaticBox(
-            parent=self.unitInfo, label="Slot4:", id=wx.ID_ANY,
+            parent=self.unitInfoBox, label="Slot4:", id=wx.ID_ANY,
             pos=(265, 150), size=(80, 115)
             pos=(265, 150), size=(80, 115)
           ),
           ),
           wx.StaticBox(
           wx.StaticBox(
-            parent=self.unitInfo, label="Slot5:", id=wx.ID_ANY,
+            parent=self.unitInfoBox, label="Slot5:", id=wx.ID_ANY,
             pos=(180, 150), size=(80, 115)
             pos=(180, 150), size=(80, 115)
           ),
           ),
           wx.StaticBox(
           wx.StaticBox(
-            parent=self.unitInfo, label="Slot6:", id=wx.ID_ANY,
+            parent=self.unitInfoBox, label="Slot6:", id=wx.ID_ANY,
             pos=(180, 30), size=(80, 115)
             pos=(180, 30), size=(80, 115)
           )
           )
         ]
         ]
-        self.runeList = [
+        self.runeLabelList = [
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[0],  id=wx.ID_ANY, label="",
+            parent=runeBoxList[0],  id=wx.ID_ANY, label="",
             pos=(0, 0), size=(80, 115)
             pos=(0, 0), size=(80, 115)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[1],  id=wx.ID_ANY, label="",
+            parent=runeBoxList[1],  id=wx.ID_ANY, label="",
             pos=(0, 0), size=(80, 115)
             pos=(0, 0), size=(80, 115)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[2],  id=wx.ID_ANY, label="",
+            parent=runeBoxList[2],  id=wx.ID_ANY, label="",
             pos=(0, 0), size=(80, 115)
             pos=(0, 0), size=(80, 115)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[3],  id=wx.ID_ANY, label="",
+            parent=runeBoxList[3],  id=wx.ID_ANY, label="",
             pos=(0, 0), size=(80, 115)
             pos=(0, 0), size=(80, 115)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[4],  id=wx.ID_ANY, label="",
+            parent=runeBoxList[4],  id=wx.ID_ANY, label="",
             pos=(0, 0), size=(80, 115)
             pos=(0, 0), size=(80, 115)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[5],  id=wx.ID_ANY, label="",
+            parent=runeBoxList[5],  id=wx.ID_ANY, label="",
             pos=(0, 0), size=(80, 115)
             pos=(0, 0), size=(80, 115)
           )
           )
         ]
         ]
         monospaceFont.PointSize -= 2
         monospaceFont.PointSize -= 2
         for i in range(0, 6):
         for i in range(0, 6):
-            runeListBox[i].SetFont(monospaceFont)
+            runeBoxList[i].SetFont(monospaceFont)
         monospaceFont.PointSize += 2
         monospaceFont.PointSize += 2
 
 
         # Min stats
         # Min stats
@@ -271,7 +287,7 @@ class PanelOptimizer(wx.Panel):
           parent=minStatBox, label="DMG", id=wx.ID_ANY,
           parent=minStatBox, label="DMG", id=wx.ID_ANY,
           pos=(0, 225), size=(30, 25)
           pos=(0, 225), size=(30, 25)
         )
         )
-        self.minStatSlid = [
+        self.minStatSlidList = [
             wx.Slider(
             wx.Slider(
               parent=minStatBox, id=wx.ID_ANY, pos=(30, 0),
               parent=minStatBox, id=wx.ID_ANY, pos=(30, 0),
               size=(120, 25), name="slid0"
               size=(120, 25), name="slid0"
@@ -314,13 +330,13 @@ class PanelOptimizer(wx.Panel):
             )
             )
         ]
         ]
         for i in range(0, 10):
         for i in range(0, 10):
-            self.minStatSlid[i].SetMin(0)
-            self.minStatSlid[i].SetMax(0)
-            self.minStatSlid[i].SetValue(0)
+            self.minStatSlidList[i].SetMin(0)
+            self.minStatSlidList[i].SetMax(0)
+            self.minStatSlidList[i].SetValue(0)
             self.Bind(
             self.Bind(
-              wx.EVT_SCROLL, self.minStatChangeBySlider, self.minStatSlid[i]
+              wx.EVT_SCROLL, self.minStatChangeBySlider, self.minStatSlidList[i]
             )
             )
-        self.minStatText = [
+        self.minStatTextList = [
             wx.TextCtrl(
             wx.TextCtrl(
               minStatBox, id=wx.ID_ANY, value="", pos=(155, 0), size=(65, 25),
               minStatBox, id=wx.ID_ANY, value="", pos=(155, 0), size=(65, 25),
               style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB
               style=wx.TE_RIGHT|wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB
@@ -364,7 +380,8 @@ class PanelOptimizer(wx.Panel):
         ]
         ]
         for i in range(0, 9):
         for i in range(0, 9):
             self.Bind(
             self.Bind(
-              wx.EVT_TEXT_ENTER, self.minStatChangeByText, self.minStatText[i]
+              wx.EVT_TEXT_ENTER,
+              self.minStatChangeByText, self.minStatTextList[i]
             )
             )
         minStatsReset = wx.Button(
         minStatsReset = wx.Button(
           parent=minStatBox, id=wx.ID_ANY, pos=(10, 250),
           parent=minStatBox, id=wx.ID_ANY, pos=(10, 250),
@@ -374,7 +391,7 @@ class PanelOptimizer(wx.Panel):
           parent=minStatBox, id=wx.ID_ANY, pos=(120, 250),
           parent=minStatBox, id=wx.ID_ANY, pos=(120, 250),
           size=(100, 20), style=wx.LC_REPORT, label="Adapt all")
           size=(100, 20), style=wx.LC_REPORT, label="Adapt all")
         # TODO: Add binds
         # TODO: Add binds
-        self.optimizationOptions.Add(minStatBox)
+        self.optionsSizer.Add(minStatBox)
 
 
         # Allowed main stats for even slots
         # Allowed main stats for even slots
         names = [
         names = [
@@ -385,7 +402,7 @@ class PanelOptimizer(wx.Panel):
           self, id=wx.ID_ANY, label="Main stats (2, 4, 6):",
           self, id=wx.ID_ANY, label="Main stats (2, 4, 6):",
           pos=(10, 300), size=(150, 190)
           pos=(10, 300), size=(150, 190)
         )
         )
-        self.stats = [
+        self.statCheckListList = [
           wx.CheckListBox(
           wx.CheckListBox(
             parent=statBox, id=wx.ID_ANY, pos=(5, 5),
             parent=statBox, id=wx.ID_ANY, pos=(5, 5),
             size=(70, 155), choices=names[0]
             size=(70, 155), choices=names[0]
@@ -395,20 +412,20 @@ class PanelOptimizer(wx.Panel):
             size=(70, 155), choices=names[1]
             size=(70, 155), choices=names[1]
           )
           )
         ]
         ]
-        self.optimizationOptions.Add(statBox)
+        self.optionsSizer.Add(statBox)
 
 
         # Rune sets
         # Rune sets
         names = [
         names = [
           "",        "ENERGY ", "GUARD  ", "SWIFT  ", "BLADE  ", "RAGE   ",
           "",        "ENERGY ", "GUARD  ", "SWIFT  ", "BLADE  ", "RAGE   ",
-          "FOCUS  ", "ENDURE ", "FATAL  ", "DESPAIR", "VAMPIRE", "VIOLENT",
-          "NEMESIS", "WILL   ", "SHIELD ", "REVENGE", "DESTROY", "FIGHT  ",
-          "DETERMI", "ENHANCE", "ACCURAC", "TOLERAN"
+          "FOCUS  ", "ENDURE ", "FATAL  ", "DESPAIR", "VAMPIRE",
+          "VIOLENT", "NEMESIS", "WILL   ", "SHIELD ", "REVENGE", "DESTROY",
+          "FIGHT  ", "DETERMI", "ENHANCE", "ACCURAC", "TOLERAN"
         ]
         ]
         setBox = wx.StaticBox(
         setBox = wx.StaticBox(
           self, label="Rune Sets:", id=wx.ID_ANY,
           self, label="Rune Sets:", id=wx.ID_ANY,
           pos=(170, 300), size=(115, 120)
           pos=(170, 300), size=(115, 120)
         )
         )
-        self.runeSets = [
+        self.setChoiceList = [
             wx.Choice(
             wx.Choice(
               parent=setBox, id=wx.ID_ANY, pos=(5, 0),
               parent=setBox, id=wx.ID_ANY, pos=(5, 0),
               size=(100, 30), choices=names
               size=(100, 30), choices=names
@@ -422,18 +439,18 @@ class PanelOptimizer(wx.Panel):
               size=(100, 30), choices=names
               size=(100, 30), choices=names
             )
             )
         ]
         ]
-        self.optimizationOptions.Add(setBox)
+        self.optionsSizer.Add(setBox)
 
 
         # Rune level selector
         # Rune level selector
         levelBox = wx.StaticBox(
         levelBox = wx.StaticBox(
           self, label="Rune Level:", id=wx.ID_ANY,
           self, label="Rune Level:", id=wx.ID_ANY,
           pos=(170, 420), size=(115, 70)
           pos=(170, 420), size=(115, 70)
         )
         )
-        self.level = wx.Choice(
+        self.levelChoice = wx.Choice(
           parent=levelBox, id=wx.ID_ANY, pos=(5, 0),
           parent=levelBox, id=wx.ID_ANY, pos=(5, 0),
           choices=["Current", "+ 12", " + 15"]
           choices=["Current", "+ 12", " + 15"]
         )
         )
-        self.optimizationOptions.Add(levelBox)
+        self.optionsSizer.Add(levelBox)
 
 
         # Team list
         # Team list
         teams = []
         teams = []
@@ -452,33 +469,73 @@ class PanelOptimizer(wx.Panel):
         )
         )
 
 
         # Inventory only option
         # Inventory only option
-        self.optimizationOptions.Add(teamsBox)
-        self.inventory = wx.CheckBox(
+        self.optionsSizer.Add(teamsBox)
+        self.inventoryCheck = wx.CheckBox(
           parent=self, id=wx.ID_ANY, label="Only runes in storage",
           parent=self, id=wx.ID_ANY, label="Only runes in storage",
           pos=(560, 310), size=(180, 20)
           pos=(560, 310), size=(180, 20)
         )
         )
-        self.optimizationOptions.Add(self.inventory)
-        self.teams = wx.CheckListBox(
+        self.optionsSizer.Add(self.inventoryCheck)
+        self.teamCheckList = wx.CheckListBox(
+          parent=teamsBox, id=wx.ID_ANY,
+          pos=(5, 5), size=(250, 130), choices=teams
+        )
+        btAllTeams = wx.Button(
+          parent=teamsBox, id=wx.ID_ANY,
+          pos=(5, 135), size=(120, 20), label="Select all"
+        )
+        btNoTeams = wx.Button(
           parent=teamsBox, id=wx.ID_ANY,
           parent=teamsBox, id=wx.ID_ANY,
-          pos=(5, 5), size=(250, 160), choices=teams
+          pos=(130, 135), size=(120, 20), label="Deselect all"
         )
         )
+        self.Bind(wx.EVT_BUTTON, self.selectAllTeams, btAllTeams)
+        self.Bind(wx.EVT_BUTTON, self.deselectAllTeams, btNoTeams)
 
 
         # Button to start
         # Button to start
         btOptimize = wx.Button(
         btOptimize = wx.Button(
           parent=self, id=wx.ID_ANY, pos=(600, 500),
           parent=self, id=wx.ID_ANY, pos=(600, 500),
           size=(100, 40), style=wx.LC_REPORT, label="OPTIMIZE"
           size=(100, 40), style=wx.LC_REPORT, label="OPTIMIZE"
         )
         )
-        self.optimizationOptions.Add(btOptimize)
+        self.optionsSizer.Add(btOptimize)
         self.Bind(wx.EVT_BUTTON, self.startOptimization, btOptimize)
         self.Bind(wx.EVT_BUTTON, self.startOptimization, btOptimize)
 
 
+        # Progress bar
+        self.progressGauge = wx.Gauge(
+          parent=self, id=wx.ID_ANY, range=20,
+          pos=(50, 485), size=(500, 40), style=wx.GA_HORIZONTAL
+        )
+
         # By default, hide all optimization options
         # By default, hide all optimization options
-        self.optimizationOptions.ShowItems(False)
+        self.optionsSizer.ShowItems(False)
+
+    def selectAllTeams(self, event = None):
+        """Selects all teams in the list.
+
+        Parameters
+        ----------
+        event : wxEvent, optional
+            The event that triggered the call (default is None).
+
+        """
+        for i in range(0, len(self.teamIds)):
+            self.teamCheckList.Check(i, True)
+
+    def deselectAllTeams(self, event = None):
+        """Deselects all teams in the list.
+
+        Parameters
+        ----------
+        event : wxEvent, optional
+            The event that triggered the call (default is None).
+
+        """
+        for i in range(0, len(self.teamIds)):
+            self.teamCheckList.Check(i, False)
 
 
     def selectUnit(self, event = None):
     def selectUnit(self, event = None):
         """Loads a unit info and enables optimizaton options.
         """Loads a unit info and enables optimizaton options.
 
 
-        Called when a unit is selected in unitSelector. If called from an
-        an event, the unit selected in unitSelector gets priority. When
+        Called when a unit is selected in unitChoice. If called from an
+        an event, the unit selected in unitChoice gets priority. When
         manually called, it uses unitId, so it must be set beforehand.
         manually called, it uses unitId, so it must be set beforehand.
 
 
         Parameters
         Parameters
@@ -488,10 +545,21 @@ class PanelOptimizer(wx.Panel):
 
 
         """
         """
 
 
+        # If its called from an event, it means a unit has been selected in this
+        # panel selector.
         if event != None:
         if event != None:
             self.unitId = \
             self.unitId = \
-              self.unidIdSelectorIndex[self.unitSelector.GetSelection()]
-            # TODO: Else mark selected in selector
+              self.unidIdSelectorIndex[self.unitChoice.GetSelection()]
+
+        # It it was not called from an event, it uses self.unitId and sets the
+        # selected unit in the unit selector automatically.
+        else:
+            for i in range(0, len(self.unidIdSelectorIndex)):
+                if self.unidIdSelectorIndex[i] == self.unitId:
+                    self.unitChoice.SetSelection(i)
+                    break
+
+        # Get the unit details
         cursor = conn.execute("""
         cursor = conn.execute("""
           SELECT
           SELECT
             base_hp,
             base_hp,
@@ -518,20 +586,20 @@ class PanelOptimizer(wx.Panel):
         """)
         """)
         row = cursor.fetchone()
         row = cursor.fetchone()
         # First, set sliders max values
         # First, set sliders max values
-        self.minStatSlid[0].SetMax(50000)  #HP
-        self.minStatSlid[1].SetMax(5000)   #ATK
-        self.minStatSlid[2].SetMax(5000)   #DEF
-        self.minStatSlid[3].SetMax(500)    #SPD
-        self.minStatSlid[4].SetMax(100)    #CRR
-        self.minStatSlid[5].SetMax(500)    #CRD
-        self.minStatSlid[6].SetMax(100)    #RES
-        self.minStatSlid[7].SetMax(85)     #ACC
-        self.minStatSlid[8].SetMax(250000) #EHP
-        self.minStatSlid[9].SetMax(8000)   #DMG
-        self.unitInfo.SetLabel(row[17] + " #" + row[16])
+        self.minStatSlidList[0].SetMax(50000)  #HP
+        self.minStatSlidList[1].SetMax(5000)   #ATK
+        self.minStatSlidList[2].SetMax(5000)   #DEF
+        self.minStatSlidList[3].SetMax(500)    #SPD
+        self.minStatSlidList[4].SetMax(100)    #CRR
+        self.minStatSlidList[5].SetMax(500)    #CRD
+        self.minStatSlidList[6].SetMax(100)    #RES
+        self.minStatSlidList[7].SetMax(85)     #ACC
+        self.minStatSlidList[8].SetMax(250000) #EHP
+        self.minStatSlidList[9].SetMax(8000)   #DMG
+        self.unitInfoBox.SetLabel(row[17] + " #" + row[16])
         for i in range(0, 8):
         for i in range(0, 8):
             value = str(row[i])
             value = str(row[i])
-            self.minStatSlid[i].SetMin(int(value))
+            self.minStatSlidList[i].SetMin(int(value))
             if i > 3:
             if i > 3:
                 value = value + "%"
                 value = value + "%"
             else:
             else:
@@ -539,8 +607,8 @@ class PanelOptimizer(wx.Panel):
             self.statGrid.SetCellValue(row=i, col=0, s=value)
             self.statGrid.SetCellValue(row=i, col=0, s=value)
         for i in range(0, 8):
         for i in range(0, 8):
             value = str(row[8 + i])
             value = str(row[8 + i])
-            self.minStatSlid[i].SetValue(int(value))
-            self.minStatText[i].SetValue(value)
+            self.minStatSlidList[i].SetValue(int(value))
+            self.minStatTextList[i].SetValue(value)
             self.unitStats[i] = int(value)
             self.unitStats[i] = int(value)
             if i > 3:
             if i > 3:
                 value = value + "%"
                 value = value + "%"
@@ -552,14 +620,14 @@ class PanelOptimizer(wx.Panel):
         baseDef = int(self.statGrid.GetCellValue(row=2, col=0).replace("%", ""))
         baseDef = int(self.statGrid.GetCellValue(row=2, col=0).replace("%", ""))
         baseEhp = math.ceil((((baseDef * 3.5) + 1140) * baseHp) / 1000)
         baseEhp = math.ceil((((baseDef * 3.5) + 1140) * baseHp) / 1000)
         self.statGrid.SetCellValue(row=8, col=0, s=str(baseEhp))
         self.statGrid.SetCellValue(row=8, col=0, s=str(baseEhp))
-        self.minStatSlid[8].SetMin(baseEhp)
+        self.minStatSlidList[8].SetMin(baseEhp)
         currentHp = int(self.statGrid.GetCellValue(row=0, col=1))
         currentHp = int(self.statGrid.GetCellValue(row=0, col=1))
         currentDef = \
         currentDef = \
           int(self.statGrid.GetCellValue(row=2, col=1).replace("%", ""))
           int(self.statGrid.GetCellValue(row=2, col=1).replace("%", ""))
         currentEhp = math.ceil((((currentDef * 3.5) + 1140) * currentHp) / 1000)
         currentEhp = math.ceil((((currentDef * 3.5) + 1140) * currentHp) / 1000)
         self.statGrid.SetCellValue(row=8, col=1, s=str(currentEhp))
         self.statGrid.SetCellValue(row=8, col=1, s=str(currentEhp))
-        self.minStatSlid[8].SetValue(currentEhp)
-        self.minStatText[8].SetValue(str(currentEhp))
+        self.minStatSlidList[8].SetValue(currentEhp)
+        self.minStatTextList[8].SetValue(str(currentEhp))
         baseAtk = int(self.statGrid.GetCellValue(row=1, col=0))
         baseAtk = int(self.statGrid.GetCellValue(row=1, col=0))
         baseCrr = int(self.statGrid.GetCellValue(row=4, col=0).replace("%", ""))
         baseCrr = int(self.statGrid.GetCellValue(row=4, col=0).replace("%", ""))
         baseCrd = int(self.statGrid.GetCellValue(row=5, col=0).replace("%", ""))
         baseCrd = int(self.statGrid.GetCellValue(row=5, col=0).replace("%", ""))
@@ -571,7 +639,7 @@ class PanelOptimizer(wx.Panel):
           ((baseAtk + (baseAtk * baseCrd / 100)) * baseCrr / 100)
           ((baseAtk + (baseAtk * baseCrd / 100)) * baseCrr / 100)
         )
         )
         self.statGrid.SetCellValue(row=9, col=0, s=str(baseDmg))
         self.statGrid.SetCellValue(row=9, col=0, s=str(baseDmg))
-        self.minStatSlid[9].SetMin(baseDmg)
+        self.minStatSlidList[9].SetMin(baseDmg)
         currentAtk = int(self.statGrid.GetCellValue(row=1, col=1))
         currentAtk = int(self.statGrid.GetCellValue(row=1, col=1))
         currentCrr = \
         currentCrr = \
           int(self.statGrid.GetCellValue(row=4, col=0).replace("%", ""))
           int(self.statGrid.GetCellValue(row=4, col=0).replace("%", ""))
@@ -585,12 +653,12 @@ class PanelOptimizer(wx.Panel):
           ((currentAtk + (currentAtk * currentCrd / 100)) * currentCrr / 100)
           ((currentAtk + (currentAtk * currentCrd / 100)) * currentCrr / 100)
         )
         )
         self.statGrid.SetCellValue(row=9, col=1, s=str(currentDmg))
         self.statGrid.SetCellValue(row=9, col=1, s=str(currentDmg))
-        self.minStatSlid[9].SetValue(currentDmg)
-        self.minStatText[9].SetValue(str(currentDmg))
+        self.minStatSlidList[9].SetValue(currentDmg)
+        self.minStatTextList[9].SetValue(str(currentDmg))
 
 
         # Populate the runes
         # Populate the runes
         for i in range(0, 6):
         for i in range(0, 6):
-            self.runeList[i].SetLabel("")
+            self.runeLabelList[i].SetLabel("")
         cursor = conn.execute("""
         cursor = conn.execute("""
           SELECT
           SELECT
             id, slot, type
             id, slot, type
@@ -633,35 +701,35 @@ class PanelOptimizer(wx.Panel):
                   stat_names[rowStats[1]] + str(rowStats[2]).rjust(4) + ""
                   stat_names[rowStats[1]] + str(rowStats[2]).rjust(4) + ""
                 if rowStats[3] > 0:
                 if rowStats[3] > 0:
                     label = label + " +" + str(rowStats[3])
                     label = label + " +" + str(rowStats[3])
-            self.runeList[i].SetLabel(label)
+            self.runeLabelList[i].SetLabel(label)
             i = i + 1
             i = i + 1
 
 
         # Try to infer data to set the default options, reset the rest
         # Try to infer data to set the default options, reset the rest
         # Except the team list, rune level and storage: never reset those.
         # Except the team list, rune level and storage: never reset those.
-        self.stats[0].SetCheckedItems(())
+        self.statCheckListList[0].SetCheckedItems(())
         for i in range(0, 3):
         for i in range(0, 3):
             if currEvenStats[i] == 1: # HP
             if currEvenStats[i] == 1: # HP
-                self.stats[0].Check(0, True)
+                self.statCheckListList[0].Check(0, True)
             elif currEvenStats[i] == 2: # HP%
             elif currEvenStats[i] == 2: # HP%
-                self.stats[0].Check(1, True)
+                self.statCheckListList[0].Check(1, True)
             elif currEvenStats[i] == 3: # ATK
             elif currEvenStats[i] == 3: # ATK
-                self.stats[0].Check(2, True)
+                self.statCheckListList[0].Check(2, True)
             elif currEvenStats[i] == 4: # ATK%
             elif currEvenStats[i] == 4: # ATK%
-                self.stats[0].Check(3, True)
+                self.statCheckListList[0].Check(3, True)
             elif currEvenStats[i] == 5: # DEF
             elif currEvenStats[i] == 5: # DEF
-                self.stats[0].Check(4, True)
+                self.statCheckListList[0].Check(4, True)
             elif currEvenStats[i] == 6: # DEF%
             elif currEvenStats[i] == 6: # DEF%
-                self.stats[0].Check(5, True)
+                self.statCheckListList[0].Check(5, True)
             elif currEvenStats[i] == 8: # SPD
             elif currEvenStats[i] == 8: # SPD
-                self.stats[1].Check(0, True)
+                self.statCheckListList[1].Check(0, True)
             elif currEvenStats[i] == 9: # CRR
             elif currEvenStats[i] == 9: # CRR
-                self.stats[1].Check(1, True)
+                self.statCheckListList[1].Check(1, True)
             elif currEvenStats[i] == 10: # CRD
             elif currEvenStats[i] == 10: # CRD
-                self.stats[1].Check(2, True)
+                self.statCheckListList[1].Check(2, True)
             elif currEvenStats[i] == 11: # RES
             elif currEvenStats[i] == 11: # RES
-                self.stats[1].Check(3, True)
+                self.statCheckListList[1].Check(3, True)
             elif currEvenStats[i] == 12: # ACC
             elif currEvenStats[i] == 12: # ACC
-                self.stats[1].Check(4, True)
+                self.statCheckListList[1].Check(4, True)
         currSetList = [-1, -1, -1]
         currSetList = [-1, -1, -1]
         j = 0
         j = 0
         for i in range(0, 23):
         for i in range(0, 23):
@@ -679,16 +747,23 @@ class PanelOptimizer(wx.Panel):
                         currSetList[j] = i - 1
                         currSetList[j] = i - 1
                         j += 1
                         j += 1
                 # If a set of 4 has 4
                 # If a set of 4 has 4
-                else:
+                elif i in [3, 5, 8, 10, 11, 13]:
                     if currSets[i] >= 4:
                     if currSets[i] >= 4:
                         currSetList[j] = i - 1
                         currSetList[j] = i - 1
                         j += 1
                         j += 1
+        # Rune set IDs 9 and 12 dont exist, so do a little trick with indexes.
         for i in range(0, 3):
         for i in range(0, 3):
-            if currSetList[i] != -1:
-                self.runeSets[i].SetSelection(currSetList[i])
+            #if currSetList[i] != 0:
+            actualId = currSetList[i] + 1
+            if (actualId > 8):
+                actualId -= 1
+            if (actualId > 11):
+                actualId -= 1
+            self.setChoiceList[i].SetSelection(actualId)
 
 
 
 
-        self.optimizationOptions.ShowItems(True)
+
+        self.optionsSizer.ShowItems(True)
 
 
     def startOptimization(self, event):
     def startOptimization(self, event):
         """Prepares and runs a command optimization.
         """Prepares and runs a command optimization.
@@ -708,7 +783,7 @@ class PanelOptimizer(wx.Panel):
         command = "RuneOptimizer optimize "
         command = "RuneOptimizer optimize "
         unitId = self.unitId
         unitId = self.unitId
         command += unitId
         command += unitId
-        level = self.level.GetSelection()
+        level = self.levelChoice.GetSelection()
         if level == 1:
         if level == 1:
             level = "12"
             level = "12"
         elif level == 2:
         elif level == 2:
@@ -719,8 +794,8 @@ class PanelOptimizer(wx.Panel):
         #print("    Rune level: " + level)
         #print("    Rune level: " + level)
         sets = ""
         sets = ""
         for i in range (0, 2):
         for i in range (0, 2):
-            selected = self.runeSets[i].GetString(
-              self.runeSets[i].GetSelection()
+            selected = self.setChoiceList[i].GetString(
+              self.setChoiceList[i].GetSelection()
             ).upper().replace(" ", "");
             ).upper().replace(" ", "");
             for j in range(0, 22):
             for j in range(0, 22):
                 name = set_names[j].upper()
                 name = set_names[j].upper()
@@ -734,8 +809,9 @@ class PanelOptimizer(wx.Panel):
         command += (" --sets " + sets)
         command += (" --sets " + sets)
         stats = ""
         stats = ""
         selected_stats = \
         selected_stats = \
-          self.stats[0].GetCheckedItems() + self.stats[1].GetCheckedItems()
-        for s in self.stats[0].GetCheckedItems():
+          self.statCheckListList[0].GetCheckedItems() + \
+          self.statCheckListList[1].GetCheckedItems()
+        for s in self.statCheckListList[0].GetCheckedItems():
             if s == 0:
             if s == 0:
                 stats += "hpflat,"
                 stats += "hpflat,"
             elif s == 1:
             elif s == 1:
@@ -748,7 +824,7 @@ class PanelOptimizer(wx.Panel):
                 stats += "defflat,"
                 stats += "defflat,"
             elif s == 5:
             elif s == 5:
                 stats += "def,"
                 stats += "def,"
-        for s in self.stats[1].GetCheckedItems():
+        for s in self.statCheckListList[1].GetCheckedItems():
             if s == 0:
             if s == 0:
                 stats += "spd,"
                 stats += "spd,"
             elif s == 1:
             elif s == 1:
@@ -765,35 +841,106 @@ class PanelOptimizer(wx.Panel):
         command += (" --stats " + stats)
         command += (" --stats " + stats)
         #print("    Main stats: " + stats)
         #print("    Main stats: " + stats)
 
 
-        command += (" --min-hp " + str(self.minStatSlid[0].GetValue()))
-        command += (" --min-atk " + str(self.minStatSlid[1].GetValue()))
-        command += (" --min-def " + str(self.minStatSlid[2].GetValue()))
-        command += (" --min-spd " + str(self.minStatSlid[3].GetValue()))
-        command += (" --min-crr " + str(self.minStatSlid[4].GetValue()))
-        command += (" --min-crd " + str(self.minStatSlid[5].GetValue()))
-        command += (" --min-res " + str(self.minStatSlid[6].GetValue()))
-        command += (" --min-acc " + str(self.minStatSlid[7].GetValue()))
-        command += (" --min-ehp " + str(self.minStatSlid[8].GetValue()))
-        command += (" --min-dmg " + str(self.minStatSlid[9].GetValue()))
-
-        if self.inventory.GetValue():
+        command += (" --min-hp " + str(self.minStatSlidList[0].GetValue()))
+        command += (" --min-atk " + str(self.minStatSlidList[1].GetValue()))
+        command += (" --min-def " + str(self.minStatSlidList[2].GetValue()))
+        command += (" --min-spd " + str(self.minStatSlidList[3].GetValue()))
+        command += (" --min-crr " + str(self.minStatSlidList[4].GetValue()))
+        command += (" --min-crd " + str(self.minStatSlidList[5].GetValue()))
+        command += (" --min-res " + str(self.minStatSlidList[6].GetValue()))
+        command += (" --min-acc " + str(self.minStatSlidList[7].GetValue()))
+        command += (" --min-ehp " + str(self.minStatSlidList[8].GetValue()))
+        command += (" --min-dmg " + str(self.minStatSlidList[9].GetValue()))
+
+        if self.inventoryCheck.GetValue():
             command += " --storage"
             command += " --storage"
-        if len(self.teams.GetCheckedItems()) > 0:
+        if len(self.teamCheckList.GetCheckedItems()) > 0:
             command += " --no-teams "
             command += " --no-teams "
-            for team in self.teams.GetCheckedItems():
+            for team in self.teamCheckList.GetCheckedItems():
                 command += str(self.teamIds[team]) + ","
                 command += str(self.teamIds[team]) + ","
             command = command[:-1]
             command = command[:-1]
 
 
 
 
         command += (" --gui ")
         command += (" --gui ")
-        command = os.path.dirname(os.path.realpath(__file__)) + "/../../" + command
+        command = \
+          os.path.dirname(os.path.realpath(__file__)) + "/../../" + command
         print("Command: " + command)
         print("Command: " + command)
 
 
-        out = subprocess.check_output(command.split())
-        json = bytes.decode(out)
+        self.progressGauge.SetValue(0)
+
+        # Timer ot periodically check on the process
+        self.timer = wx.Timer(self)
+        self.timer.Start(1000)
+        self.Bind(wx.EVT_TIMER, self.checkProcess)
+
+        # Create and execute the process
+        self.Bind(wx.EVT_END_PROCESS, self.optimizationComplete)
+        #print("Command: " + command)
+        self.process = wx.Process(self)
+        self.process.Redirect()
+        wx.Execute(command, wx.EXEC_ASYNC, self.process)
+
+    def checkProcess(self, event):
+        """Checks the process output and updates progress bar.
+
+        Parameters
+        ----------
+        event : wxEvent, optional
+            The event that triggered the call.
+
+        """
+        if self.process is not None:
+            stream = self.process.GetInputStream()
+            if stream.CanRead():
+                text = bytes.decode(stream.read())
+                text = text[:-1] # Remove the last newline
+
+                # Get only the last line
+                if text.rfind("\n") != -1:
+                    text = text[text.rfind("\n") + 1:]
+
+                # If the line is just a number, it's a progress indicator (1-20)
+                if text.isnumeric() and int(text) <= 20:
+                    self.progressGauge.SetValue(int(text))
+        else:
+            self.timer.Stop()
+
+    def optimizationComplete(self, event):
+        """Called when the update process is complete.
+
+        Hiddes the progress image, checks for errors in the output, prints a
+        message annd sets self.updateDone and self.updateError.
+
+        Parameters
+        ----------
+        event : wxEvent, optional
+            The event that triggered the call.
+
+        """
+
+        self.timer.Stop()
+        self.progressGauge.SetValue(20)
+
+        stream = self.process.GetInputStream()
+        jsonText = ""
+
+        if stream.CanRead():
+            text = bytes.decode(stream.read())
+            text = text[:-1] # Remove the last newline
+
+            # Get only the last line
+            if text.rfind("\n") != -1:
+                text = text[text.rfind("\n") + 1:]
+
+            jsonText = text
+
+        print('Finished. Result:\n' + text)
+
+        """
+
         # DEBUG: Sample data.
         # DEBUG: Sample data.
         #self.unitId = "7223811472"
         #self.unitId = "7223811472"
-        #json = """{"result_count":5000,"results":[
+        #json = ""{"result_count":5000,"results":[
         #    {"id":0,"rating":215,"hp":20461,"atk":2521,"dfc":845,"spd":137,"crr":63,"crd":167,"res":29,"acc":15,"ehp":83839,"dmg":5174,"runes":["22677809846","22920616295","21755980400","25633344349","26207902579","28512560500"]},
         #    {"id":0,"rating":215,"hp":20461,"atk":2521,"dfc":845,"spd":137,"crr":63,"crd":167,"res":29,"acc":15,"ehp":83839,"dmg":5174,"runes":["22677809846","22920616295","21755980400","25633344349","26207902579","28512560500"]},
         #    {"id":1,"rating":195,"hp":18876,"atk":2521,"dfc":853,"spd":137,"crr":60,"crd":174,"res":37,"acc":8,"ehp":77873,"dmg":5153,"runes":["22677809846","22920616295","27654723287","25633344349","26207902579","28512560500"]},
         #    {"id":1,"rating":195,"hp":18876,"atk":2521,"dfc":853,"spd":137,"crr":60,"crd":174,"res":37,"acc":8,"ehp":77873,"dmg":5153,"runes":["22677809846","22920616295","27654723287","25633344349","26207902579","28512560500"]},
         #    {"id":2,"rating":185,"hp":17730,"atk":2521,"dfc":862,"spd":147,"crr":60,"crd":164,"res":28,"acc":15,"ehp":73704,"dmg":5002,"runes":["21564691276","22920616295","27654723287","25633344349","26207902579","22348038576"]},
         #    {"id":2,"rating":185,"hp":17730,"atk":2521,"dfc":862,"spd":147,"crr":60,"crd":164,"res":28,"acc":15,"ehp":73704,"dmg":5002,"runes":["21564691276","22920616295","27654723287","25633344349","26207902579","22348038576"]},
@@ -801,13 +948,32 @@ class PanelOptimizer(wx.Panel):
         #    {"id":4,"rating":176,"hp":15319,"atk":2530,"dfc":909,"spd":142,"crr":60,"crd":165,"res":28,"acc":15,"ehp":66202,"dmg":5035,"runes":["21564691276","16759622995","27654723287","22750814840","26207902579","22348038576"]}]}
         #    {"id":4,"rating":176,"hp":15319,"atk":2530,"dfc":909,"spd":142,"crr":60,"crd":165,"res":28,"acc":15,"ehp":66202,"dmg":5035,"runes":["21564691276","16759622995","27654723287","22750814840","26207902579","22348038576"]}]}
         #"""
         #"""
 
 
+        print ("---- RESULT OUTPUT -------------------------------------------")
+        print(jsonText)
+        print ("--------------------------------------------------------------")
 
 
-        print ("---- OUTPUT ------------------------------------------------------------------------------------------")
-        print(json)
-        print ("------------------------------------------------------------------------------------------------------")
-
-        self.GetParent().frameResults.processResults(self.unitId, json)
-
+        if jsonText != "":
+            data = json.loads(
+              jsonText,
+              object_hook=lambda d: SimpleNamespace(**d)
+            )
+            if data.result_count == 0:
+                wx.MessageBox(
+                  parent=self,
+                  message="No results found for the current settings.",
+                  caption="No results found"
+                )
+            else:
+                self.GetParent().frameResults.processResults(
+                  self.unitId, jsonText
+                )
+                self.GetParent().ChangeSelection(3)
+        else:
+            wx.MessageBox(
+                  parent=self,
+                  message="No data received from RuneOptimizer.",
+                  caption="Error"
+                )
 
 
     def minStatChangeBySlider(self, event):
     def minStatChangeBySlider(self, event):
         """Changes text when a slider is changed.
         """Changes text when a slider is changed.
@@ -822,7 +988,7 @@ class PanelOptimizer(wx.Panel):
         """
         """
 
 
         slidId = int(event.GetEventObject().GetName().replace("slid", ""))
         slidId = int(event.GetEventObject().GetName().replace("slid", ""))
-        self.minStatText[slidId].SetValue(
+        self.minStatTextList[slidId].SetValue(
           str(event.GetEventObject().GetValue())
           str(event.GetEventObject().GetValue())
         )
         )
 
 
@@ -840,15 +1006,15 @@ class PanelOptimizer(wx.Panel):
         textId = int(event.GetEventObject().GetName().replace("tx", ""))
         textId = int(event.GetEventObject().GetName().replace("tx", ""))
         if event.GetEventObject().GetValue().isdigit() == False:
         if event.GetEventObject().GetValue().isdigit() == False:
             event.GetEventObject().SetValue(
             event.GetEventObject().SetValue(
-              str(self.minStatSlid[textId].GetValue())
+              str(self.minStatSlidList[textId].GetValue())
             )
             )
         value = int(event.GetEventObject().GetValue())
         value = int(event.GetEventObject().GetValue())
-        minValue = self.minStatSlid[textId].GetMin()
-        maxValue = self.minStatSlid[textId].GetMax()
+        minValue = self.minStatSlidList[textId].GetMin()
+        maxValue = self.minStatSlidList[textId].GetMax()
         if value < minValue:
         if value < minValue:
             value = minValue
             value = minValue
             event.GetEventObject().SetValue(str(value))
             event.GetEventObject().SetValue(str(value))
         elif value > maxValue:
         elif value > maxValue:
             value = maxValue
             value = maxValue
             event.GetEventObject().SetValue(str(value))
             event.GetEventObject().SetValue(str(value))
-        self.minStatSlid[textId].SetValue(value)
+        self.minStatSlidList[textId].SetValue(value)

+ 151 - 148
src/RuneOptimizerGUI/classes/PanelResults.py

@@ -22,12 +22,10 @@ class PanelResults(wx.Panel):
 
 
     Parameters
     Parameters
     ----------
     ----------
-    unitId : str
+    unitId : string
         ID of the unit being optimized (default "").
         ID of the unit being optimized (default "").
-    unitName : str
+    unitName : string
         Name of the unit being optimized (default "").
         Name of the unit being optimized (default "").
-    unitNameLabel : wx.StaticText
-        Labels for the unit name.
     data : Python Object
     data : Python Object
         Results from RuneOptimizer (default None).
         Results from RuneOptimizer (default None).
     unitStats : int[10]
     unitStats : int[10]
@@ -39,32 +37,36 @@ class PanelResults(wx.Panel):
         Number of pages of results (default 0).
         Number of pages of results (default 0).
     linesPerPage : int
     linesPerPage : int
         Number of results to show per page (default 10).
         Number of results to show per page (default 10).
-    pgPrevBt : wx.Button
-        Button to go to the previous page.
-    pgPrevBt : wx.Button
-        Button to go to the previous page.
-    resultsPageIndicator : wx.StaticText
-        Label to indicate the current and maximum pages.
+    selectedResultndex : int
+        Selected result index (default -1).
+    unitNameLabel : wx.StaticText
+        Labels for the unit name.
+    tableSizer : wx.BoxSizer
+        Holds the result list. Hidden until processResults is called.
+    detailsSizer : wx.BoxSizer
+        Holds every widget that is hidden until a result is selected.
     resultGrid : wx.Grid.grid
     resultGrid : wx.Grid.grid
         Table of results.
         Table of results.
-    resultContent : wx.BoxSizer
-        Holds every widget that is hidden until a result is selected.
+    pgPrevButton : wx.Button
+        Button to go to the previous page.
+    pageLabel : wx.StaticText
+        Label to indicate the current and maximum pages.
+    pgPrevButton : wx.Button
+        Button to go to the previous page.
     statGrid : wx.Grid.grid
     statGrid : wx.Grid.grid
         Table to show the new stats with the selected result.
         Table to show the new stats with the selected result.
-    runeIds : wx.StaticText[6]
+    idLabelList : wx.StaticText[6]
         Labels with the IDs of the runes in the current result.
         Labels with the IDs of the runes in the current result.
-    runeLocations : wx.StaticText[6]
+    locationLabelList : wx.StaticText[6]
         Labels with the locations of the runes in the current result.
         Labels with the locations of the runes in the current result.
-    runeSets : wx.StaticText[6]
+    setLabelList : wx.StaticText[6]
         Labels with the set names of the runes in the current result.
         Labels with the set names of the runes in the current result.
-    runeMains : wx.StaticText[6]
+    mainLabelList : wx.StaticText[6]
         Labels with the main stats of the runes in the current result.
         Labels with the main stats of the runes in the current result.
-    runeInnates : wx.StaticText[6]
+    innateLabelList : wx.StaticText[6]
         Labels with the innates of the runes in the current result.
         Labels with the innates of the runes in the current result.
-    runeStats : wx.StaticText[6][4]
+    statLabelList : wx.StaticText[6][4]
         Labels with the stats of the runes in the current result.
         Labels with the stats of the runes in the current result.
-    selectedResultndex : int
-        Selected result index (default -1).
 
 
     Methods
     Methods
     -------
     -------
@@ -74,8 +76,6 @@ class PanelResults(wx.Panel):
         Goes to the previous result page.
         Goes to the previous result page.
     pgNext(event)
     pgNext(event)
         Goes to the next result page.
         Goes to the next result page.
-    closeWindow(event)
-        Closes the frame.
     applyRunes(event)
     applyRunes(event)
         Applies the runes in the currently selected result.
         Applies the runes in the currently selected result.
     printResults()
     printResults()
@@ -89,25 +89,26 @@ class PanelResults(wx.Panel):
 
 
     unitId = ""
     unitId = ""
     unitName = ""
     unitName = ""
-    unitNameLabel = None
     data = None
     data = None
     unitStats = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
     unitStats = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
     page = 0
     page = 0
     totalPages = 0
     totalPages = 0
     linesPerPage = 10
     linesPerPage = 10
-    pgPrevBt = None
-    pgNextBt = None
-    resultsPageIndicator = None
+    selectedResultIndex = -1
+    unitNameLabel = None
+    tableSizer = None
+    detailsSizer = None
     resultGrid = None
     resultGrid = None
-    resultContent = None
+    pgPrevButton = None
+    pageLabel = None
+    pgNextButton = None
     statGrid = None
     statGrid = None
-    runeIds = None
-    runeLocations = None
-    runeSets = None
-    runeMains = None
-    runeInnates = None
-    runeStats = None
-    selectedResultIndex = -1
+    idLabelList = None
+    locationLabelList = None
+    setLabelList = None
+    mainLabelList = None
+    innateLabelList = None
+    statLabelList = None
 
 
     def __init__(self, parent, id=wx.ID_ANY):
     def __init__(self, parent, id=wx.ID_ANY):
         """Initializes the panel.
         """Initializes the panel.
@@ -120,6 +121,10 @@ class PanelResults(wx.Panel):
         wx.Panel.__init__(self, parent=parent, id=id)
         wx.Panel.__init__(self, parent=parent, id=id)
 
 
         # Prepare some fonts
         # Prepare some fonts
+        titleFont = wx.Font(
+          pointSize=14, family=wx.FONTFAMILY_DEFAULT,
+          style=wx.FONTSTYLE_NORMAL, weight=wx.FONTWEIGHT_BOLD
+        )
         monospaceFont = wx.Font(
         monospaceFont = wx.Font(
           pointSize=10, family=wx.FONTFAMILY_TELETYPE,
           pointSize=10, family=wx.FONTFAMILY_TELETYPE,
           style=wx.FONTSTYLE_NORMAL, weight=wx.FONTWEIGHT_NORMAL
           style=wx.FONTSTYLE_NORMAL, weight=wx.FONTWEIGHT_NORMAL
@@ -138,11 +143,12 @@ class PanelResults(wx.Panel):
             parent=self, id=wx.ID_ANY, label="Nothing yet. Optimize something!",
             parent=self, id=wx.ID_ANY, label="Nothing yet. Optimize something!",
             pos=(0, 0), size=(400, 30)
             pos=(0, 0), size=(400, 30)
         )
         )
+        self.unitNameLabel.SetFont(titleFont)
 
 
         # Contains the results table. Hidden until they are loaded.
         # Contains the results table. Hidden until they are loaded.
-        self.resultContainer = wx.BoxSizer(wx.VERTICAL)
+        self.tableSizer = wx.BoxSizer(wx.VERTICAL)
         # Contains all thigs to be shown once a result is selected
         # Contains all thigs to be shown once a result is selected
-        self.resultContent = wx.BoxSizer(wx.VERTICAL)
+        self.detailsSizer = wx.BoxSizer(wx.VERTICAL)
 
 
         # The result list table
         # The result list table
         self.resultGrid = wx.grid.Grid(
         self.resultGrid = wx.grid.Grid(
@@ -187,26 +193,26 @@ class PanelResults(wx.Panel):
         self.Bind(
         self.Bind(
           wx.grid.EVT_GRID_SELECT_CELL, self.resultSelected, self.resultGrid
           wx.grid.EVT_GRID_SELECT_CELL, self.resultSelected, self.resultGrid
         )
         )
-        self.resultContainer.Add(self.resultGrid)
+        self.tableSizer.Add(self.resultGrid)
 
 
         # Paginator
         # Paginator
-        self.pgPrevBt = wx.Button(
+        self.pgPrevButton = wx.Button(
           parent=self, id=wx.ID_ANY, pos=(530, 30), size=(40, 50),
           parent=self, id=wx.ID_ANY, pos=(530, 30), size=(40, 50),
           style=wx.LC_REPORT, label="Prev\npage"
           style=wx.LC_REPORT, label="Prev\npage"
         )
         )
-        self.resultContainer.Add(self.pgPrevBt)
-        self.resultsPageIndicator = wx.StaticText(
+        self.tableSizer.Add(self.pgPrevButton)
+        self.pageLabel = wx.StaticText(
           parent=self,id=wx.ID_ANY, pos=(530, 80), size=(40, 15),
           parent=self,id=wx.ID_ANY, pos=(530, 80), size=(40, 15),
           style=wx.ALIGN_CENTRE_HORIZONTAL, label="1/1"
           style=wx.ALIGN_CENTRE_HORIZONTAL, label="1/1"
         )
         )
-        self.resultContainer.Add(self.resultsPageIndicator)
-        self.pgNextBt = wx.Button(
+        self.tableSizer.Add(self.pageLabel)
+        self.pgNextButton = wx.Button(
           parent=self, id=wx.ID_ANY, pos=(530, 100), size=(40, 50),
           parent=self, id=wx.ID_ANY, pos=(530, 100), size=(40, 50),
           style=wx.LC_REPORT, label="Next\npage"
           style=wx.LC_REPORT, label="Next\npage"
         )
         )
-        self.resultContainer.Add(self.pgNextBt)
-        self.Bind(wx.EVT_BUTTON, self.pgPrev, self.pgPrevBt)
-        self.Bind(wx.EVT_BUTTON, self.pgNext, self.pgNextBt)
+        self.tableSizer.Add(self.pgNextButton)
+        self.Bind(wx.EVT_BUTTON, self.pgPrev, self.pgPrevButton)
+        self.Bind(wx.EVT_BUTTON, self.pgNext, self.pgNextButton)
 
 
         # Stats table
         # Stats table
         self.statGrid = wx.grid.Grid(
         self.statGrid = wx.grid.Grid(
@@ -247,11 +253,11 @@ class PanelResults(wx.Panel):
         self.statGrid.SetRowLabelValue(row=7, value="ACC")
         self.statGrid.SetRowLabelValue(row=7, value="ACC")
         self.statGrid.SetRowLabelValue(row=8, value="EHP")
         self.statGrid.SetRowLabelValue(row=8, value="EHP")
         self.statGrid.SetRowLabelValue(row=9, value="DMG")
         self.statGrid.SetRowLabelValue(row=9, value="DMG")
-        self.resultContent.Add(self.statGrid)
+        self.detailsSizer.Add(self.statGrid)
 
 
         #Rune set list
         #Rune set list
         monospaceFont.PointSize -= 2
         monospaceFont.PointSize -= 2
-        runeListBox = [
+        rubeBoxList = [
           wx.StaticBox(
           wx.StaticBox(
             parent=self, label="Slot1:",id=wx.ID_ANY,
             parent=self, label="Slot1:",id=wx.ID_ANY,
             pos=(350, 210), size=(140, 160)
             pos=(350, 210), size=(140, 160)
@@ -278,277 +284,277 @@ class PanelResults(wx.Panel):
           )
           )
         ]
         ]
         for i in range(0, 6):
         for i in range(0, 6):
-            runeListBox[i].SetFont(monospaceFont)
-            self.resultContent.Add(runeListBox[i])
+            rubeBoxList[i].SetFont(monospaceFont)
+            self.detailsSizer.Add(rubeBoxList[i])
 
 
-        self.runeIds = [
+        self.idLabelList = [
           wx.StaticText(
           wx.StaticText(
-            runeListBox[0], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
+            rubeBoxList[0], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[1], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
+            rubeBoxList[1], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[2], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
+            rubeBoxList[2], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[3], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
+            rubeBoxList[3], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[4], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
+            rubeBoxList[4], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[5], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
+            rubeBoxList[5], id=wx.ID_ANY, label="", pos=(5, 0), size=(120, 10)
           )
           )
         ]
         ]
 
 
-        self.runeLocations = [
+        self.locationLabelList = [
           wx.StaticText(
           wx.StaticText(
-            runeListBox[0], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
+            rubeBoxList[0], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[1], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
+            rubeBoxList[1], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[2], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
+            rubeBoxList[2], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[3], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
+            rubeBoxList[3], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[4], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
+            rubeBoxList[4], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[5], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
+            rubeBoxList[5], id=wx.ID_ANY, label="", pos=(5, 15), size=(120, 10)
           ),
           ),
         ]
         ]
 
 
-        self.runeSets = [
+        self.setLabelList = [
           wx.StaticText(
           wx.StaticText(
-            runeListBox[0], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
+            rubeBoxList[0], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[1], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
+            rubeBoxList[1], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[2], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
+            rubeBoxList[2], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[3], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
+            rubeBoxList[3], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[4], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
+            rubeBoxList[4], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            runeListBox[5], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
+            rubeBoxList[5], id=wx.ID_ANY, label="", pos=(5, 30), size=(120, 10)
           ),
           ),
         ]
         ]
 
 
         wx.StaticLine(
         wx.StaticLine(
-          parent=runeListBox[0], id=wx.ID_ANY,
+          parent=rubeBoxList[0], id=wx.ID_ANY,
           pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
           pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
         )
         )
         wx.StaticLine(
         wx.StaticLine(
-          parent=runeListBox[1], id=wx.ID_ANY,
+          parent=rubeBoxList[1], id=wx.ID_ANY,
           pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
           pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
         )
         )
         wx.StaticLine(
         wx.StaticLine(
-          parent=runeListBox[2], id=wx.ID_ANY,
+          parent=rubeBoxList[2], id=wx.ID_ANY,
           pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
           pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
         )
         )
         wx.StaticLine(
         wx.StaticLine(
-          parent=runeListBox[3], id=wx.ID_ANY,
+          parent=rubeBoxList[3], id=wx.ID_ANY,
           pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
           pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
         )
         )
         wx.StaticLine(
         wx.StaticLine(
-          parent=runeListBox[4], id=wx.ID_ANY,
+          parent=rubeBoxList[4], id=wx.ID_ANY,
           pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
           pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
         )
         )
         wx.StaticLine(
         wx.StaticLine(
-          parent=runeListBox[5], id=wx.ID_ANY,
+          parent=rubeBoxList[5], id=wx.ID_ANY,
           pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
           pos=(5, 45), size=(130, 1), style=wx.LC_REPORT
         )
         )
 
 
-        self.runeMains = [
+        self.mainLabelList = [
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[0], id=wx.ID_ANY, label="",
+            parent=rubeBoxList[0], id=wx.ID_ANY, label="",
             pos=(5, 50), size=(120, 10)
             pos=(5, 50), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[1], id=wx.ID_ANY, label="",
+            parent=rubeBoxList[1], id=wx.ID_ANY, label="",
             pos=(5, 50), size=(120, 10)
             pos=(5, 50), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[2], id=wx.ID_ANY, label="",
+            parent=rubeBoxList[2], id=wx.ID_ANY, label="",
             pos=(5, 50), size=(120, 10)
             pos=(5, 50), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[3], id=wx.ID_ANY, label="",
+            parent=rubeBoxList[3], id=wx.ID_ANY, label="",
             pos=(5, 50), size=(120, 10)
             pos=(5, 50), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[4], id=wx.ID_ANY, label="",
+            parent=rubeBoxList[4], id=wx.ID_ANY, label="",
             pos=(5, 50), size=(120, 10)
             pos=(5, 50), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[5], id=wx.ID_ANY, label="",
+            parent=rubeBoxList[5], id=wx.ID_ANY, label="",
             pos=(5, 50), size=(120, 10)
             pos=(5, 50), size=(120, 10)
           ),
           ),
         ]
         ]
         for i in range(0, 6):
         for i in range(0, 6):
-            self.runeMains[i].SetFont(monospaceFontBold)
+            self.mainLabelList[i].SetFont(monospaceFontBold)
 
 
-        self.runeInnates = [
+        self.innateLabelList = [
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[0], id=wx.ID_ANY, label="",
+            parent=rubeBoxList[0], id=wx.ID_ANY, label="",
             pos=(5, 65), size=(120, 10)
             pos=(5, 65), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[1], id=wx.ID_ANY, label="",
+            parent=rubeBoxList[1], id=wx.ID_ANY, label="",
             pos=(5, 65), size=(120, 10)
             pos=(5, 65), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[2], id=wx.ID_ANY, label="",
+            parent=rubeBoxList[2], id=wx.ID_ANY, label="",
             pos=(5, 65), size=(120, 10)
             pos=(5, 65), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[3], id=wx.ID_ANY, label="",
+            parent=rubeBoxList[3], id=wx.ID_ANY, label="",
             pos=(5, 65), size=(120, 10)
             pos=(5, 65), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[4], id=wx.ID_ANY, label="",
+            parent=rubeBoxList[4], id=wx.ID_ANY, label="",
             pos=(5, 65), size=(120, 10)
             pos=(5, 65), size=(120, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[5], id=wx.ID_ANY, label="",
+            parent=rubeBoxList[5], id=wx.ID_ANY, label="",
             pos=(5, 65), size=(120, 10)
             pos=(5, 65), size=(120, 10)
           )
           )
         ]
         ]
         for i in range(0, 6):
         for i in range(0, 6):
-            self.runeInnates[i].SetFont(monospaceFontItalic)
+            self.innateLabelList[i].SetFont(monospaceFontItalic)
 
 
-        self.runeStats = [
+        self.statLabelList = [
           [
           [
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[0], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[0], id=wx.ID_ANY, label="",
               pos=(5, 80), size=(120, 10)
               pos=(5, 80), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[0], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[0], id=wx.ID_ANY, label="",
               pos=(5, 95), size=(120, 10)
               pos=(5, 95), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[0], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[0], id=wx.ID_ANY, label="",
               pos=(5, 110), size=(120, 10)
               pos=(5, 110), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[0], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[0], id=wx.ID_ANY, label="",
               pos=(5, 125), size=(120, 10)
               pos=(5, 125), size=(120, 10)
             )
             )
           ],
           ],
           [
           [
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[1], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[1], id=wx.ID_ANY, label="",
               pos=(5, 80), size=(120, 10)
               pos=(5, 80), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[1], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[1], id=wx.ID_ANY, label="",
               pos=(5, 95), size=(120, 10)
               pos=(5, 95), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[1], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[1], id=wx.ID_ANY, label="",
               pos=(5, 110), size=(120, 10)
               pos=(5, 110), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[1], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[1], id=wx.ID_ANY, label="",
               pos=(5, 125), size=(120, 10)
               pos=(5, 125), size=(120, 10)
             )
             )
           ],
           ],
           [
           [
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[2], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[2], id=wx.ID_ANY, label="",
               pos=(5, 80), size=(120, 10)
               pos=(5, 80), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[2], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[2], id=wx.ID_ANY, label="",
               pos=(5, 95), size=(120, 10)
               pos=(5, 95), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[2], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[2], id=wx.ID_ANY, label="",
               pos=(5, 110), size=(120, 10)
               pos=(5, 110), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[2], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[2], id=wx.ID_ANY, label="",
               pos=(5, 125), size=(120, 10)
               pos=(5, 125), size=(120, 10)
             )
             )
           ],
           ],
           [
           [
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[3], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[3], id=wx.ID_ANY, label="",
               pos=(5, 80), size=(120, 10)
               pos=(5, 80), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[3], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[3], id=wx.ID_ANY, label="",
               pos=(5, 95), size=(120, 10)
               pos=(5, 95), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[3], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[3], id=wx.ID_ANY, label="",
               pos=(5, 110), size=(120, 10)
               pos=(5, 110), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[3], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[3], id=wx.ID_ANY, label="",
               pos=(5, 125), size=(120, 10)
               pos=(5, 125), size=(120, 10)
             )
             )
           ],
           ],
           [
           [
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[4], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[4], id=wx.ID_ANY, label="",
               pos=(5, 80), size=(120, 10)
               pos=(5, 80), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[4], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[4], id=wx.ID_ANY, label="",
               pos=(5, 95), size=(120, 10)
               pos=(5, 95), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[4], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[4], id=wx.ID_ANY, label="",
               pos=(5, 110), size=(120, 10)
               pos=(5, 110), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[4], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[4], id=wx.ID_ANY, label="",
               pos=(5, 125), size=(120, 10)
               pos=(5, 125), size=(120, 10)
             )
             )
           ],
           ],
           [
           [
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[5], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[5], id=wx.ID_ANY, label="",
               pos=(5, 80), size=(120, 10)
               pos=(5, 80), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[5], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[5], id=wx.ID_ANY, label="",
               pos=(5, 95), size=(120, 10)
               pos=(5, 95), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[5], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[5], id=wx.ID_ANY, label="",
               pos=(5, 110), size=(120, 10)
               pos=(5, 110), size=(120, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[5], id=wx.ID_ANY, label="",
+              parent=rubeBoxList[5], id=wx.ID_ANY, label="",
               pos=(5, 125), size=(120, 10)
               pos=(5, 125), size=(120, 10)
             )
             )
           ],
           ],
         ]
         ]
 
 
         # Action buttons
         # Action buttons
-        applyBt = wx.Button(
+        applyButton = wx.Button(
           parent=self, id=wx.ID_ANY, pos=(10, 450), size=(165, 60),
           parent=self, id=wx.ID_ANY, pos=(10, 450), size=(165, 60),
           style=wx.LC_REPORT, label="Apply runes"
           style=wx.LC_REPORT, label="Apply runes"
         )
         )
-        self.Bind(wx.EVT_BUTTON, self.applyRunes, applyBt)
-        self.resultContent.Add(applyBt)
+        self.Bind(wx.EVT_BUTTON, self.applyRunes, applyButton)
+        self.detailsSizer.Add(applyButton)
 
 
         # By default, hide everything TODO
         # By default, hide everything TODO
-        self.resultContainer.ShowItems(False)
-        self.resultContent.ShowItems(False)
+        self.tableSizer.ShowItems(False)
+        self.detailsSizer.ShowItems(False)
 
 
     def processResults(self, unitId=None, jsonData=""):
     def processResults(self, unitId=None, jsonData=""):
         """Processes data obtained from RuneOptimizer.
         """Processes data obtained from RuneOptimizer.
@@ -654,9 +660,6 @@ class PanelResults(wx.Panel):
         if (self.selectedResultIndex < 0):
         if (self.selectedResultIndex < 0):
             # TODO: Show error
             # TODO: Show error
             return;
             return;
-        print("self.selectedResultIndex: " + str(self.selectedResultIndex))
-        #for i in range(0, 6):
-        #    print(self.data.results[self.selectedResultIndex].runes[i])
         # First, unassign all runes currently assigned to the unit
         # First, unassign all runes currently assigned to the unit
         cursor = conn.execute(
         cursor = conn.execute(
           """
           """
@@ -754,16 +757,16 @@ class PanelResults(wx.Panel):
         after changing pages or processing data.
         after changing pages or processing data.
         """
         """
 
 
-        self.pgPrevBt.Enable(True)
-        self.pgNextBt.Enable(True)
+        self.pgPrevButton.Enable(True)
+        self.pgNextButton.Enable(True)
         if self.totalPages == 1:
         if self.totalPages == 1:
-            self.pgPrevBt.Enable(False)
-            self.pgNextBt.Enable(False)
+            self.pgPrevButton.Enable(False)
+            self.pgNextButton.Enable(False)
         elif self.page == 0:
         elif self.page == 0:
-            self.pgPrevBt.Enable(False)
+            self.pgPrevButton.Enable(False)
         elif self.page + 1 == self.totalPages:
         elif self.page + 1 == self.totalPages:
-            self.pgNextBt.Enable(False)
-        self.resultsPageIndicator.SetLabel(
+            self.pgNextButton.Enable(False)
+        self.pageLabel.SetLabel(
           str(self.page + 1) + "/" + str(self.totalPages)
           str(self.page + 1) + "/" + str(self.totalPages)
         )
         )
         for i in range(0, 10):
         for i in range(0, 10):
@@ -791,7 +794,7 @@ class PanelResults(wx.Panel):
         self.unitNameLabel.SetLabel(self.unitName + "    #" + self.unitId)
         self.unitNameLabel.SetLabel(self.unitName + "    #" + self.unitId)
 
 
         # Make the table visible
         # Make the table visible
-        self.resultContainer.ShowItems(True)
+        self.tableSizer.ShowItems(True)
 
 
     def resultSelected(self, event):
     def resultSelected(self, event):
         """Populates and shows the runes and effective stats with the
         """Populates and shows the runes and effective stats with the
@@ -1029,17 +1032,17 @@ class PanelResults(wx.Panel):
         else:
         else:
             self.statGrid.SetCellValue(row=9, col=1, s="")
             self.statGrid.SetCellValue(row=9, col=1, s="")
 
 
-        self.resultContent.ShowItems(True)
+        self.detailsSizer.ShowItems(True)
 
 
         # Clean the runes
         # Clean the runes
         for i in range(0, 5):
         for i in range(0, 5):
-            self.runeIds[i].SetLabel("")
-            self.runeLocations[i].SetLabel("")
-            self.runeSets[i].SetLabel("")
-            self.runeMains[i].SetLabel("")
-            self.runeInnates[i].SetLabel("")
+            self.idLabelList[i].SetLabel("")
+            self.locationLabelList[i].SetLabel("")
+            self.setLabelList[i].SetLabel("")
+            self.mainLabelList[i].SetLabel("")
+            self.innateLabelList[i].SetLabel("")
             for j in range(0, 3):
             for j in range(0, 3):
-                self.runeStats[i][j].SetLabel("")
+                self.statLabelList[i][j].SetLabel("")
 
 
         # Display the runes
         # Display the runes
         cursor = conn.execute(
         cursor = conn.execute(
@@ -1067,14 +1070,14 @@ class PanelResults(wx.Panel):
         i = 0
         i = 0
         for row in cursor:
         for row in cursor:
             # Rows are 21 charactes width
             # Rows are 21 charactes width
-            self.runeIds[i].SetLabel(("#" + str(row[0])).rjust(21, " "))
+            self.idLabelList[i].SetLabel(("#" + str(row[0])).rjust(21, " "))
             if row[4] == None:
             if row[4] == None:
-                self.runeLocations[i].SetLabel("Storage")
+                self.locationLabelList[i].SetLabel("Storage")
             else:
             else:
-                self.runeLocations[i].SetLabel(
+                self.locationLabelList[i].SetLabel(
                   str(row[5])[0:9].ljust(9, " ") + " #" + str(row[4]) + ""
                   str(row[5])[0:9].ljust(9, " ") + " #" + str(row[4]) + ""
                 )
                 )
-            self.runeSets[i].SetLabel(
+            self.setLabelList[i].SetLabel(
               set_names[row[2]].ljust(18, " ") + "+" + str(row[3])
               set_names[row[2]].ljust(18, " ") + "+" + str(row[3])
             )
             )
             #print(self.data.results[self.selectedResultIndex].runes[i])
             #print(self.data.results[self.selectedResultIndex].runes[i])
@@ -1115,12 +1118,12 @@ class PanelResults(wx.Panel):
                         value = value + "%"
                         value = value + "%"
                 line = name + value
                 line = name + value
                 if slot == -1: # main
                 if slot == -1: # main
-                    self.runeMains[i].SetLabel(line)
+                    self.mainLabelList[i].SetLabel(line)
                 elif slot == 0: # innate
                 elif slot == 0: # innate
-                    self.runeInnates[i].SetLabel(line)
+                    self.innateLabelList[i].SetLabel(line)
                 else: # normal stats
                 else: # normal stats
-                    self.runeStats[i][slot - 1].SetLabel(line)
+                    self.statLabelList[i][slot - 1].SetLabel(line)
             i += 1
             i += 1
 
 
         # Make the info visible
         # Make the info visible
-        self.resultContent.ShowItems(True)
+        self.detailsSizer.ShowItems(True)

+ 145 - 118
src/RuneOptimizerGUI/classes/PanelUnits.py

@@ -22,33 +22,39 @@ class PanelUnits(wx.Panel):
 
 
     Parameters
     Parameters
     ----------
     ----------
+    selecterId : string
+        ID of the currently selected unit.
     unitList : wx.ListCtrl
     unitList : wx.ListCtrl
         Selectable unit list with priorities.
         Selectable unit list with priorities.
-    filterName : wx.TextCtrl
+    filterNameText : wx.TextCtrl
         Text input to filter units names.
         Text input to filter units names.
-    filterNames : wx.CheckBox
+    filterNameTexts : wx.CheckBox
         Checkbox to include or exclude units in storage.
         Checkbox to include or exclude units in storage.
-    filterNoRunes : wx.CheckBox
+    filterNoRunesCheck : wx.CheckBox
         Checkbox to include or exclude units without runes.
         Checkbox to include or exclude units without runes.
-    filterNoTeams : wx.CheckBox
+    filterNoTeamsCheck : wx.CheckBox
         Checkbox to include or exclude units in no teams.
         Checkbox to include or exclude units in no teams.
+    detailsSizer : wx.BoxSizer
+        Hold the unit detail elements. Hidden until unit selction.
     statGrid : wx.Grid.grid
     statGrid : wx.Grid.grid
         Table with the unit base and current stats.
         Table with the unit base and current stats.
-    runeSets : wx.StaticText[6]
+    setLabelList : wx.StaticText[6]
         Labels with the set of the runes of the selected unit.
         Labels with the set of the runes of the selected unit.
-    runeIds : wx.StaticText[6]
+    idLabelList : wx.StaticText[6]
         Labels with the IDs of the runes of the selected unit.
         Labels with the IDs of the runes of the selected unit.
-    runeMains : wx.StaticText[6]
+    mainLabelList : wx.StaticText[6]
         Labels with the main stats of the runes of the selected unit.
         Labels with the main stats of the runes of the selected unit.
-    runeInnates : wx.StaticText[6]
+    innateLabelList : wx.StaticText[6]
         Labels with the innates of the runes of the selected unit.
         Labels with the innates of the runes of the selected unit.
-    runeStats : wx.StaticText[6][4]
+    statLabelList : wx.StaticText[6][4]
         Labels with the stats of the runes of the selected unit.
         Labels with the stats of the runes of the selected unit.
 
 
     Methods
     Methods
     -------
     -------
     populateUnitList(event)
     populateUnitList(event)
         Populates the unit list.
         Populates the unit list.
+    goToOptimizer(event)
+        Prepares the optimizer panel with the selected unit and redirects.
     unitSelected(event)
     unitSelected(event)
         Loads a unit info.
         Loads a unit info.
     processResults(jsonData)
     processResults(jsonData)
@@ -56,17 +62,19 @@ class PanelUnits(wx.Panel):
 
 
     """
     """
 
 
+    selectedId = None
     unitList = None
     unitList = None
-    filterName = None
-    filterStorage = None
-    filterNoRunes = None
-    filterNoTeams = None
+    filterNameText = None
+    filterStorageCheck = None
+    filterNoRunesCheck = None
+    filterNoTeamsCheck = None
+    detailsSizer = None
     statGrid = None
     statGrid = None
-    runeSets = None
-    runeIds = None
-    runeMains = None
-    runeInnates = None
-    runeStats = None
+    setLabelList = None
+    idLabelList = None
+    mainLabelList = None
+    innateLabelList = None
+    statLabelList = None
 
 
     def __init__(self, parent, id=wx.ID_ANY):
     def __init__(self, parent, id=wx.ID_ANY):
         """Initializes the panel.
         """Initializes the panel.
@@ -116,36 +124,47 @@ class PanelUnits(wx.Panel):
         wx.StaticText(
         wx.StaticText(
           parent=filterBox, label="Monster name", pos=(5, 5), size=(180, 20)
           parent=filterBox, label="Monster name", pos=(5, 5), size=(180, 20)
         )
         )
-        self.filterName = wx.TextCtrl(
+        self.filterNameText = wx.TextCtrl(
           parent=filterBox, id=wx.ID_ANY, value="", pos=(5, 25),
           parent=filterBox, id=wx.ID_ANY, value="", pos=(5, 25),
           size=(177, 20), style=wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB
           size=(177, 20), style=wx.TE_PROCESS_ENTER|wx.TE_PROCESS_TAB
         )
         )
-        self.Bind(wx.EVT_TEXT_ENTER, self.populateUnitList, self.filterName)
-        self.filterStorage = wx.CheckBox(
+        self.Bind(wx.EVT_TEXT_ENTER, self.populateUnitList, self.filterNameText)
+        self.filterStorageCheck = wx.CheckBox(
           parent=filterBox, id=wx.ID_ANY,
           parent=filterBox, id=wx.ID_ANY,
           label="Monsters in storage", pos=(5, 55), size=(180, 20)
           label="Monsters in storage", pos=(5, 55), size=(180, 20)
         )
         )
-        self.filterStorage.SetValue(True)
-        self.Bind(wx.EVT_CHECKBOX, self.populateUnitList, self.filterStorage)
-        self.filterNoRunes = wx.CheckBox(
+        self.filterStorageCheck.SetValue(True)
+        self.Bind(
+          wx.EVT_CHECKBOX, self.populateUnitList, self.filterStorageCheck
+        )
+        self.filterNoRunesCheck = wx.CheckBox(
           parent=filterBox, id=wx.ID_ANY,
           parent=filterBox, id=wx.ID_ANY,
           label="Monsters without runes", pos=(5, 75), size=(180, 20)
           label="Monsters without runes", pos=(5, 75), size=(180, 20)
         )
         )
-        self.filterNoRunes.SetValue(True)
-        self.Bind(wx.EVT_CHECKBOX, self.populateUnitList, self.filterNoRunes)
-        self.filterNoTeams = wx.CheckBox(
+        self.filterNoRunesCheck.SetValue(True)
+        self.Bind(
+          wx.EVT_CHECKBOX, self.populateUnitList, self.filterNoRunesCheck
+        )
+        self.filterNoTeamsCheck = wx.CheckBox(
           parent=filterBox, id=wx.ID_ANY,
           parent=filterBox, id=wx.ID_ANY,
           label="Monsters not in teams", pos=(5, 95), size=(180, 20)
           label="Monsters not in teams", pos=(5, 95), size=(180, 20)
         )
         )
-        self.filterNoTeams.SetValue(True)
-        self.Bind(wx.EVT_CHECKBOX, self.populateUnitList, self.filterNoTeams)
+        self.filterNoTeamsCheck.SetValue(True)
+        self.Bind(
+          wx.EVT_CHECKBOX, self.populateUnitList, self.filterNoTeamsCheck
+        )
 
 
         self.populateUnitList(None)
         self.populateUnitList(None)
 
 
+        # Sizer for all the unit details. It will be hidden until a unit is
+        # selected.
+        self.detailsSizer = wx.BoxSizer(wx.VERTICAL)
+
         # Stats table
         # Stats table
         self.statGrid = wx.grid.Grid(
         self.statGrid = wx.grid.Grid(
           parent=self, id=wx.ID_ANY, pos=(210, 260), size=(165, 220)
           parent=self, id=wx.ID_ANY, pos=(210, 260), size=(165, 220)
         )
         )
+        self.detailsSizer.Add(self.statGrid)
         self.statGrid.CreateGrid(
         self.statGrid.CreateGrid(
           numRows=10, numCols=2,
           numRows=10, numCols=2,
           selmode=wx.grid.Grid.GridSelectionModes.SelectRowsOrColumns
           selmode=wx.grid.Grid.GridSelectionModes.SelectRowsOrColumns
@@ -185,7 +204,7 @@ class PanelUnits(wx.Panel):
         # Rune list
         # Rune list
         # Decrease fonts for rune tables
         # Decrease fonts for rune tables
         monospaceFont.PointSize -= 2
         monospaceFont.PointSize -= 2
-        runeListBox = [
+        runeBoxList = [
           wx.StaticBox(
           wx.StaticBox(
             parent=self, label="Slot1:",id=wx.ID_ANY,
             parent=self, label="Slot1:",id=wx.ID_ANY,
             pos=(500, 255), size=(105, 110)
             pos=(500, 255), size=(105, 110)
@@ -212,256 +231,266 @@ class PanelUnits(wx.Panel):
           )
           )
         ]
         ]
         for i in range(0, 6):
         for i in range(0, 6):
-            runeListBox[i].SetFont(monospaceFont)
-            #self.resultContent.Add(runeListBox[i])
+            runeBoxList[i].SetFont(monospaceFont)
+            self.detailsSizer.Add(runeBoxList[i])
 
 
-        self.runeSets = [
+        self.setLabelList = [
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[0], id=wx.ID_ANY, label="",
+            parent=runeBoxList[0], id=wx.ID_ANY, label="",
             pos=(0, 0), size=(105, 10)
             pos=(0, 0), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[1], id=wx.ID_ANY, label="",
+            parent=runeBoxList[1], id=wx.ID_ANY, label="",
             pos=(0, 0), size=(105, 10)
             pos=(0, 0), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[2], id=wx.ID_ANY, label="",
+            parent=runeBoxList[2], id=wx.ID_ANY, label="",
             pos=(0, 0), size=(105, 10)
             pos=(0, 0), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[3], id=wx.ID_ANY, label="",
+            parent=runeBoxList[3], id=wx.ID_ANY, label="",
             pos=(0, 0), size=(105, 10)
             pos=(0, 0), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[4], id=wx.ID_ANY, label="",
+            parent=runeBoxList[4], id=wx.ID_ANY, label="",
             pos=(0, 0), size=(105, 10)
             pos=(0, 0), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[5], id=wx.ID_ANY, label="",
+            parent=runeBoxList[5], id=wx.ID_ANY, label="",
             pos=(0, 0), size=(105, 10)
             pos=(0, 0), size=(105, 10)
           ),
           ),
         ]
         ]
 
 
-        self.runeIds = [
+        self.idLabelList = [
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[0], id=wx.ID_ANY, label="",
+            parent=runeBoxList[0], id=wx.ID_ANY, label="",
             pos=(0, 10), size=(105, 10)
             pos=(0, 10), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[1], id=wx.ID_ANY, label="",
+            parent=runeBoxList[1], id=wx.ID_ANY, label="",
             pos=(0, 10), size=(105, 10)
             pos=(0, 10), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[2], id=wx.ID_ANY, label="",
+            parent=runeBoxList[2], id=wx.ID_ANY, label="",
             pos=(0, 10), size=(105, 10)
             pos=(0, 10), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[3], id=wx.ID_ANY, label="",
+            parent=runeBoxList[3], id=wx.ID_ANY, label="",
             pos=(0, 10), size=(105, 10)
             pos=(0, 10), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[4], id=wx.ID_ANY, label="",
+            parent=runeBoxList[4], id=wx.ID_ANY, label="",
             pos=(0, 10), size=(105, 10)
             pos=(0, 10), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[5], id=wx.ID_ANY, label="",
+            parent=runeBoxList[5], id=wx.ID_ANY, label="",
             pos=(0, 10), size=(105, 10)
             pos=(0, 10), size=(105, 10)
           )
           )
         ]
         ]
         wx.StaticLine(
         wx.StaticLine(
-          parent=runeListBox[0], id=wx.ID_ANY,
+          parent=runeBoxList[0], id=wx.ID_ANY,
           pos=(0, 20), size=(105, 1), style=wx.LC_REPORT
           pos=(0, 20), size=(105, 1), style=wx.LC_REPORT
         )
         )
         wx.StaticLine(
         wx.StaticLine(
-          parent=runeListBox[1], id=wx.ID_ANY,
+          parent=runeBoxList[1], id=wx.ID_ANY,
           pos=(0, 20), size=(105, 1), style=wx.LC_REPORT
           pos=(0, 20), size=(105, 1), style=wx.LC_REPORT
         )
         )
         wx.StaticLine(
         wx.StaticLine(
-          parent=runeListBox[2], id=wx.ID_ANY,
+          parent=runeBoxList[2], id=wx.ID_ANY,
           pos=(0, 20), size=(105, 1), style=wx.LC_REPORT
           pos=(0, 20), size=(105, 1), style=wx.LC_REPORT
         )
         )
         wx.StaticLine(
         wx.StaticLine(
-          parent=runeListBox[3], id=wx.ID_ANY,
+          parent=runeBoxList[3], id=wx.ID_ANY,
           pos=(0, 20), size=(105, 1), style=wx.LC_REPORT
           pos=(0, 20), size=(105, 1), style=wx.LC_REPORT
         )
         )
         wx.StaticLine(
         wx.StaticLine(
-          parent=runeListBox[4], id=wx.ID_ANY,
+          parent=runeBoxList[4], id=wx.ID_ANY,
           pos=(0, 20), size=(105, 1), style=wx.LC_REPORT
           pos=(0, 20), size=(105, 1), style=wx.LC_REPORT
         )
         )
         wx.StaticLine(
         wx.StaticLine(
-          parent=runeListBox[5], id=wx.ID_ANY,
+          parent=runeBoxList[5], id=wx.ID_ANY,
           pos=(0, 20), size=(105, 1), style=wx.LC_REPORT
           pos=(0, 20), size=(105, 1), style=wx.LC_REPORT
         )
         )
 
 
-        self.runeMains = [
+        self.mainLabelList = [
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[0], id=wx.ID_ANY, label="",
+            parent=runeBoxList[0], id=wx.ID_ANY, label="",
             pos=(0, 30), size=(105, 10)
             pos=(0, 30), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[1], id=wx.ID_ANY, label="",
+            parent=runeBoxList[1], id=wx.ID_ANY, label="",
             pos=(0, 30), size=(105, 10)
             pos=(0, 30), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[2], id=wx.ID_ANY, label="",
+            parent=runeBoxList[2], id=wx.ID_ANY, label="",
             pos=(0, 30), size=(105, 10)
             pos=(0, 30), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[3], id=wx.ID_ANY, label="",
+            parent=runeBoxList[3], id=wx.ID_ANY, label="",
             pos=(0, 30), size=(105, 10)
             pos=(0, 30), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[4], id=wx.ID_ANY, label="",
+            parent=runeBoxList[4], id=wx.ID_ANY, label="",
             pos=(0, 30), size=(105, 10)
             pos=(0, 30), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[5], id=wx.ID_ANY, label="",
+            parent=runeBoxList[5], id=wx.ID_ANY, label="",
             pos=(0, 30), size=(105, 10)
             pos=(0, 30), size=(105, 10)
           )
           )
         ]
         ]
         for i in range(0, 6):
         for i in range(0, 6):
-            self.runeMains[i].SetFont(monospaceFontBold)
+            self.mainLabelList[i].SetFont(monospaceFontBold)
 
 
-        self.runeInnates = [
+        self.innateLabelList = [
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[0], id=wx.ID_ANY, label="",
+            parent=runeBoxList[0], id=wx.ID_ANY, label="",
             pos=(0, 40), size=(105, 10)
             pos=(0, 40), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[1], id=wx.ID_ANY, label="",
+            parent=runeBoxList[1], id=wx.ID_ANY, label="",
             pos=(0, 40), size=(105, 10)
             pos=(0, 40), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[2], id=wx.ID_ANY, label="",
+            parent=runeBoxList[2], id=wx.ID_ANY, label="",
             pos=(0, 40), size=(105, 10)
             pos=(0, 40), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[3], id=wx.ID_ANY, label="",
+            parent=runeBoxList[3], id=wx.ID_ANY, label="",
             pos=(0, 40), size=(105, 10)
             pos=(0, 40), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[4], id=wx.ID_ANY, label="",
+            parent=runeBoxList[4], id=wx.ID_ANY, label="",
             pos=(0, 40), size=(105, 10)
             pos=(0, 40), size=(105, 10)
           ),
           ),
           wx.StaticText(
           wx.StaticText(
-            parent=runeListBox[5], id=wx.ID_ANY, label="",
+            parent=runeBoxList[5], id=wx.ID_ANY, label="",
             pos=(0, 40), size=(105, 10)
             pos=(0, 40), size=(105, 10)
           )
           )
         ]
         ]
         for i in range(0, 6):
         for i in range(0, 6):
-            self.runeInnates[i].SetFont(monospaceFontItalic)
+            self.innateLabelList[i].SetFont(monospaceFontItalic)
 
 
-        self.runeStats = [
+        self.statLabelList = [
           [
           [
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[0], id=wx.ID_ANY, label="",
+              parent=runeBoxList[0], id=wx.ID_ANY, label="",
               pos=(0, 50), size=(105, 10)
               pos=(0, 50), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[0], id=wx.ID_ANY, label="",
+              parent=runeBoxList[0], id=wx.ID_ANY, label="",
               pos=(0, 60), size=(105, 10)
               pos=(0, 60), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[0], id=wx.ID_ANY, label="",
+              parent=runeBoxList[0], id=wx.ID_ANY, label="",
               pos=(0, 70), size=(105, 10)
               pos=(0, 70), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[0], id=wx.ID_ANY, label="",
+              parent=runeBoxList[0], id=wx.ID_ANY, label="",
               pos=(0, 80), size=(105, 10)
               pos=(0, 80), size=(105, 10)
             )
             )
           ],
           ],
           [
           [
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[1], id=wx.ID_ANY, label="",
+              parent=runeBoxList[1], id=wx.ID_ANY, label="",
               pos=(0, 50), size=(105, 10)
               pos=(0, 50), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[1], id=wx.ID_ANY, label="",
+              parent=runeBoxList[1], id=wx.ID_ANY, label="",
               pos=(0, 60), size=(105, 10)
               pos=(0, 60), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[1], id=wx.ID_ANY, label="",
+              parent=runeBoxList[1], id=wx.ID_ANY, label="",
               pos=(0, 70), size=(105, 10)
               pos=(0, 70), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[1], id=wx.ID_ANY, label="",
+              parent=runeBoxList[1], id=wx.ID_ANY, label="",
               pos=(0, 80), size=(105, 10)
               pos=(0, 80), size=(105, 10)
             )
             )
           ],
           ],
           [
           [
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[2], id=wx.ID_ANY, label="",
+              parent=runeBoxList[2], id=wx.ID_ANY, label="",
               pos=(0, 50), size=(105, 10)
               pos=(0, 50), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[2], id=wx.ID_ANY, label="",
+              parent=runeBoxList[2], id=wx.ID_ANY, label="",
               pos=(0, 60), size=(105, 10)
               pos=(0, 60), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[2], id=wx.ID_ANY, label="",
+              parent=runeBoxList[2], id=wx.ID_ANY, label="",
               pos=(0, 70), size=(105, 10)
               pos=(0, 70), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[2], id=wx.ID_ANY, label="",
+              parent=runeBoxList[2], id=wx.ID_ANY, label="",
               pos=(0, 80), size=(105, 10)
               pos=(0, 80), size=(105, 10)
             )
             )
           ],
           ],
           [
           [
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[3], id=wx.ID_ANY, label="",
+              parent=runeBoxList[3], id=wx.ID_ANY, label="",
               pos=(0, 50), size=(105, 10)
               pos=(0, 50), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[3], id=wx.ID_ANY, label="",
+              parent=runeBoxList[3], id=wx.ID_ANY, label="",
               pos=(0, 60), size=(105, 10)
               pos=(0, 60), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[3], id=wx.ID_ANY, label="",
+              parent=runeBoxList[3], id=wx.ID_ANY, label="",
               pos=(0, 70), size=(105, 10)
               pos=(0, 70), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[3], id=wx.ID_ANY, label="",
+              parent=runeBoxList[3], id=wx.ID_ANY, label="",
               pos=(0, 80), size=(105, 10)
               pos=(0, 80), size=(105, 10)
             )
             )
           ],
           ],
           [
           [
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[4], id=wx.ID_ANY, label="",
+              parent=runeBoxList[4], id=wx.ID_ANY, label="",
               pos=(0, 50), size=(105, 10)
               pos=(0, 50), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[4], id=wx.ID_ANY, label="",
+              parent=runeBoxList[4], id=wx.ID_ANY, label="",
               pos=(0, 60), size=(105, 10)
               pos=(0, 60), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[4], id=wx.ID_ANY, label="",
+              parent=runeBoxList[4], id=wx.ID_ANY, label="",
               pos=(0, 70), size=(105, 10)
               pos=(0, 70), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[4], id=wx.ID_ANY, label="",
+              parent=runeBoxList[4], id=wx.ID_ANY, label="",
               pos=(0, 80), size=(105, 10)
               pos=(0, 80), size=(105, 10)
             )
             )
           ],
           ],
           [
           [
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[5], id=wx.ID_ANY, label="",
+              parent=runeBoxList[5], id=wx.ID_ANY, label="",
               pos=(0, 50), size=(105, 10)
               pos=(0, 50), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[5], id=wx.ID_ANY, label="",
+              parent=runeBoxList[5], id=wx.ID_ANY, label="",
               pos=(0, 60), size=(105, 10)
               pos=(0, 60), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[5], id=wx.ID_ANY, label="",
+              parent=runeBoxList[5], id=wx.ID_ANY, label="",
               pos=(0, 70), size=(105, 10)
               pos=(0, 70), size=(105, 10)
             ),
             ),
             wx.StaticText(
             wx.StaticText(
-              parent=runeListBox[5], id=wx.ID_ANY, label="",
+              parent=runeBoxList[5], id=wx.ID_ANY, label="",
               pos=(0, 80), size=(105, 10)
               pos=(0, 80), size=(105, 10)
             )
             )
           ]
           ]
         ]
         ]
 
 
+        optimizeButton = wx.Button(
+          parent=self, id=wx.ID_ANY, pos=(500, 500), size=(105, 30),
+          style=wx.LC_REPORT, label="Optimize"
+        )
+        self.detailsSizer.Add(optimizeButton)
+        self.Bind(wx.EVT_BUTTON, self.goToOptimizer, optimizeButton)
+
+        # By default, hide all optimization options
+        self.detailsSizer.ShowItems(False)
+
 
 
     def populateUnitList(self, event):
     def populateUnitList(self, event):
         """Populates the unit list.
         """Populates the unit list.
@@ -476,7 +505,7 @@ class PanelUnits(wx.Panel):
         """
         """
 
 
         # Get units from db
         # Get units from db
-        name = self.filterName.GetValue()
+        name = self.filterNameText.GetValue()
         query = """
         query = """
           SELECT
           SELECT
             id,
             id,
@@ -491,11 +520,11 @@ class PanelUnits(wx.Panel):
           WHERE
           WHERE
             name LIKE '%""" + name + """%'
             name LIKE '%""" + name + """%'
         """
         """
-        if self.filterStorage.GetValue() == False:
+        if self.filterStorageCheck.GetValue() == False:
             query += " AND storage = 0 "
             query += " AND storage = 0 "
-        if self.filterNoRunes.GetValue() == False:
+        if self.filterNoRunesCheck.GetValue() == False:
             query += " AND id IN (SELECT DISTINCT unit FROM runes) "
             query += " AND id IN (SELECT DISTINCT unit FROM runes) "
-        if self.filterNoTeams.GetValue() == False:
+        if self.filterNoTeamsCheck.GetValue() == False:
             query += " AND id IN (SELECT DISTINCT unit FROM units_teams) "
             query += " AND id IN (SELECT DISTINCT unit FROM units_teams) "
         query += " ORDER BY priority DESC; ";
         query += " ORDER BY priority DESC; ";
         print(query)
         print(query)
@@ -513,6 +542,18 @@ class PanelUnits(wx.Panel):
                 self.unitList.SetItem(i, 2, " ")
                 self.unitList.SetItem(i, 2, " ")
             i = i + 1
             i = i + 1
 
 
+    def goToOptimizer(self, event = None):
+        """Prepares the optimizer panel with the selected unit and redirects.
+
+        Parameters
+        ----------
+        event : wxEvent, optional
+            The event that triggered the call (default is None).
+
+        """
+        self.GetParent().frameOptimizer.unitId = self.selectedId
+        self.GetParent().frameOptimizer.selectUnit(event=None)
+        self.GetParent().ChangeSelection(2)
 
 
     def unitSelected(self, event):
     def unitSelected(self, event):
         """Loads a unit info and enables optimizaton options.
         """Loads a unit info and enables optimizaton options.
@@ -527,9 +568,6 @@ class PanelUnits(wx.Panel):
         """
         """
         id = str(self.unitList.GetItemData(self.unitList.GetFirstSelected()))
         id = str(self.unitList.GetItemData(self.unitList.GetFirstSelected()))
 
 
-        #print("UNIT SELECTED: " + id)
-
-
         cursor = conn.execute("""
         cursor = conn.execute("""
           SELECT
           SELECT
             base_hp,
             base_hp,
@@ -555,12 +593,10 @@ class PanelUnits(wx.Panel):
             id = """ + id + """;
             id = """ + id + """;
         """)
         """)
         row = cursor.fetchone()
         row = cursor.fetchone()
-        #self.unitContent.ShowItems(True)
-        #self.unitNameValue = str(row[17])
-        #self.unitName.SetLabel(str(row[17]) + "    (# " + str(row[16]) + ")")
+        self.selectedId = id
+        self.detailsSizer.ShowItems(True)
         for i in range(0, 8):
         for i in range(0, 8):
             value = str(row[i])
             value = str(row[i])
-        #    self.minStatSlid[i].SetMin(int(value))
             if i > 3:
             if i > 3:
                 value = value + "%"
                 value = value + "%"
             else:
             else:
@@ -568,9 +604,6 @@ class PanelUnits(wx.Panel):
             self.statGrid.SetCellValue(row=i, col=0, s=value)
             self.statGrid.SetCellValue(row=i, col=0, s=value)
         for i in range(0, 8):
         for i in range(0, 8):
             value = str(row[8 + i])
             value = str(row[8 + i])
-        #    self.minStatSlid[i].SetValue(int(value))
-        #    self.minStatText[i].SetValue(value)
-        #    self.currentStats[i] = int(value)
             if i > 3:
             if i > 3:
                 value = value + "%"
                 value = value + "%"
             else:
             else:
@@ -587,8 +620,6 @@ class PanelUnits(wx.Panel):
           int(self.statGrid.GetCellValue(row=2, col=1).replace("%", ""))
           int(self.statGrid.GetCellValue(row=2, col=1).replace("%", ""))
         currentEhp = math.ceil((((currentDef * 3.5) + 1140) * currentHp) / 1000)
         currentEhp = math.ceil((((currentDef * 3.5) + 1140) * currentHp) / 1000)
         self.statGrid.SetCellValue(row=8, col=1, s=str(currentEhp))
         self.statGrid.SetCellValue(row=8, col=1, s=str(currentEhp))
-        #self.minStatSlid[8].SetValue(currentEhp)
-        #self.minStatText[8].SetValue(str(currentEhp))
         baseAtk = int(self.statGrid.GetCellValue(row=1, col=0))
         baseAtk = int(self.statGrid.GetCellValue(row=1, col=0))
         baseCrr = int(self.statGrid.GetCellValue(row=4, col=0).replace("%", ""))
         baseCrr = int(self.statGrid.GetCellValue(row=4, col=0).replace("%", ""))
         baseCrd = int(self.statGrid.GetCellValue(row=5, col=0).replace("%", ""))
         baseCrd = int(self.statGrid.GetCellValue(row=5, col=0).replace("%", ""))
@@ -600,22 +631,18 @@ class PanelUnits(wx.Panel):
           ((baseAtk + (baseAtk * baseCrd / 100)) * baseCrr / 100)
           ((baseAtk + (baseAtk * baseCrd / 100)) * baseCrr / 100)
         )
         )
         self.statGrid.SetCellValue(row=9, col=0, s=str(baseDmg))
         self.statGrid.SetCellValue(row=9, col=0, s=str(baseDmg))
-        #self.minStatSlid[9].SetMin(baseDmg)
         currentAtk = int(self.statGrid.GetCellValue(row=1, col=1))
         currentAtk = int(self.statGrid.GetCellValue(row=1, col=1))
         currentCrr = \
         currentCrr = \
           int(self.statGrid.GetCellValue(row=4, col=0).replace("%", ""))
           int(self.statGrid.GetCellValue(row=4, col=0).replace("%", ""))
         currentCrd = \
         currentCrd = \
           int(self.statGrid.GetCellValue(row=5, col=1).replace("%", ""))
           int(self.statGrid.GetCellValue(row=5, col=1).replace("%", ""))
         if (currentCrr > 100):
         if (currentCrr > 100):
-            # Dont use crit rate over 100
             currentCrr = 100
             currentCrr = 100
         currentDmg = math.ceil(
         currentDmg = math.ceil(
           (currentAtk * (100 - currentCrr) / 100) +
           (currentAtk * (100 - currentCrr) / 100) +
           ((currentAtk + (currentAtk * currentCrd / 100)) * currentCrr / 100)
           ((currentAtk + (currentAtk * currentCrd / 100)) * currentCrr / 100)
         )
         )
         self.statGrid.SetCellValue(row=9, col=1, s=str(currentDmg))
         self.statGrid.SetCellValue(row=9, col=1, s=str(currentDmg))
-        #self.minStatSlid[9].SetValue(currentDmg)
-        #self.minStatText[9].SetValue(str(currentDmg))
 
 
         # Populate the runes
         # Populate the runes
         cursor = conn.execute("""
         cursor = conn.execute("""
@@ -635,9 +662,9 @@ class PanelUnits(wx.Panel):
         i = 0
         i = 0
         for row in cursor:
         for row in cursor:
             # Rows are 19 charactes width
             # Rows are 19 charactes width
-            self.runeSets[i].SetLabel(set_names[row[2]])
+            self.setLabelList[i].SetLabel(set_names[row[2]])
             rid = ("#" + str(row[0])).rjust(13, " ")
             rid = ("#" + str(row[0])).rjust(13, " ")
-            self.runeIds[i].SetLabel(rid)
+            self.idLabelList[i].SetLabel(rid)
             #setname = set_names[row[2]][0:6].ljust(6, " ")
             #setname = set_names[row[2]][0:6].ljust(6, " ")
 
 
             level = "+" + str(row[3]).ljust(2, " ")
             level = "+" + str(row[3]).ljust(2, " ")
@@ -681,10 +708,10 @@ class PanelUnits(wx.Panel):
                         value = value + "%"
                         value = value + "%"
                 line = name + value
                 line = name + value
                 if slot == -1: # main
                 if slot == -1: # main
-                    self.runeMains[i].SetLabel(line + "|   " + level)
+                    self.mainLabelList[i].SetLabel(line + "|   " + level)
                 elif slot == 0: # innate
                 elif slot == 0: # innate
                     innateLabel = line
                     innateLabel = line
                 else: # normal stats
                 else: # normal stats
-                    self.runeStats[i][slot - 1].SetLabel(line)
-            self.runeInnates[i].SetLabel(innateLabel + "|" + eff)
+                    self.statLabelList[i][slot - 1].SetLabel(line)
+            self.innateLabelList[i].SetLabel(innateLabel + "|" + eff)
             i = i + 1
             i = i + 1

+ 0 - 721
src/RuneOptimizerGUI/classes/ResultsFrame.py

@@ -1,721 +0,0 @@
-"""
-This file is part of RuneOptimizer.
-
-RuneOptimizer 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.
-
-RuneOptimizer 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
-RuneOptimizer. If not, see <https://www.gnu.org/licenses/>.
-
-"""
-
-
-class ResultsFrame(wx.Frame):
-    """
-    The frame uset to see and check results.
-
-    Parameters
-    ----------
-    unitId : str
-        ID of the unit being optimized (default "").
-    unitName : str
-        Name of the unit being optimized (default "").
-    data : Python Object
-        Results from RuneOptimizer (default None).
-    currentStats : int[10]
-        The current stats of the unit being optimized. (default is
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).
-    page : int
-        Currently displayed page, 0-index (default 0).
-    totalPages : int
-        Number of pages of results (default 0).
-    linesPerPage : int
-        Number of results to show per page (default 10).
-    pgPrevBt : wx.Button
-        Button to go to the previous page.
-    pgPrevBt : wx.Button
-        Button to go to the previous page.
-    resultsPageIndicator : wx.StaticText
-        Label to indicate the current and maximum pages.
-    resultGrid : wx.Grid.grid
-        Table of results.
-    resultContent : wx.BoxSizer
-        Holds every widget that is hidden until a result is selected.
-    statGrid : wx.Grid.grid
-        Table to show the new stats with the selected result.
-    runeIds : wx.StaticText[6]
-        Labels with the IDs of the runes in the current result.
-    runeLocations : wx.StaticText[6]
-        Labels with the locations of the runes in the current result.
-    runeSets : wx.StaticText[6]
-        Labels with the set names of the runes in the current result.
-    runeMains : wx.StaticText[6]
-        Labels with the main stats of the runes in the current result.
-    runeInnates : wx.StaticText[6]
-        Labels with the innates of the runes in the current result.
-    runeStats : wx.StaticText[6][4]
-        Labels with the stats of the runes in the current result.
-    selectedResultndex : int
-        Selected result index (default -1).
-
-    Methods
-    -------
-    processResults(jsonData)
-        Processes data obtained from RuneOptimizer.
-    pgPrev(event)
-        Goes to the previous result page.
-    pgNext(event)
-        Goes to the next result page.
-    closeWindow(event)
-        Closes the frame.
-    applyRunes(event)
-        Applies the runes in the currently selected result.
-    printResults()
-        Populates the results table with the results in the currently
-        selected page.
-    resultSelected(event)
-        Populates and shows the runes and effective stats with the
-        currently seleced result.
-
-    """
-
-    unitId = ""
-    unitName = ""
-    data = None
-    currentStats = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
-    page = 0
-    totalPages = 0
-    linesPerPage = 10
-    pgPrevBt = None
-    pgNextBt = None
-    resultsPageIndicator = None
-    resultGrid = None
-    resultContent = None
-    statGrid = None
-    runeIds = None
-    runeLocations = None
-    runeSets = None
-    runeMains = None
-    runeInnates = None
-    runeStats = None
-    selectedResultIndex = -1
-
-    def __init__(self, *args, **kw):
-        """Initializes the class.
-
-        Sets upt all the widgets.
-
-        """
-
-        global conn
-        # ensure the parent's __init__ is called
-        super(ResultsFrame, self).__init__(*args, **kw)
-
-        # create a panel in the frame
-        pnl = wx.Panel(self)
-
-        self.resultGrid = wx.grid.Grid(parent=pnl, id=-1, pos=(50, 30), size=(544, 220))
-        self.resultGrid.CreateGrid(numRows=10, numCols=11, selmode=wx.grid.Grid.GridSelectionModes.SelectRows)
-        self.resultGrid.EnableEditing(False)
-        self.resultGrid.SetDefaultCellAlignment(horiz=wx.ALIGN_RIGHT, vert=wx.ALIGN_CENTRE)
-        monospaceFont = wx.Font(10, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
-        self.resultGrid.SetDefaultCellFont(monospaceFont)
-        self.resultGrid.SetRowLabelSize(width=35)
-        self.resultGrid.SetColLabelValue(col=0, value="Rating")
-        self.resultGrid.SetColSize(col=0, width=50)
-        self.resultGrid.SetColLabelValue(col=1, value="HP")
-        self.resultGrid.SetColSize(col=1, width=50)
-        self.resultGrid.SetColLabelValue(col=2, value="ATK")
-        self.resultGrid.SetColSize(col=2, width=40)
-        self.resultGrid.SetColLabelValue(col=3, value="DEF")
-        self.resultGrid.SetColSize(col=3, width=40)
-        self.resultGrid.SetColLabelValue(col=4, value="SPD")
-        self.resultGrid.SetColSize(col=4, width=40)
-        self.resultGrid.SetColLabelValue(col=5, value="CRR")
-        self.resultGrid.SetColSize(col=5, width=40)
-        self.resultGrid.SetColLabelValue(col=6, value="CRD")
-        self.resultGrid.SetColSize(col=6, width=40)
-        self.resultGrid.SetColLabelValue(col=7, value="RES")
-        self.resultGrid.SetColSize(col=7, width=40)
-        self.resultGrid.SetColLabelValue(col=8, value="ACC")
-        self.resultGrid.SetColSize(col=8, width=40)
-        self.resultGrid.SetColLabelValue(col=9, value="EHP")
-        self.resultGrid.SetColSize(col=9, width=60)
-        self.resultGrid.SetColLabelValue(col=10, value="DMG")
-        self.resultGrid.SetColSize(col=10, width=50)
-        self.resultGrid.SetColLabelSize(height=20)
-        self.resultGrid.SetDefaultRowSize(height=20)
-        self.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.resultSelected, self.resultGrid)
-
-        # Paginator
-        self.pgPrevBt = wx.Button(parent=pnl, id=-1, pos=(580, 30), size=(40, 50), style=wx.LC_REPORT, label="Prev\npage")
-        self.resultsPageIndicator = wx.StaticText(parent=pnl, label="1/1",id=-1, pos=(580, 80), size=(40, 15), style=wx.ALIGN_CENTRE_HORIZONTAL)
-        self.pgNextBt = wx.Button(parent=pnl, id=-1, pos=(580, 100), size=(40, 50), style=wx.LC_REPORT, label="Next\npage")
-        self.Bind(wx.EVT_BUTTON, self.pgPrev, self.pgPrevBt)
-        self.Bind(wx.EVT_BUTTON, self.pgNext, self.pgNextBt)
-
-        self.resultContent = wx.BoxSizer(wx.VERTICAL)
-
-        # Stats table
-        self.statGrid = wx.grid.Grid(parent=pnl, id=-1, pos=(650, 30), size=(205, 220), style=wx.LC_REPORT)
-        self.statGrid.CreateGrid(numRows=10, numCols=2, selmode=wx.grid.Grid.GridSelectionModes.SelectRowsOrColumns)
-        self.statGrid.EnableEditing(False)
-        self.statGrid.SetDefaultCellAlignment(horiz=wx.ALIGN_RIGHT, vert=wx.ALIGN_CENTRE)
-        monospaceFont = wx.Font(10, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
-        self.statGrid.SetDefaultCellFont(monospaceFont)
-        self.statGrid.SetColSize(col=0, width=70)
-        self.statGrid.SetColLabelValue(col=0, value="Value")
-        self.statGrid.SetColLabelValue(col=1, value="Diff")
-        self.statGrid.SetRowLabelSize(width=35)
-        self.statGrid.SetColLabelSize(height=20)
-        self.statGrid.SetRowSize(row=0, height=20)
-        self.statGrid.SetRowSize(row=1, height=20)
-        self.statGrid.SetRowSize(row=2, height=20)
-        self.statGrid.SetRowSize(row=3, height=20)
-        self.statGrid.SetRowSize(row=4, height=20)
-        self.statGrid.SetRowSize(row=5, height=20)
-        self.statGrid.SetRowSize(row=6, height=20)
-        self.statGrid.SetRowSize(row=7, height=20)
-        self.statGrid.SetRowSize(row=8, height=20)
-        self.statGrid.SetRowSize(row=9, height=20)
-        self.statGrid.SetRowLabelValue(row=0, value=" HP")
-        self.statGrid.SetRowLabelValue(row=1, value="ATK")
-        self.statGrid.SetRowLabelValue(row=2, value="DEF")
-        self.statGrid.SetRowLabelValue(row=3, value="SPD")
-        self.statGrid.SetRowLabelValue(row=4, value="CRR")
-        self.statGrid.SetRowLabelValue(row=5, value="CRD")
-        self.statGrid.SetRowLabelValue(row=6, value="RES")
-        self.statGrid.SetRowLabelValue(row=7, value="ACC")
-        self.statGrid.SetRowLabelValue(row=8, value="EHP")
-        self.statGrid.SetRowLabelValue(row=9, value="DMG")
-        self.resultContent.Add(self.statGrid)
-
-        monospaceFont = wx.Font(10, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
-        monospaceFont.PointSize -= 2
-        monospaceFontBold = wx.Font(10, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
-        monospaceFontBold.PointSize -= 2
-        monospaceFontItalic = wx.Font(10, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_ITALIC, wx.FONTWEIGHT_NORMAL)
-        monospaceFontItalic.PointSize -= 2
-
-        #Rune set list
-        runeListBox = [
-          wx.StaticBox(parent=pnl, label="Slot1:",id=-1, pos=(200, 255), size=(140, 160)),
-          wx.StaticBox(parent=pnl, label="Slot2:",id=-1, pos=(350, 255), size=(140, 160)),
-          wx.StaticBox(parent=pnl, label="Slot3:",id=-1, pos=(350, 420), size=(140, 160)),
-          wx.StaticBox(parent=pnl, label="Slot4:",id=-1, pos=(200, 420), size=(140, 160)),
-          wx.StaticBox(parent=pnl, label="Slot5:",id=-1, pos=(50, 420), size=(140, 160)),
-          wx.StaticBox(parent=pnl, label="Slot6:",id=-1, pos=(50, 255), size=(140, 160)),
-        ]
-        for i in range(0, 6):
-            runeListBox[i].SetFont(monospaceFont)
-            self.resultContent.Add(runeListBox[i])
-
-        self.runeIds = [
-          wx.StaticText(runeListBox[0], label="",id=-1, pos=(5, 0), size=(120, 10)),
-          wx.StaticText(runeListBox[1], label="",id=-1, pos=(5, 0), size=(120, 10)),
-          wx.StaticText(runeListBox[2], label="",id=-1, pos=(5, 0), size=(120, 10)),
-          wx.StaticText(runeListBox[3], label="",id=-1, pos=(5, 0), size=(120, 10)),
-          wx.StaticText(runeListBox[4], label="",id=-1, pos=(5, 0), size=(120, 10)),
-          wx.StaticText(runeListBox[5], label="",id=-1, pos=(5, 0), size=(120, 10)),
-        ]
-
-        self.runeLocations = [
-          wx.StaticText(runeListBox[0], label="",id=-1, pos=(5, 15), size=(120, 10)),
-          wx.StaticText(runeListBox[1], label="",id=-1, pos=(5, 15), size=(120, 10)),
-          wx.StaticText(runeListBox[2], label="",id=-1, pos=(5, 15), size=(120, 10)),
-          wx.StaticText(runeListBox[3], label="",id=-1, pos=(5, 15), size=(120, 10)),
-          wx.StaticText(runeListBox[4], label="",id=-1, pos=(5, 15), size=(120, 10)),
-          wx.StaticText(runeListBox[5], label="",id=-1, pos=(5, 15), size=(120, 10)),
-        ]
-
-        self.runeSets = [
-          wx.StaticText(runeListBox[0], label="",id=-1, pos=(5, 30), size=(120, 10)),
-          wx.StaticText(runeListBox[1], label="",id=-1, pos=(5, 30), size=(120, 10)),
-          wx.StaticText(runeListBox[2], label="",id=-1, pos=(5, 30), size=(120, 10)),
-          wx.StaticText(runeListBox[3], label="",id=-1, pos=(5, 30), size=(120, 10)),
-          wx.StaticText(runeListBox[4], label="",id=-1, pos=(5, 30), size=(120, 10)),
-          wx.StaticText(runeListBox[5], label="",id=-1, pos=(5, 30), size=(120, 10)),
-        ]
-
-        wx.StaticLine(parent=runeListBox[0], id=-1, pos=(5, 45), size=(130, 1), style=wx.LC_REPORT)
-        wx.StaticLine(parent=runeListBox[1], id=-1, pos=(5, 45), size=(130, 1), style=wx.LC_REPORT)
-        wx.StaticLine(parent=runeListBox[2], id=-1, pos=(5, 45), size=(130, 1), style=wx.LC_REPORT)
-        wx.StaticLine(parent=runeListBox[3], id=-1, pos=(5, 45), size=(130, 1), style=wx.LC_REPORT)
-        wx.StaticLine(parent=runeListBox[4], id=-1, pos=(5, 45), size=(130, 1), style=wx.LC_REPORT)
-        wx.StaticLine(parent=runeListBox[5], id=-1, pos=(5, 45), size=(130, 1), style=wx.LC_REPORT)
-
-        self.runeMains = [
-          wx.StaticText(runeListBox[0], label="",id=-1, pos=(5, 50), size=(120, 10)),
-          wx.StaticText(runeListBox[1], label="",id=-1, pos=(5, 50), size=(120, 10)),
-          wx.StaticText(runeListBox[2], label="",id=-1, pos=(5, 50), size=(120, 10)),
-          wx.StaticText(runeListBox[3], label="",id=-1, pos=(5, 50), size=(120, 10)),
-          wx.StaticText(runeListBox[4], label="",id=-1, pos=(5, 50), size=(120, 10)),
-          wx.StaticText(runeListBox[5], label="",id=-1, pos=(5, 50), size=(120, 10)),
-        ]
-        for i in range(0, 6):
-            self.runeMains[i].SetFont(monospaceFontBold)
-
-        self.runeInnates = [
-          wx.StaticText(runeListBox[0], label="",id=-1, pos=(5, 65), size=(120, 10)),
-          wx.StaticText(runeListBox[1], label="",id=-1, pos=(5, 65), size=(120, 10)),
-          wx.StaticText(runeListBox[2], label="",id=-1, pos=(5, 65), size=(120, 10)),
-          wx.StaticText(runeListBox[3], label="",id=-1, pos=(5, 65), size=(120, 10)),
-          wx.StaticText(runeListBox[4], label="",id=-1, pos=(5, 65), size=(120, 10)),
-          wx.StaticText(runeListBox[5], label="",id=-1, pos=(5, 65), size=(120, 10)),
-        ]
-        for i in range(0, 6):
-            self.runeInnates[i].SetFont(monospaceFontItalic)
-
-        self.runeStats = [
-          [
-            wx.StaticText(runeListBox[0], label="",id=-1, pos=(5, 80), size=(120, 10)),
-            wx.StaticText(runeListBox[0], label="",id=-1, pos=(5, 95), size=(120, 10)),
-            wx.StaticText(runeListBox[0], label="",id=-1, pos=(5, 110), size=(120, 10)),
-            wx.StaticText(runeListBox[0], label="",id=-1, pos=(5, 125), size=(120, 10))
-          ],
-          [
-            wx.StaticText(runeListBox[1], label="",id=-1, pos=(5, 80), size=(120, 10)),
-            wx.StaticText(runeListBox[1], label="",id=-1, pos=(5, 95), size=(120, 10)),
-            wx.StaticText(runeListBox[1], label="",id=-1, pos=(5, 110), size=(120, 10)),
-            wx.StaticText(runeListBox[1], label="",id=-1, pos=(5, 125), size=(120, 10))
-          ],
-          [
-            wx.StaticText(runeListBox[2], label="",id=-1, pos=(5, 80), size=(120, 10)),
-            wx.StaticText(runeListBox[2], label="",id=-1, pos=(5, 95), size=(120, 10)),
-            wx.StaticText(runeListBox[2], label="",id=-1, pos=(5, 110), size=(120, 10)),
-            wx.StaticText(runeListBox[2], label="",id=-1, pos=(5, 125), size=(120, 10))
-          ],
-          [
-            wx.StaticText(runeListBox[3], label="",id=-1, pos=(5, 80), size=(120, 10)),
-            wx.StaticText(runeListBox[3], label="",id=-1, pos=(5, 95), size=(120, 10)),
-            wx.StaticText(runeListBox[3], label="",id=-1, pos=(5, 110), size=(120, 10)),
-            wx.StaticText(runeListBox[3], label="",id=-1, pos=(5, 125), size=(120, 10))
-          ],
-          [
-            wx.StaticText(runeListBox[4], label="",id=-1, pos=(5, 80), size=(120, 10)),
-            wx.StaticText(runeListBox[4], label="",id=-1, pos=(5, 95), size=(120, 10)),
-            wx.StaticText(runeListBox[4], label="",id=-1, pos=(5, 110), size=(120, 10)),
-            wx.StaticText(runeListBox[4], label="",id=-1, pos=(5, 125), size=(120, 10))
-          ],
-          [
-            wx.StaticText(runeListBox[5], label="",id=-1, pos=(5, 80), size=(120, 10)),
-            wx.StaticText(runeListBox[5], label="",id=-1, pos=(5, 95), size=(120, 10)),
-            wx.StaticText(runeListBox[5], label="",id=-1, pos=(5, 110), size=(120, 10)),
-            wx.StaticText(runeListBox[5], label="",id=-1, pos=(5, 125), size=(120, 10))
-          ],
-        ]
-
-        # Action buttons
-        applyBt = wx.Button(parent=pnl, id=-1, pos=(650, 330), size=(165, 60), style=wx.LC_REPORT, label="Apply runes")
-        self.Bind(wx.EVT_BUTTON, self.applyRunes, applyBt)
-        self.resultContent.Add(applyBt)
-        closeBt = wx.Button(parent=pnl, id=-1, pos=(650, 430), size=(165, 60), style=wx.LC_REPORT, label="Close")
-        self.Bind(wx.EVT_BUTTON, self.closeWindow, closeBt)
-
-        # By default, hide everything
-        self.resultContent.ShowItems(False)
-
-    def processResults(self, jsonData):
-        """Processes data obtained from RuneOptimizer.
-
-        Reads the JSON data and initializes the property data.
-        Automatically calls printResults();
-
-        Parameters
-        ----------
-        jsonData : str
-            The data, as received from RuneOptimizer.
-
-        """
-
-        self.data = json.loads(jsonData, object_hook=lambda d: SimpleNamespace(**d))
-        self.totalPages = math.ceil(len(self.data.results) / self.linesPerPage)
-        self.printResults()
-
-    def pgPrev(self, event):
-        """Goes to the previous page of results.
-
-        Checks if there is a previous page to go to. If so, it
-        automatically calls printResults();
-
-        Parameters
-        ----------
-        event : wxEvent, optional
-            The event that triggered the call (default is None).
-
-        """
-
-        if self.page > 0:
-            self.page -= 1
-            self.printResults()
-
-    def pgNext(self, event):
-        """Goes to the next page of results.
-
-        Checks if there is a next page to go to. If so, it
-        automatically calls printResults();
-
-        Parameters
-        ----------
-        event : wxEvent, optional
-            The event that triggered the call (default is None).
-
-        """
-
-        if self.page < self.totalPages:
-            self.page += 1
-            self.printResults()
-
-    def closeWindow(self, event):
-        """Closes the window.
-
-        Parameters
-        ----------
-        event : wxEvent, optional
-            The event that triggered the call (default is None).
-
-        """
-
-        self.Close(True)
-
-    def applyRunes(self, event):
-        """Applies the selected results and saves data to the database.
-
-        Parameters
-        ----------
-        event : wxEvent, optional
-            The event that triggered the call (default is None).
-
-        """
-
-        global conn
-
-        if (self.selectedResultIndex < 0):
-            # TODO: Show error
-            return;
-        print("self.selectedResultIndex: " + str(self.selectedResultIndex))
-        for i in range(0, 6):
-            print(self.data.results[self.selectedResultIndex].runes[i])
-        # First, unassign all runes currently assigned to the unit
-        cursor = conn.execute(
-          """
-            UPDATE runes SET unit = null
-            WHERE unit = ?
-          """,
-          (
-            self.unitId,
-          )
-        )
-
-        # Next, mark units as modified
-        cursor = conn.execute(
-          """
-            UPDATE units SET modified = 1
-            WHERE id = ? OR id IN (SELECT unit FROM runes WHERE id IN (?, ?, ?, ?, ?, ?))
-          """,
-          (
-            self.unitId,
-            self.data.results[self.selectedResultIndex].runes[0],
-            self.data.results[self.selectedResultIndex].runes[1],
-            self.data.results[self.selectedResultIndex].runes[2],
-            self.data.results[self.selectedResultIndex].runes[3],
-            self.data.results[self.selectedResultIndex].runes[4],
-            self.data.results[self.selectedResultIndex].runes[5]
-          )
-        )
-
-        # Lastly, assign the runes
-        cursor = conn.execute(
-          """
-            UPDATE runes SET unit = ?
-            WHERE id IN (?, ?, ?, ?, ?, ?)
-          """,
-          (
-            self.unitId,
-            self.data.results[self.selectedResultIndex].runes[0],
-            self.data.results[self.selectedResultIndex].runes[1],
-            self.data.results[self.selectedResultIndex].runes[2],
-            self.data.results[self.selectedResultIndex].runes[3],
-            self.data.results[self.selectedResultIndex].runes[4],
-            self.data.results[self.selectedResultIndex].runes[5]
-          )
-        )
-        conn.commit()
-        # TODO: Recalculate all modified units stats from the database
-        print("Applied!")
-        recalculteStatsOfModifiedUnits()
-        print("All recalculated!")
-
-        # Fetch the new values for self.currentStats
-        cursor = conn.execute(
-          """
-            SELECT
-              current_hp,
-              current_atk,
-              current_def,
-              current_spd,
-              current_crr,
-              current_crd,
-              current_res,
-              current_acc
-            FROM units
-            WHERE id = ?
-          """,
-          (
-            self.unitId,
-          )
-        )
-        row = cursor.fetchone()
-        for i in range(0, 8):
-            self.currentStats[i] = int(row[i])
-        self.currentStats[9] = math.ceil((((self.currentStats[2] * 3.5) + 1140) * self.currentStats[0]) / 1000)
-        self.currentStats[10] = math.ceil((self.currentStats[1] * (100 - self.currentStats[4]) / 100) + ((self.currentStats[1] + (self.currentStats[1] * self.currentStats[5] / 100)) * self.currentStats[4] / 100));
-        self.resultSelected(None)
-
-    def printResults(self):
-        """Populates the results table with the results in the
-        currently selected page.
-
-        It doesn't change the selcted result. Automaticcaly called
-        after changing pages or processing data.
-        """
-
-        self.pgPrevBt.Enable(True)
-        self.pgNextBt.Enable(True)
-        if self.totalPages == 1:
-            self.pgPrevBt.Enable(False)
-            self.pgNextBt.Enable(False)
-        elif self.page == 0:
-            self.pgPrevBt.Enable(False)
-        elif self.page + 1 == self.totalPages:
-            self.pgNextBt.Enable(False)
-        self.resultsPageIndicator.SetLabel(str(self.page + 1) + "/" + str(self.totalPages))
-        #for result in self.data.results:
-        for i in range(0, 10):
-            rindex = i + (self.linesPerPage * self.page)
-            if (len(self.data.results) > rindex):
-                self.resultGrid.SetRowLabelValue(row=i, value=str(rindex + 1))
-                result = self.data.results[rindex]
-                self.resultGrid.SetCellValue(row=i, col=0, s=str(result.rating))
-                self.resultGrid.SetCellValue(row=i, col=1, s=str(result.hp))
-                self.resultGrid.SetCellValue(row=i, col=2, s=str(result.atk))
-                self.resultGrid.SetCellValue(row=i, col=3, s=str(result.dfc))
-                self.resultGrid.SetCellValue(row=i, col=4, s=str(result.spd))
-                self.resultGrid.SetCellValue(row=i, col=5, s=str(result.crr))
-                self.resultGrid.SetCellValue(row=i, col=6, s=str(result.crd))
-                self.resultGrid.SetCellValue(row=i, col=7, s=str(result.res))
-                self.resultGrid.SetCellValue(row=i, col=8, s=str(result.acc))
-                self.resultGrid.SetCellValue(row=i, col=9, s=str(result.ehp))
-                self.resultGrid.SetCellValue(row=i, col=10, s=str(result.dmg))
-            else:
-                self.resultGrid.SetRowLabelValue(row=i, value="")
-                for j in range(0, 11):
-                    self.resultGrid.SetCellValue(row=i, col=j, s="")
-
-    def resultSelected(self, event):
-        """Populates and shows the runes and effective stats with the
-        currently seleced result.
-
-        It also enables the apply button.
-
-        Parameters
-        ----------
-        event : wxEvent, optional
-            The event that triggered the call (default is None).
-
-        """
-
-        selectedLine = self.resultGrid.GetSelectedRows()[0]
-        self.selectedResultIndex = selectedLine + (self.linesPerPage * self.page)
-        self.statGrid.SetCellValue(row=0, col=0, s=str(self.data.results[self.selectedResultIndex].hp) + " ")
-        diff = self.data.results[self.selectedResultIndex].hp - self.currentStats[0]
-        if (diff < 0):
-            self.statGrid.SetCellValue(row=0, col=1, s="- " + str(abs(diff)) + " ")
-            self.statGrid.SetCellTextColour(row=0, col=1, colour=wx.Colour(red=255, green=0, blue=0))
-        elif (diff > 0):
-            self.statGrid.SetCellValue(row=0, col=1, s="+ " + str(diff) + " ")
-            self.statGrid.SetCellTextColour(row=0, col=1, colour=wx.Colour(red=0, green=255, blue=0))
-        else:
-            self.statGrid.SetCellValue(row=0, col=1, s="")
-
-        self.statGrid.SetCellValue(row=1, col=0, s=str(self.data.results[self.selectedResultIndex].atk) + " ")
-        diff = self.data.results[self.selectedResultIndex].atk - self.currentStats[1]
-        if (diff < 0):
-            self.statGrid.SetCellValue(row=1, col=1, s="- " + str(abs(diff)) + " ")
-            self.statGrid.SetCellTextColour(row=1, col=1, colour=wx.Colour(red=255, green=0, blue=0))
-        elif (diff > 0):
-            self.statGrid.SetCellValue(row=1, col=1, s="+ " + str(diff) + " ")
-            self.statGrid.SetCellTextColour(row=1, col=1, colour=wx.Colour(red=0, green=255, blue=0))
-        else:
-            self.statGrid.SetCellValue(row=1, col=1, s="")
-
-        self.statGrid.SetCellValue(row=2, col=0, s=str(self.data.results[self.selectedResultIndex].dfc) + " ")
-        diff = self.data.results[self.selectedResultIndex].atk - self.currentStats[2]
-        if (diff < 0):
-            self.statGrid.SetCellValue(row=2, col=1, s="- " + str(abs(diff)) + " ")
-            self.statGrid.SetCellTextColour(row=1, col=1, colour=wx.Colour(red=255, green=0, blue=0))
-        elif (diff > 0):
-            self.statGrid.SetCellValue(row=2, col=1, s="+ " + str(diff) + " ")
-            self.statGrid.SetCellTextColour(row=2, col=1, colour=wx.Colour(red=0, green=255, blue=0))
-        else:
-            self.statGrid.SetCellValue(row=2, col=1, s="")
-
-        self.statGrid.SetCellValue(row=3, col=0, s=str(self.data.results[self.selectedResultIndex].spd) + " ")
-        diff = self.data.results[self.selectedResultIndex].spd - self.currentStats[3]
-        if (diff < 0):
-            self.statGrid.SetCellValue(row=3, col=1, s="- " + str(abs(diff)) + " ")
-            self.statGrid.SetCellTextColour(row=3, col=1, colour=wx.Colour(red=255, green=0, blue=0))
-        elif (diff > 0):
-            self.statGrid.SetCellValue(row=3, col=1, s="+ " + str(diff) + " ")
-            self.statGrid.SetCellTextColour(row=3, col=1, colour=wx.Colour(red=0, green=255, blue=0))
-        else:
-            self.statGrid.SetCellValue(row=3, col=1, s="")
-
-
-        self.statGrid.SetCellValue(row=4, col=0, s=str(self.data.results[self.selectedResultIndex].crr) + "%")
-        diff = self.data.results[self.selectedResultIndex].crr - self.currentStats[4]
-        if (diff < 0):
-            self.statGrid.SetCellValue(row=4, col=1, s="- " + str(abs(diff)) + "%")
-            self.statGrid.SetCellTextColour(row=4, col=1, colour=wx.Colour(red=255, green=0, blue=0))
-        elif (diff > 0):
-            self.statGrid.SetCellValue(row=4, col=1, s="+ " + str(diff) + "%")
-            self.statGrid.SetCellTextColour(row=4, col=1, colour=wx.Colour(red=0, green=255, blue=0))
-        else:
-            self.statGrid.SetCellValue(row=4, col=1, s="")
-
-        self.statGrid.SetCellValue(row=5, col=0, s=str(self.data.results[self.selectedResultIndex].crd) + "%")
-        diff = self.data.results[self.selectedResultIndex].crd - self.currentStats[5]
-        if (diff < 0):
-            self.statGrid.SetCellValue(row=5, col=1, s="- " + str(abs(diff)) + "%")
-            self.statGrid.SetCellTextColour(row=5, col=1, colour=wx.Colour(red=255, green=0, blue=0))
-        elif (diff > 0):
-            self.statGrid.SetCellValue(row=5, col=1, s="+ " + str(diff) + "%")
-            self.statGrid.SetCellTextColour(row=5, col=1, colour=wx.Colour(red=0, green=255, blue=0))
-        else:
-            self.statGrid.SetCellValue(row=5, col=1, s="")
-
-        self.statGrid.SetCellValue(row=6, col=0, s=str(self.data.results[self.selectedResultIndex].res) + "%")
-        diff = self.data.results[self.selectedResultIndex].res - self.currentStats[6]
-        if (diff < 0):
-            self.statGrid.SetCellValue(row=6, col=1, s="- " + str(abs(diff)) + "%")
-            self.statGrid.SetCellTextColour(row=6, col=1, colour=wx.Colour(red=255, green=0, blue=0))
-        elif (diff > 0):
-            self.statGrid.SetCellValue(row=6, col=1, s="+ " + str(diff) + "%")
-            self.statGrid.SetCellTextColour(row=6, col=1, colour=wx.Colour(red=0, green=255, blue=0))
-        else:
-            self.statGrid.SetCellValue(row=6, col=1, s="")
-
-        self.statGrid.SetCellValue(row=7, col=0, s=str(self.data.results[self.selectedResultIndex].acc) + "%")
-        diff = self.data.results[self.selectedResultIndex].acc - self.currentStats[7]
-        if (diff < 0):
-            self.statGrid.SetCellValue(row=7, col=1, s="- " + str(abs(diff)) + "%")
-            self.statGrid.SetCellTextColour(row=7, col=1, colour=wx.Colour(red=255, green=0, blue=0))
-        elif (diff > 0):
-            self.statGrid.SetCellValue(row=7, col=1, s="+ " + str(diff) + "%")
-            self.statGrid.SetCellTextColour(row=7, col=1, colour=wx.Colour(red=0, green=255, blue=0))
-        else:
-            self.statGrid.SetCellValue(row=7, col=1, s="")
-
-        self.statGrid.SetCellValue(row=8, col=0, s=str(self.data.results[self.selectedResultIndex].ehp) + " ")
-        diff = self.data.results[self.selectedResultIndex].ehp - self.currentStats[8]
-        if (diff < 0):
-            self.statGrid.SetCellValue(row=8, col=1, s="- " + str(abs(diff)) + " ")
-            self.statGrid.SetCellTextColour(row=8, col=1, colour=wx.Colour(red=255, green=0, blue=0))
-        elif (diff > 0):
-            self.statGrid.SetCellValue(row=8, col=1, s="+ " + str(diff) + " ")
-            self.statGrid.SetCellTextColour(row=8, col=1, colour=wx.Colour(red=0, green=255, blue=0))
-        else:
-            self.statGrid.SetCellValue(row=8, col=1, s="")
-
-        self.statGrid.SetCellValue(row=9, col=0, s=str(self.data.results[self.selectedResultIndex].dmg) + " ")
-        diff = self.data.results[self.selectedResultIndex].dmg - self.currentStats[9]
-        if (diff < 0):
-            self.statGrid.SetCellValue(row=9, col=1, s="- " + str(abs(diff)) + " ")
-            self.statGrid.SetCellTextColour(row=9, col=1, colour=wx.Colour(red=255, green=0, blue=0))
-        elif (diff > 0):
-            self.statGrid.SetCellValue(row=9, col=1, s="+ " + str(diff) + " ")
-            self.statGrid.SetCellTextColour(row=9, col=1, colour=wx.Colour(red=0, green=255, blue=0))
-        else:
-            self.statGrid.SetCellValue(row=9, col=1, s="")
-
-        self.resultContent.ShowItems(True)
-
-        # Clean the runes
-        for i in range(0, 5):
-            self.runeIds[i].SetLabel("")
-            self.runeLocations[i].SetLabel("")
-            self.runeSets[i].SetLabel("")
-            self.runeMains[i].SetLabel("")
-            self.runeInnates[i].SetLabel("")
-            for j in range(0, 3):
-                self.runeStats[i][j].SetLabel("")
-
-        # Display the runes
-        cursor = conn.execute(
-          """
-            SELECT runes.id, runes.slot, runes.type, runes.level, units.id, units.name
-            FROM runes LEFT JOIN units ON runes.unit = units.id
-            WHERE runes.id IN (?, ?, ?, ?, ?, ?)
-            ORDER BY runes.slot;
-          """,
-          (
-            self.data.results[self.selectedResultIndex].runes[0],
-            self.data.results[self.selectedResultIndex].runes[1],
-            self.data.results[self.selectedResultIndex].runes[2],
-            self.data.results[self.selectedResultIndex].runes[3],
-            self.data.results[self.selectedResultIndex].runes[4],
-            self.data.results[self.selectedResultIndex].runes[5]
-          )
-        )
-        i = 0
-        for row in cursor:
-            # Rows are 21 charactes width
-            self.runeIds[i].SetLabel(("#" + str(row[0])).rjust(21, " "))
-            if row[4] == None:
-                self.runeLocations[i].SetLabel("Storage")
-            else:
-                self.runeLocations[i].SetLabel(str(row[5])[0:9].ljust(9, " ") + " #" + str(row[4]) + "")
-            self.runeSets[i].SetLabel(set_names[row[2]].ljust(18, " ") + "+" + str(row[3]))
-            #print(self.data.results[self.selectedResultIndex].runes[i])
-            cursorStats = conn.execute(
-              """
-                SELECT
-                  slot, stat, value, grind, enchant
-                FROM rune_stats
-                WHERE
-                  rune = ?
-                ORDER BY slot;
-              """,
-              (self.data.results[self.selectedResultIndex].runes[i],)
-            )
-            for rowStats in cursorStats:
-                slot = rowStats[0]
-                if rowStats[4] == 1: # if enchanted
-                    name = (stat_names[rowStats[1]].replace("%", "").replace(" ", "") + " * ").rjust(8, " ")
-                else:
-                    name = (stat_names[rowStats[1]].replace("%", "").replace(" ", "") + "   ").rjust(8, " ")
-                value = str(rowStats[2])
-                if rowStats[1] in [2, 4, 6, 9, 10, 11, 23]:
-                    value = value + "%"
-                else:
-                    value = value + " "
-                value = value.rjust(5)
-                if rowStats[3] > 0: # if grinded
-                    value = value + "  + " + str(rowStats[3])
-                    if rowStats[1] in [2, 4, 6, 9, 10, 11, 23]:
-                        value = value + "%"
-                line = name + value
-                if slot == -1: # main
-                    self.runeMains[i].SetLabel(line)
-                elif slot == 0: # innate
-                    self.runeInnates[i].SetLabel(line)
-                else: # normal stats
-                    self.runeStats[i][slot - 1].SetLabel(line)
-            i += 1

+ 6 - 70
src/RuneOptimizerGUI/classes/RuneOptimizerFrame.py

@@ -20,54 +20,8 @@ class RuneOptimizerFrame(wx.Frame):
     """
     """
     The main application window.
     The main application window.
 
 
-    Parameters
-    ----------
-    unitList : wx.ListCtrl
-        Selectable unit list with priorities.
-    unitContent : wx.BoxSizer
-        Holds every widget that is hidden until a unit is selected.
-    unitName : wx.StaticText
-        Label with the unit name.
-    statGrid : wx.Grid.grid
-        Table with the unit base and current stats.
-    runeList : wx.StaticText[6]
-        Labels with all the info about the currently equipped runes.
-    minStatSlider : wx.Slider[6]
-        List of sliders for the minimum selectors for each stat.
-    minStatText : wx.StaticText[6]
-        List of text inputs for the minimum selectors for each stat.
-    runeSets : wx.Choice[3]
-        List of selector to pik rune sets.
-    stats : wx.CheckListBox[2]
-        Tho selctors to choose stats allowed in optimization.
-    level : wx.Choice
-        Selector to pick the level for the rune optimization.
-    currentStats : int[10]
-        The current stats of the unit being optimized. (default is
-        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).
-    filterName : wx.TextCtrl
-        Text input to filter units names.
-    filterNames : wx.CheckBox
-        Checkbox to include or exclude units in storage.
-    filterNoRunes : wx.CheckBox
-        Checkbox to include or exclude units without runes.
-    filterNoTeams : wx.CheckBox
-        Checkbox to include or exclude units in no teams.
-
     Methods
     Methods
     -------
     -------
-    processResults(jsonData)
-        Processes data obtained from RuneOptimizer.
-    populateUnitList(event)
-        Populates the unit list.
-    startOptimization(event)
-        Prepares and runs a command optimization.
-    minStatChangeBySlider(event)
-        Changes text when a slider is changed.
-    minStatChangeByTExt(event)
-        Changes the slider when the text is changed.
-    unitSelected(event)
-        Loads a unit info and enables optimizaton options.
     makeMenuBar(event)
     makeMenuBar(event)
         Creates the app menu bar.
         Creates the app menu bar.
     closeApp(event)
     closeApp(event)
@@ -75,34 +29,18 @@ class RuneOptimizerFrame(wx.Frame):
     showAbout(event)
     showAbout(event)
         Display an About dialog.
         Display an About dialog.
     updateFromJson(event)
     updateFromJson(event)
-        Updates data from a JSON file.
+        Shows a dialog to update data from a JSON file.
     updateFromSwdb(event)
     updateFromSwdb(event)
-        Updates data from a JSON file.
+        Updates data from a SWDB instance.
     updateFromSwarfarm(event)
     updateFromSwarfarm(event)
-        Updates data from a JSON file.
+        Updates data from Swarfarm.
     updateFromSqlite(event)
     updateFromSqlite(event)
-        Updates data from a JSON file.
+        Updates data from a SQLite file.
     showUnimplemented(parent, event)
     showUnimplemented(parent, event)
         Displays a message for unimplemented features.
         Displays a message for unimplemented features.
 
 
     """
     """
 
 
-    unitList = None
-    unitContent = None
-    unitName = None
-    statGrid = None
-    runeList = None
-    minStatSlid = None
-    minStatText = None
-    runeSets = None
-    stats = None
-    level = None
-    currentStats = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
-    filterName = None
-    filterStorage = None
-    filterNoRunes = None
-    filterNoTeams = None
-
     def __init__(self, *args, **kw):
     def __init__(self, *args, **kw):
         """
         """
         Initializes the class.
         Initializes the class.
@@ -217,11 +155,9 @@ class RuneOptimizerFrame(wx.Frame):
 
 
         wx.MessageBox("RuneOptimizerAbout", wx.OK | wx.ICON_INFORMATION)
         wx.MessageBox("RuneOptimizerAbout", wx.OK | wx.ICON_INFORMATION)
 
 
-    def updateFromJson(self, event):
+    def updateFromJson(self, event = None):
         """
         """
-        Updates data from a JSON file.
-
-        TODO
+        Shows a dialog to update data from a JSON file.
 
 
         Parameters
         Parameters
         ----------
         ----------

+ 16 - 2
src/RuneOptimizerGUI/classes/TabList.py

@@ -20,6 +20,17 @@ class TabList(wx.Listbook):
     """
     """
     The main menu.
     The main menu.
 
 
+    Parameters
+    ----------
+    frameUnits : PanelUnits
+        Unit details view.
+    frameTeams : PanelTeams
+        Team management view.
+    frameOptimizer : PanelOptimizer
+        Optimizer view.
+    frameResults : PanelUnits
+        Optimization results view.
+
     Methods
     Methods
     -------
     -------
     OnPageChanged(event)
     OnPageChanged(event)
@@ -34,7 +45,10 @@ class TabList(wx.Listbook):
     frameOptimizer = None
     frameOptimizer = None
     frameResults = None
     frameResults = None
 
 
-    def __init__(self, parent, id=wx.ID_ANY, pos=(0, 0), size=(800, 600), style=wx.LC_REPORT):
+    def __init__(
+      self, parent, id=wx.ID_ANY,
+      pos=(0, 0), size=(800, 600), style=wx.LC_REPORT
+    ):
         """
         """
         Initializes the tablist.
         Initializes the tablist.
 
 
@@ -74,7 +88,7 @@ class TabList(wx.Listbook):
           type=wx.BITMAP_TYPE_BMP
           type=wx.BITMAP_TYPE_BMP
         )
         )
         il.Add(bmp)
         il.Add(bmp)
-        self.AssignImageList(il)
+         .AssignImageList(il)
 
 
         # Create the entries
         # Create the entries
         self.frameUnits = PanelUnits(self)
         self.frameUnits = PanelUnits(self)

二進制
src/RuneOptimizerGUI/res/icon/progress.gif