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