You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

671 lines
30 KiB

#include "TabbedComponent.h"
#include "DocumentComponent.h"
#include "InputComponent.h"
#include "BoxComponent.h"
#include <iostream>
TabbedComponent::TabbedComponent(const float rawX, const float rawY, const float rawWidth, const float rawHeight, const int passedWindowWidth, const int passedWindowHeight) : MultiComponent(rawX, rawY, rawWidth, rawHeight, passedWindowWidth, passedWindowHeight) {
// picking flag
tabbed = true;
// make 2 multiComponents
// put into rootDOM
// one for the document
// one for the tab UI
// make sure boxes & text for document is draw first
// then draw on top:
// 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, this->tabAddColor, passedWindowWidth, passedWindowHeight);
addNewBox->name = "addNewTab";
// needs to be adjust when our parent is adjusted...
// pre-layout
addNewBox->uiControl.x = { 0 , static_cast<int>(x) }; // 0
addNewBox->uiControl.y = { 100, -96 - static_cast<int>(y) }; // height - 96px
addNewBox->uiControl.w = { 0 , 32 }; // 32px
addNewBox->uiControl.h = { 0 , 32 }; // 32px
addNewBox->boundToPage = false;
addNewBox->onClick = [this]() {
//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->tabAddHoverColor);
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) {
//std::cout << "TabbedComponent::addTab - windowSize: " << windowWidth << "x" << windowHeight << std::endl;
auto tabId = ++tabCounter; // always increasing
std::cout << "TabbedComponent::addTab - new tabId: " << tabId << std::endl;
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, this->tabTextColor, windowWidth, windowHeight);
size_t textWidth = 0;
newTabTitle->win = this->win;
std::unique_ptr<sizeResponse> textInfo = newTabTitle->size();
if (textInfo) {
textWidth = static_cast<size_t>(textInfo->width);
//std::cout << "tab text width: " << textWidth << std::endl;
}
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::shared_ptr<Tab>>::iterator it = this->tabs.begin(); it!=this->tabs.end(); ++it) {
startX += it->get()->w;
}
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, 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, 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);
rootComponent->children.push_back(newTabBox);
newTab->selectorBox = newTabBox;
newTabTitle->x = newTab->x + 5;
newTabTitle->y = -73;
newTabTitle->uiControl.x = { 0 , newTab->x + 5 }; // 0
newTabTitle->uiControl.y = { 0 , -73 }; // height - 73px
newTabTitle->uiControl.w = { 0 , static_cast<int>(textWidth) }; // textWidth
newTabTitle->uiControl.h = { 0 , 12 }; // 12px
newTabTitle->resize(windowWidth, windowHeight); // rasterize
newTabTitle->name = "add new tab label";
newTabTitle->boundToPage = false;
// add to component tree
newTabTitle->setParent(rootComponent);
rootComponent->children.push_back(newTabTitle);
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, 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
closeTabBox->uiControl.h = { 0 , 32 }; // 32px
closeTabBox->name = "tabCloseBox";
closeTabBox->boundToPage = false;
closeTabBox->onClick = [this, tabId]() {
//std::cout << "close tab " << tabId << std::endl;
this->removeTab(tabId);
};
closeTabBox->onMouseover = [closeTabBox, this]() {
//std::cout << "closeTabBox->onMouseover" << std::endl;
closeTabBox->changeColor(this->tabCloseHoverColor);
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
closeTabBox->setParent(rootComponent);
rootComponent->children.push_back(closeTabBox);
// build empty document
std::shared_ptr<DocumentComponent> docComponent = std::make_shared<DocumentComponent>(0, 0, windowWidth, windowHeight, windowWidth, windowHeight);
docComponent->name = "TabX docComponent";
docComponent->win = this->win;
docComponent->boundToPage = false;
docComponent->onBeforeLoad=[this](std::string url) {
//std::cout << "tabbedComponent::addTab:::docComponent->onBeforeLoad - fire" << std::endl;
// if we're in a tab
if (this->mpSelectedTab) {
// set tab
TextComponent *textComponent = this->mpSelectedTab->titleBox.get();
if (textComponent) {
// similar to loadDomIntoTab
textComponent->text = url;
textComponent->wrap();
// recalc what that just did to our fellow tabs
this->layoutTabs(this->selectedTab, 0);
this->selectedTab->get()->history->pushState(nullptr, url, url);
}
} else {
std::cout << "tabbedComponent::addTab:::docComponent->onBeforeLoad - document component but no tab selected" << std::endl;
// but we're loading into a specific tab, we have a doc component...
if (!this->tabs.size()) {
std::cout << "tabbedComponent::addTab:::docComponent->onBeforeLoad - document component but no tabs!" << std::endl;
}
}
// set address bar
InputComponent *ab = dynamic_cast<InputComponent*>(this->win->addressComponent.get());
if (ab) {
ab->setValue(url);
ab->updateText();
} else {
std::cout << "No address component" << std::endl;
}
this->updateWindowState(url);
};
// set up position and resize info
docComponent->y = -96; // our bar
docComponent->uiControl.x = { 0, 0 }; // 0
docComponent->uiControl.y = { 0, -96 }; // -96px
docComponent->uiControl.w = { 100, 0 }; // 100%
docComponent->uiControl.h = { 100, -96 }; // 100% - 96px
// adjust rootComponent based on y
docComponent->rootComponent->name = "root of doc";
docComponent->rootComponent->y = docComponent->y;
// don't attach this component to our root, yet...
// 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;
std::shared_ptr<DocumentComponent> p_docComponent = std::static_pointer_cast<DocumentComponent>(this->documentComponent);
if (p_docComponent) {
// now tell it to navigate somewhere
p_docComponent->navTo(goToURL.toString());
}
//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;
//renderDirty = true;
win->renderDirty = true;
// also update the new picking system
// likely won need to do this because the addTab never moves
//this->updateMouse();
}
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->setValue(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;
// I'm not sure we need this
/*
DocumentComponent *docComponent = dynamic_cast<DocumentComponent*>(this->documentComponent.get());
if (docComponent) {
docComponent->currentURL = newTitle;
}
*/
//}
// 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) {
return it;
}
}
return this->tabs.end();
}
void TabbedComponent::selectTab(std::shared_ptr<Tab> tab) {
//std::cout << "TabbedComponent::selectTab - select tab " << tabId << std::endl;
// locate tab
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;
}
if (newTab->get() == nullptr) {
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
// swap contents with document components
// remove from our children
std::vector<std::shared_ptr<Component>>::iterator it2;
it2 = std::find(this->rootComponent->children.begin(), this->rootComponent->children.end(), this->documentComponent);
if ( it2 != this->rootComponent->children.end() ) {
//std::cout << "Found old contents" << std::endl;
// FIXME: cast to doccomp and setDOM to null to make sure its clean
it2->get()->parent = nullptr;
this->rootComponent->children.erase(it2);
}
//std::cout << "adding new contents" << std::endl;
// select new document
this->rootComponent->children.push_back(tab->contents);
tab->contents->setParent(this->rootComponent);
// resize this content incase the window was resized since last selection
if (tab->contents->windowWidth != this->windowWidth || tab->contents->windowHeight != this->windowHeight) {
std::cout << "detected resize, resizing tab's doc component" << std::endl;
tab->contents->resize(this->windowWidth, this->windowHeight);
}
this->documentComponent = tab->contents;
InputComponent *ab = dynamic_cast<InputComponent*>(this->win->addressComponent.get());
if (ab) {
ab->setValue(tab->titleBox->text);
//std::cout << "tab->titleBox->text: " << tab->titleBox->text << std::endl;
if (ab->getValue() == "New Tab") {
ab->setValue("http://"); // should be "" but we don't have an awesome-bar yet
}
ab->updateText();
} else {
std::cout << "TabbedComponent::selectTab - 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;
//std::cout << "TabbedComponent::selectTab - selector found: " << found << 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);
}
// if we had something selected
// make sure we didn't just reselect ourself
//if (this->selectedTabId != newTab->get()->id) {
if (this->mpSelectedTab && 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);
} else {
if (this->tabs.size()) {
std::cout << "TabbedComponent::selectTab - Can't find selectorBox for tab" << std::endl;
}
}
}
// make sure we're the selected one
this->selectedTab = this->getTab(tab->id); // iterator
this->selectedTabId = tab->id; // integer
// doesn't move, will this double free?
this->mpSelectedTab = tab; // pointer
if (ab) {
this->updateWindowState(ab->getValue());
} else {
std::cout << "TabbedComponent::selectTab - cant update window no address bar" << std::endl;
}
}
// 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 = tab->get()->titleBox.get();
if (!textComponent) {
std::cout << "TabbedComponent::layoutTab - 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 << "TabbedComponent::layoutTab - 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 << "TabbedComponent::layoutTab - 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<sizeResponse> textInfo = textComponent->size();
if (textInfo) {
textWidthWPad = textInfo->width;
//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;
}
docComponent->setDOM(newRoot);
if (this->selectedTab == this->tabs.end()) {
std::cout << "TabbedComponent::loadDomIntoTab - No current tab selected" << std::endl;
return;
}
if (this->tabs.size() == 0) {
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;
return;
}
textComponent->text = newTitle;
textComponent->wrap();
int textWidth = 0;
std::unique_ptr<std::pair<int, int>> textInfo = textComponent->size();
if (textInfo) {
textWidth = textInfo->first;
//std::cout << "tab text width: " << textWidth << std::endl;
}
textWidth += 10; // 5px padding each side
// update width
this->selectedTab->get()->w = static_cast<size_t>(textWidth) + 32; // selector Box (text + padding) + close Box
// need to update selectorBox's width
this->selectedTab->get()->selectorBox->width = textWidth;
// need to update the uiControl
this->selectedTab->get()->selectorBox->uiControl.w = { 0, textWidth }; //
this->selectedTab->get()->selectorBox->resize(windowWidth, windowHeight); // apply new width
// need to move all tabs after this one
this->selectedTab->get()->closeBox->x = this->selectedTab->get()->x + static_cast<int>(this->selectedTab->get()->w) - 32;
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);
}
//FIXME: make sure we update window's ptrs, we can't have documentComponent not pointing to nullptr when there's no tabs
void TabbedComponent::removeTab(size_t tabId) {
// find tabId
bool found = false;
size_t widthToRemove = 0;
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
std::vector<std::shared_ptr<Component>>::iterator it2;
it2 = std::find(this->rootComponent->children.begin(), this->rootComponent->children.end(), it->get()->selectorBox);
if ( it2 != this->rootComponent->children.end() ) {
//std::cout << "found our select component in parent tree" << std::endl;
it2->get()->parent = nullptr;
this->rootComponent->children.erase(it2);
}
it2 = std::find(this->rootComponent->children.begin(), this->rootComponent->children.end(), it->get()->closeBox);
if ( it2 != this->rootComponent->children.end() ) {
//std::cout << "found our close component in parent tree" << std::endl;
it2->get()->parent = nullptr;
this->rootComponent->children.erase(it2);
}
it2 = std::find(this->rootComponent->children.begin(), this->rootComponent->children.end(), it->get()->titleBox);
if ( it2 != this->rootComponent->children.end() ) {
//std::cout << "found our titleBox component in parent tree" << std::endl;
it2->get()->parent = nullptr;
this->rootComponent->children.erase(it2);
}
it2 = std::find(this->rootComponent->children.begin(), this->rootComponent->children.end(), it->get()->contents);
if ( it2 != this->rootComponent->children.end() ) {
//std::cout << "found our document component in parent tree" << std::endl;
DocumentComponent *docComponent = dynamic_cast<DocumentComponent*>(it2->get());
if (docComponent) {
// unload components
docComponent->setDOM(std::make_shared<Node>(NodeType::ROOT));
} else {
std::cout << "TabbedComponent::removeTab - our contents aren't a document component" << std::endl;
}
it2->get()->parent = nullptr;
this->rootComponent->children.erase(it2);
}
// remove tab
widthToRemove = it->get()->w;
// are we the selected tab
if (this->selectedTab == it) {
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;
pSelectedTab = this->tabs[1];
}
this->selectTab(pSelectedTab);
}
}
it->get()->contents.reset(); // nuke document
//it->reset(); // free memory before losing track of it
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) {
// create empty document
//docComponent->domRootNode = std::make_shared<Node>(NodeType::ROOT);
//docComponent->domDirty = true;
//docComponent->rootComponent = std::make_shared<Component>();
//docComponent->rootComponent->name = "rootComponent";
// properly clean up the DOM Tree
docComponent->setDOM(std::make_shared<Node>(NodeType::ROOT));
}
//this->documentComponent = nullptr;
}
found = true;
if (it == this->tabs.end()) break;
}
// we need to move (relayout) all remove tabs after this id
if (found) {
//std::cout << "TabbedComponent::removeTab - Need to adjust: " << it->get()->id << std::endl;
it->get()->titleBox->x -= widthToRemove;
it->get()->titleBox->resize(windowWidth, windowHeight); // TextComponent, need a resize() to move vertices
it->get()->selectorBox->x -= widthToRemove;
it->get()->selectorBox->resize(windowWidth, windowHeight); // BoxComponent, need a resize() to move vertices
it->get()->closeBox->x -= widthToRemove;
it->get()->closeBox->resize(windowWidth, windowHeight); // BoxComponent, need a resize() to move vertices
}
}
//this->renderDirty = true;
this->win->renderDirty = true;
// also update the new picking system
this->updateMouse();
}