From 4fe4b7299b9da9d023e01abc883c7262e8dc3f45 Mon Sep 17 00:00:00 2001
From: Odilitime <janesmith@airmail.cc>
Date: Tue, 22 Aug 2017 04:25:24 -0700
Subject: [PATCH] put colors in properties, hover effects, history integration
 start, updateWindowState() refactor, getTab(), layoutTab(), tab previous
 property, updateMouse()

---
 src/graphics/components/TabbedComponent.cpp | 330 +++++++++++++++++---
 src/graphics/components/TabbedComponent.h   |  31 +-
 2 files changed, 315 insertions(+), 46 deletions(-)

diff --git a/src/graphics/components/TabbedComponent.cpp b/src/graphics/components/TabbedComponent.cpp
index aa531e21..015c573a 100644
--- a/src/graphics/components/TabbedComponent.cpp
+++ b/src/graphics/components/TabbedComponent.cpp
@@ -15,7 +15,7 @@ TabbedComponent::TabbedComponent(const float rawX, const float rawY, const float
     // boxes & text for tab UI
     // or we can manually force doc components first and skipped later... sounds like a better start
     
-    std::unique_ptr<BoxComponent> addNewBox = std::make_unique<BoxComponent>(x, passedWindowHeight - 96 - y, 32, 32, 0x00FF00FF, passedWindowWidth, passedWindowHeight);
+    std::unique_ptr<BoxComponent> addNewBox = std::make_unique<BoxComponent>(x, passedWindowHeight - 96 - y, 32, 32, this->tabAddColor, passedWindowWidth, passedWindowHeight);
     addNewBox->name = "addNewTab";
     
     // needs to be adjust when our parent is adjusted...
@@ -30,9 +30,24 @@ TabbedComponent::TabbedComponent(const float rawX, const float rawY, const float
         //std::cout << "new tab" << std::endl;
         this->addTab("New Tab");
     };
+    // this will cause problems if addNewBox goes out of scope but then not events should be firing
+    BoxComponent *addBoxHandle = addNewBox.get();
+    addNewBox->onMouseover = [addBoxHandle, this]() {
+        //std::cout << "addNewBox->onMouseover" << std::endl;
+        addBoxHandle->changeColor(this->tabHoverColor);
+        this->win->renderDirty = true;
+    };
+    addNewBox->onMouseout = [addBoxHandle, this]() {
+        //std::cout << "addNewBox->onMouseout" << std::endl;
+        addBoxHandle->changeColor(this->tabAddColor);
+        this->win->renderDirty = true;
+    };
     // add to component tree
     addNewBox->setParent(rootComponent);
     rootComponent->children.push_back(std::move(addNewBox));
+    
+    // just set it to the end for now
+    this->selectedTab = this->tabs.end();
 }
 
 void TabbedComponent::addTab(std::string passedTitle) {
@@ -41,12 +56,12 @@ void TabbedComponent::addTab(std::string passedTitle) {
     auto tabId = ++tabCounter; // always increasing
     std::cout << "TabbedComponent::addTab - new tabId: " << tabId << std::endl;
         
-    std::unique_ptr<Tab> newTab=std::make_unique<Tab>();
+    std::shared_ptr<Tab> newTab=std::make_shared<Tab>();
     //newTab->title = passedTitle;
     newTab->id = tabId;
 
     //(const std::string &rawText, const int rawX, const int rawY, const unsigned int size, const bool bolded, const unsigned int hexColor, const int passedWindowWidth, const int passedWindowHeight)
-    std::shared_ptr<TextComponent> newTabTitle = std::make_shared<TextComponent>(passedTitle, 0, 0, 12, false, 0x000000FF, windowWidth, windowHeight);
+    std::shared_ptr<TextComponent> newTabTitle = std::make_shared<TextComponent>(passedTitle, 0, 0, 12, false, this->tabTextColor, windowWidth, windowHeight);
     size_t textWidth = 0;
     std::unique_ptr<std::pair<int, int>> textInfo = newTabTitle->size();
     if (textInfo) {
@@ -56,25 +71,41 @@ void TabbedComponent::addTab(std::string passedTitle) {
     textWidth += 10; // 5px padding each side
     // well we need to figure out where the last tab start
     size_t startX = x + 32; // our start + 32px for new tab button
-    for(std::vector<std::unique_ptr<Tab>>::iterator it = this->tabs.begin(); it!=this->tabs.end(); ++it) {
+    for(std::vector<std::shared_ptr<Tab>>::iterator it = this->tabs.begin(); it!=this->tabs.end(); ++it) {
         startX += it->get()->w;
     }
-    newTab->x = startX;
+    newTab->x = static_cast<int>(startX);
     newTab->w = textWidth + 32;
 
     
     //std::cout << "TabbedComponent::addTab - windowHeight: " << windowHeight << " y: " << y << std::endl;
-    std::shared_ptr<BoxComponent> newTabBox = std::make_shared<BoxComponent>(newTab->x, windowHeight - 96, newTab->w - 32, 32, 0x00FFFFFF, windowWidth, windowHeight);
+    std::shared_ptr<BoxComponent> newTabBox = std::make_shared<BoxComponent>(newTab->x, windowHeight - 96, newTab->w - 32, 32, this->tabInactiveColor, windowWidth, windowHeight);
     newTabBox->uiControl.x = { 0  ,  newTab->x }; // 0
     newTabBox->uiControl.y = { 100,  -96  }; // height - 96px
     newTabBox->uiControl.w = { 0  ,  static_cast<int>(newTab->w) - 32 }; // 32px
     newTabBox->uiControl.h = { 0  ,  32 }; // 32px
     newTabBox->name = "tabSelectorBox";
     newTabBox->boundToPage = false;
-    newTabBox->onClick = [this, tabId]() {
-        std::cout << "TabbedComponent::addTab:onClick() - select tab " << tabId << std::endl;
-        this->selectTab(tabId);
+    newTabBox->onClick = [this, newTab]() {
+        //std::cout << "TabbedComponent::addTab:onClick() - select tab " << newTab->id << std::endl;
+        this->selectTab(newTab);
+    };
+    newTabBox->onMouseover = [newTabBox, this]() {
+        //std::cout << "newTabBox->onMouseover" << std::endl;
+        newTabBox->changeColor(this->tabHoverColor);
+        this->win->renderDirty = true;
+    };
+    newTabBox->onMouseout = [newTabBox, tabId, this]() {
+        //std::cout << "newTabBox->onMouseout" << std::endl;
+        // if it an active or inactive tab
+        if (this->selectedTabId == tabId) {
+            newTabBox->changeColor(this->tabActiveColor);
+        } else {
+            newTabBox->changeColor(this->tabInactiveColor);
+        }
+        this->win->renderDirty = true;
     };
+    
     //newTab->selectorBox=std::move(newTabBox);
     // add to component tree
     newTabBox->setParent(rootComponent);
@@ -98,7 +129,7 @@ void TabbedComponent::addTab(std::string passedTitle) {
     newTab->titleBox = newTabTitle;
 
     // x + 64 * (tabs.size() + 1)
-    std::shared_ptr<BoxComponent> closeTabBox = std::make_shared<BoxComponent>(newTab->x + static_cast<int>(newTab->w) - 32, windowHeight - 96, 32, 32, 0xFF0000FF, windowWidth, windowHeight);
+    std::shared_ptr<BoxComponent> closeTabBox = std::make_shared<BoxComponent>(newTab->x + static_cast<int>(newTab->w) - 32, windowHeight - 96, 32, 32, this->tabCloseColor, windowWidth, windowHeight);
     closeTabBox->uiControl.x = { 0  ,  newTab->x + static_cast<int>(newTab->w) - 32  }; // 0
     closeTabBox->uiControl.y = { 100  ,  -96  }; // height - 96px
     closeTabBox->uiControl.w = { 0  ,  32 }; // 32px
@@ -107,9 +138,21 @@ void TabbedComponent::addTab(std::string passedTitle) {
     closeTabBox->name = "tabCloseBox";
     closeTabBox->boundToPage = false;
     closeTabBox->onClick = [this, tabId]() {
-        std::cout << "close tab " << tabId << std::endl;
+        //std::cout << "close tab " << tabId << std::endl;
         this->removeTab(tabId);
     };
+
+    closeTabBox->onMouseover = [closeTabBox, this]() {
+        //std::cout << "closeTabBox->onMouseover" << std::endl;
+        closeTabBox->changeColor(0xF00000FF);
+        this->win->renderDirty = true;
+    };
+    closeTabBox->onMouseout = [closeTabBox, this]() {
+        //std::cout << "closeTabBox->onMouseout" << std::endl;
+        closeTabBox->changeColor(this->tabCloseColor);
+        this->win->renderDirty = true;
+    };
+    
     newTab->closeBox = closeTabBox;
     //newTab->selectorBox=std::move(newTabBox);
     // add to component tree
@@ -136,35 +179,73 @@ void TabbedComponent::addTab(std::string passedTitle) {
     
     // don't need to touch dom, should be empty to start
     newTab->contents = docComponent;
+    
+    newTab->history = std::make_unique<BrowsingHistory>([this](URL const& goToURL) {
+        std::cout << "history goto " << goToURL << std::endl;
+        this->win->navTo(goToURL.toString());
+    });
+    
+    if (tabs.size()) {
+        newTab->previousTab = tabs.back();
+    } else {
+        newTab->previousTab = nullptr;
+    }
 
     tabs.push_back(std::move(newTab));
-    std::cout << "tabs: " << tabs.size() << std::endl;
+    //std::cout << "tabs: " << tabs.size() << std::endl;
     //renderDirty = true;
     win->renderDirty = true;
-}
 
-// calculate size and position for a tab
-void TabbedComponent::layoutTab(std::vector<std::unique_ptr<Tab>>::iterator tab) {
-    // find text
-    // find selector
-    // find close
-    // get text size for it's current string
-    // pad
-    // adjust ui map accordingly
-    // adjust x of text
-    // adjust x and w of selector
-    // adjust x of close
+    // also update the new picking system
+    // likely won need to do this because the addTab never moves
+    //this->updateMouse();
 }
 
-void TabbedComponent::selectTab(size_t tabId) {
-    std::cout << "TabbedComponent::selectTab - select tab " << tabId << std::endl;
+void TabbedComponent::updateWindowState(std::string newTitle) {
+    //std::cout << "TabbedComponent::updateWindowState - newTitle: " << newTitle << std::endl;
+    InputComponent *inputComponent = dynamic_cast<InputComponent*>(this->win->addressComponent.get());
+    if (inputComponent) {
+        inputComponent->value = newTitle;
+        inputComponent->updateText();
+    } else {
+        std::cout << "TabbedComponent::updateWindowState - Window addressComponent isn't an inputComponent" << std::endl;
+    }
+    // need to update currentURL for navTo
+    // if we're no tab, we have no relative point, no harm in setting http://
+    //if (ab->value!="http://") {
+    this->win->currentURL = newTitle;
+    //}
     
-    std::vector<std::unique_ptr<Tab>>::iterator newTab;
-    for(std::vector<std::unique_ptr<Tab>>::iterator it = this->tabs.begin(); it != this->tabs.end(); ++it) {
+    // redraw pls
+    this->win->renderDirty = true;
+
+    // on DOM load mouse won't be over a tab
+    // and select tab doesn't change any components
+    //this->updateMouse();
+}
+
+// because iterators invalid, this is good for a quick lookup
+std::vector<std::shared_ptr<Tab>>::iterator TabbedComponent::getTab(size_t tabId) {
+    // locate tabId
+    std::vector<std::shared_ptr<Tab>>::iterator newTab;
+    for(std::vector<std::shared_ptr<Tab>>::iterator it = this->tabs.begin(); it != this->tabs.end(); ++it) {
         if (it->get()->id == tabId) {
-            newTab = it;
+            return it;
         }
     }
+    return this->tabs.end();
+}
+
+void TabbedComponent::selectTab(std::shared_ptr<Tab> tab) {
+    //std::cout << "TabbedComponent::selectTab - select tab " << tabId << std::endl;
+    
+    // locate tabId
+    if (tab == nullptr) {
+        std::cout << "TabbedComponent::selectTab - tab is nullptr" << std::endl;
+        return;
+    }
+    /*
+    std::vector<std::shared_ptr<Tab>>::iterator newTab = this->getTab(tabId);
     if (newTab == this->tabs.end()) {
         std::cout << "tab" << tabId << " doesn't exist" << std::endl;
         return;
@@ -173,6 +254,8 @@ void TabbedComponent::selectTab(size_t tabId) {
         std::cout << "tab" << tabId << " points to null" << std::endl;
         return;
     }
+    */
+    
     //std::cout << "Found tab" << std::endl;
     
     // tab system is currently keeping component tree in memory
@@ -189,28 +272,160 @@ void TabbedComponent::selectTab(size_t tabId) {
     
     //std::cout << "adding new contents" << std::endl;
     // select new document
-    this->rootComponent->children.push_back(newTab->get()->contents);
-    newTab->get()->contents->setParent(this->rootComponent);
+    this->rootComponent->children.push_back(tab->contents);
+    tab->contents->setParent(this->rootComponent);
 
-    this->documentComponent = newTab->get()->contents;
+    this->documentComponent = tab->contents;
     
     InputComponent *ab = dynamic_cast<InputComponent*>(this->win->addressComponent.get());
-    ab->value = newTab->get()->titleBox->text;
-    if (ab->value == "New Tab") {
-        ab->value = "http://"; // should be "" but we don't have an awesome-bar yet
+    if (ab) {
+        ab->value = tab->titleBox->text;
+        //std::cout << "tab->titleBox->text: " << tab->titleBox->text << std::endl;
+        if (ab->value == "New Tab") {
+            ab->value = "http://"; // should be "" but we don't have an awesome-bar yet
+        }
+        ab->updateText();
+    } else {
+        std::cout << "Window addressComponent isnt an inputcomponent" << std::endl;
+    }
+       
+    // I can't get selectedTab to works always (tab size = 1 or 2)
+    // so we'll rely on this more complex system
+    int i=0;
+    bool found = false;
+    for(std::vector<std::shared_ptr<Tab>>::iterator it=this->tabs.begin(); it!=this->tabs.end(); ++it) {
+        if (it==this->selectedTab) {
+        //if (it->get()->id == tabId) {
+            //std::cout << "found it at " << i << std::endl;
+            found = true;
+            break;
+        }
+        i++;
+    }
+    //std::cout << "i" << i << "/" << this->tabs.size() << std::endl;
+    if (found) {
+        // was there a previously selected tab?
+        //if (this->selectedTab != this->tabs.end() && this->selectedTab != this->tabs.begin()) {
+        BoxComponent *selector = dynamic_cast<BoxComponent*>(tab->selectorBox.get());
+        if (selector) {
+            selector->changeColor(this->tabActiveColor);
+        }
+        
+        // make sure we didn't just reselect ourself
+        //if (this->selectedTabId != newTab->get()->id) {
+        if (this->mpSelectedTab != tab) {
+            selector = dynamic_cast<BoxComponent*>(this->selectedTab->get()->selectorBox.get());
+            if (selector) {
+                // reset it's color
+                selector->changeColor(this->tabInactiveColor);
+            }
+        }
+        //}
+    } else {
+        // just mark all non-active color
+        BoxComponent *selector;
+        for(std::vector<std::shared_ptr<Tab>>::iterator it=this->tabs.begin(); it!=this->tabs.end(); ++it) {
+            selector = dynamic_cast<BoxComponent*>(it->get()->selectorBox.get());
+            if (selector) {
+                // reset color
+                selector->changeColor(this->tabInactiveColor);
+            }
+        }
+        // mark selected one as active
+        selector = dynamic_cast<BoxComponent*>(tab->selectorBox.get());
+        if (selector) {
+            selector->changeColor(this->tabActiveColor);
+        }
     }
-    ab->updateText();
     
     // make sure we're the selected one
-    this->selectedTab = newTab;
+    this->selectedTab = this->getTab(tab->id); // iterator
+    this->selectedTabId = tab->id; // integer
+    // doesn't move, will this double free?
+    this->mpSelectedTab = tab; // pointer
     
-    // redraw pls
-    this->win->renderDirty = true;
+    this->updateWindowState(ab->value);
+}
+
+// we expect the tab to be set up (all components allocated)
+// calculate size and position for a tab
+// we're not going to do a full set up uiContorl, we'll expect those to be set up and just adjust them
+// but then, we can't just call this to place things where we want in the cstr... hrm..
+void TabbedComponent::layoutTab(std::vector<std::shared_ptr<Tab>>::iterator tab) {
+    std::cout << "TabbedComponent::layoutTab - id: " << tab->get()->id << std::endl;
+    // find text
+    TextComponent *textComponent = dynamic_cast<TextComponent*>(tab->get()->titleBox.get());
+    if (!textComponent) {
+        std::cout << "TabbedComponent::loadDomIntoTab - titleBox isn't a TextComponent" << std::endl;
+        return;
+    }
+    
+    // vector iterators can't go backwards
+    //std::vector<std::shared_ptr<Tab>>::iterator it = tab;
+    //--it;
+    //Tab *prev = it->get();
+    Tab *prev = tab->get()->previousTab.get();
+    if (prev == nullptr) {
+        std::cout << "relaying out first tab, no prev" << std::endl;
+        //prev = nullptr;
+        tab->get()->x = x + 32; // our start + 32px for new tab button
+    } else {
+        tab->get()->x = prev->x + static_cast<int>(prev->w);
+    }
+    std::cout << "placing tab at " << tab->get()->x << std::endl;
+    
+    // get text size for it's current string
+    // we don't always need to adjust textWidth, only on text change
+    int textWidthWPad = 0;
+    std::unique_ptr<std::pair<int, int>> textInfo = textComponent->size();
+    if (textInfo) {
+        textWidthWPad = textInfo->first;
+        //std::cout << "tab text width: " << textWidth << std::endl;
+    }
+    // pad
+    textWidthWPad += 10; // 5px padding each side
+    
+    // update tab width
+    tab->get()->w = static_cast<size_t>(textWidthWPad) + 32; // selector Box (text + padding) + close Box
+
+    // adjust ui map accordingly
+    // adjust x of text
+    textComponent->x = 5 + tab->get()->x;
+    textComponent->width = textWidthWPad - 10; // ugh textComponent should be managing this...
+    textComponent->uiControl.x = { 0, static_cast<int>(textComponent->x) };
+    textComponent->uiControl.w = { 0, static_cast<int>(textComponent->width) };
+    textComponent->resize(windowWidth, windowHeight); // apply new width
+    
+    // find selector
+    // adjust x and w of selector
+    tab->get()->selectorBox->x = tab->get()->x;
+    tab->get()->selectorBox->width = textWidthWPad;
+    // need to update the uiControl
+    tab->get()->selectorBox->uiControl.x = { 0, tab->get()->x }; // tab->get()->x
+    tab->get()->selectorBox->uiControl.w = { 0, textWidthWPad }; // textWidthWPad
+    tab->get()->selectorBox->resize(windowWidth, windowHeight); // apply new width
+    
+    // find close and adjust x
+    tab->get()->closeBox->x = tab->get()->x + static_cast<int>(tab->get()->w) - 32;
+    tab->get()->closeBox->uiControl.x = { 0, tab->get()->x + static_cast<int>(tab->get()->w) - 32 }; // note it's not our width
+    // need to update the uiControl
+    tab->get()->closeBox->resize(windowWidth, windowHeight); // apply new position
+}
+
+// maybe take in a starting tab? as tabs to left aren't affected
+void TabbedComponent::layoutTabs(std::vector<std::shared_ptr<Tab>>::iterator startTab, int xAdj) {
+    std::cout << "TabbedComponent::layoutTabs - startId: " << startTab->get()->id << " xadj: " << xAdj << std::endl;
+    // luckily only one component at a time changes, we'll need to know how much x shifted
+    for(std::vector<std::shared_ptr<Tab>>::iterator it = startTab; it!=this->tabs.end(); ++it) {
+        //it->get()->x += xAdj; // adjust position
+        this->layoutTab(it);
+    }
 }
 
 void TabbedComponent::loadDomIntoTab(std::shared_ptr<Node> newRoot, std::string newTitle) {
     DocumentComponent *docComponent = dynamic_cast<DocumentComponent*>(this->documentComponent.get());
     if (!docComponent) {
+        // FIXME: could mean no tab is selected (on "default" no tab and a tab has been created)
         std::cout << "TabbedComponent::loadDomIntoTab - 'documentComponent' isn't a DocumentComponent" << std::endl;
         return;
     }
@@ -224,13 +439,32 @@ void TabbedComponent::loadDomIntoTab(std::shared_ptr<Node> newRoot, std::string
         std::cout << "TabbedComponent::loadDomIntoTab - No tabs that can be selected" << std::endl;
         return;
     }
+    
+    // std::string const& title, URL const& url
+    // FIXME: reload, don't push on reload?
+    // if the history cursor isn't at the end, we need to replace I think and nuked everything after it
+    this->selectedTab->get()->history->pushState(nullptr, newTitle, newTitle);
+    this->selectedTab->get()->history->print();
+    
     // find our titleBox
     std::vector<std::shared_ptr<Component>>::iterator it2 = std::find(this->rootComponent->children.begin(), this->rootComponent->children.end(), this->selectedTab->get()->titleBox);
     if ( it2 == this->rootComponent->children.end() ) {
         std::cout << "TabbedComponent::loadDomIntoTab - Can't find selectedTab's titleBox in rootComponent" << std::endl;
         return;
     }
+    
     std::cout << "found our titleBox component in parent tree" << std::endl;
+    
+    // get text component
+    TextComponent *textComponent = dynamic_cast<TextComponent*>(it2->get());
+    // actually change the text
+    textComponent->text = newTitle;
+    textComponent->wrap();
+    
+    // recalc what that just did to our fellow tabs
+    this->layoutTabs(this->selectedTab, 0);
+    
+    /*
     TextComponent *textComponent = dynamic_cast<TextComponent*>(it2->get());
     if (!textComponent) {
         std::cout << "TabbedComponent::loadDomIntoTab - titleBox isn't a TextComponent" << std::endl;
@@ -261,13 +495,17 @@ void TabbedComponent::loadDomIntoTab(std::shared_ptr<Node> newRoot, std::string
     this->selectedTab->get()->closeBox->uiControl.x = { 0, this->selectedTab->get()->x + static_cast<int>(this->selectedTab->get()->w) - 32 }; // note it's not our width
     // need to update the uiControl
     this->selectedTab->get()->closeBox->resize(windowWidth, windowHeight); // apply new position
+    */
+    
+    this->updateWindowState(newTitle);
 }
 
 void TabbedComponent::removeTab(size_t tabId) {
     // find tabId
     bool found = false;
     size_t widthToRemove = 0;
-    for(std::vector<std::unique_ptr<Tab>>::iterator it = this->tabs.begin(); it!=this->tabs.end(); ++it) {
+    std::vector<std::shared_ptr<Tab>>::iterator prev = this->tabs.begin();
+    for(std::vector<std::shared_ptr<Tab>>::iterator it = this->tabs.begin(); it!=this->tabs.end(); prev = it, ++it) {
         if (it->get()->id == tabId) {
             std::cout << "TabbedComponent::removeTab - found our tab" << std::endl;
             // remove our components form the component tree
@@ -310,18 +548,23 @@ void TabbedComponent::removeTab(size_t tabId) {
                 std::cout << "TabbedComponent::removeTab - removing selected tab" << std::endl;
                 if (this->tabs.size() > 1) {
                     size_t nextTabId = this->tabs.front()->id; // grab first tab
+                    std::shared_ptr<Tab> pSelectedTab = this->tabs.front();
                     // if we are the firstTab, get the 2nd
                     if (it->get()->id == nextTabId) {
-                        nextTabId = this->tabs[1]->id;
+                        //nextTabId = this->tabs[1]->id;
+                        pSelectedTab = this->tabs[1];
                     }
-                    this->selectTab(nextTabId);
+                    this->selectTab(pSelectedTab);
                 }
             }
             it = this->tabs.erase(it);
+            it->get()->previousTab = *prev; // next tab, set it to our previous
             if (!this->tabs.size()) {
                 // no tabs left
                 std::cout << "TabbedComponent::removeTab - all tabs removed" << std::endl;
                 this->selectedTab = this->tabs.end();
+                this->selectedTabId = 0;
+                this->mpSelectedTab = nullptr;
                 // get last doc Component
                 DocumentComponent *docComponent = dynamic_cast<DocumentComponent*>(this->documentComponent.get());
                 if (docComponent) {
@@ -351,4 +594,7 @@ void TabbedComponent::removeTab(size_t tabId) {
     }
     //this->renderDirty = true;
     this->win->renderDirty = true;
+    
+    // also update the new picking system
+    this->updateMouse();
 }
diff --git a/src/graphics/components/TabbedComponent.h b/src/graphics/components/TabbedComponent.h
index 18e26868..b9404f36 100644
--- a/src/graphics/components/TabbedComponent.h
+++ b/src/graphics/components/TabbedComponent.h
@@ -7,9 +7,13 @@
 
 struct Tab {
     //std::string title;
+    // I think these could be unique_ptrs
+    // would make cleaning up a tab nice
     std::shared_ptr<TextComponent> titleBox;
+    // these could be BoxComponents
     std::shared_ptr<Component> selectorBox;
     std::shared_ptr<Component> closeBox;
+    // this can be generic
     std::shared_ptr<Component> contents;
     int x;
     int y;
@@ -23,6 +27,7 @@ struct Tab {
     std::shared_ptr<Node> domRootNode = nullptr;
     //BrowsingHistory history;
     std::unique_ptr<BrowsingHistory> history = nullptr;
+    std::shared_ptr<Tab> previousTab = nullptr;
 };
 
 // could eventually be broken into "tabSelectorComponent" and "tabViewComponent" so the selector doesn't have to be attached to the view area
@@ -30,15 +35,33 @@ class TabbedComponent : public MultiComponent {
 public:
     TabbedComponent(const float rawX, const float rawY, const float rawWidth, const float rawHeight, const int passedWindowWidth, const int passedWindowHeight);
     void addTab(std::string passedTitle);
-    void layoutTab(std::vector<std::unique_ptr<Tab>>::iterator tab);
-    void selectTab(size_t tabId);
+    void updateWindowState(std::string newTitle);
+    std::vector<std::shared_ptr<Tab>>::iterator getTab(size_t tabId);
+    void selectTab(std::shared_ptr<Tab> tab);
+    void layoutTab(std::vector<std::shared_ptr<Tab>>::iterator tab);
+    void layoutTabs(std::vector<std::shared_ptr<Tab>>::iterator startTab, int xAdj);
     void loadDomIntoTab(std::shared_ptr<Node> newRoot, std::string newTitle);
     void removeTab(size_t tabId);
-    std::vector<std::unique_ptr<Tab>> tabs;
+    std::vector<std::shared_ptr<Tab>> tabs;
+
     size_t tabCounter = 0;
-    std::vector<std::unique_ptr<Tab>>::iterator selectedTab;
+    size_t selectedTabId = 0;
+    std::shared_ptr<Tab> mpSelectedTab = nullptr; // we just want a pointer to where we want to go
+    // this sucks tbh, just phase it out
+    std::vector<std::shared_ptr<Tab>>::iterator selectedTab;
+    
     // was DocumentComponent but generalized to be more general (and compatible with Tab)
     std::shared_ptr<Component> documentComponent = nullptr;
+    
+    int tabAddColor = 0xF0F0F0FF;
+    int tabAddHoverColor = 0x008888FF;
+    int tabInactiveColor = 0x808080FF;
+    int tabHoverColor = 0x008888FF;
+    int tabActiveColor = 0x00FFFFFF;
+    int tabTextColor = 0x000000FF;
+    int tabTextHoverColor = 0x008888FF;
+    int tabCloseColor = 0x222222FF;
+    int tabCloseHoverColor = 0x008888FF;
 };
 
 #endif
-- 
GitLab