diff --git a/specter/include/Specter/Button.hpp b/specter/include/Specter/Button.hpp index 1ce5fd5b7..8a4d2f052 100644 --- a/specter/include/Specter/Button.hpp +++ b/specter/include/Specter/Button.hpp @@ -81,6 +81,7 @@ public: void init(boo::IGraphicsDataFactory* factory, const IThemeData& theme); }; + ~Button() {closeMenu({});} Button(ViewResources& res, View& parentView, IButtonBinding* controlBinding, const std::string& text, Style style=Style::Block, RectangleConstraint constraint=RectangleConstraint()); @@ -92,6 +93,7 @@ public: void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseMove(const boo::SWindowCoord&); void mouseLeave(const boo::SWindowCoord&); + void think(); void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub); void draw(boo::IGraphicsCommandQueue* gfxQ); @@ -102,6 +104,9 @@ public: int nominalWidth() const {return m_nomWidth;} int nominalHeight() const {return m_nomHeight;} + void closeMenu(const boo::SWindowCoord& coord); + ViewChild>& getMenu() {return m_modalMenu;} + void setMultiplyColor(const Zeus::CColor& color) { View::setMultiplyColor(color); diff --git a/specter/include/Specter/Menu.hpp b/specter/include/Specter/Menu.hpp index 42aa1056a..1b6028f1d 100644 --- a/specter/include/Specter/Menu.hpp +++ b/specter/include/Specter/Menu.hpp @@ -24,22 +24,40 @@ class Menu : public View std::unique_ptr m_subMenu; std::unique_ptr m_headText; - int m_cWidth, m_cHeight; + int m_cWidth, m_cHeight, m_cTop; - SolidShaderVert m_verts[16]; + SolidShaderVert m_verts[8]; VertexBufferBinding m_vertsBinding; + void setVerts(int width, int height); struct ContentView : View { - ContentView(ViewResources& res, Menu& menu) : View(res, menu) {} + Menu& m_menu; + ContentView(ViewResources& res, Menu& menu); + + boo::SWindowRect m_scissorRect; + SolidShaderVert m_hlVerts[4]; + VertexBufferBinding m_hlVertsBinding; + + size_t m_highlightedItem = -1; + void setHighlightedItem(size_t idx); + void unsetHighlightedItem(size_t idx) + { + if (m_highlightedItem == idx) + setHighlightedItem(-1); + } void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseMove(const boo::SWindowCoord&); void mouseLeave(const boo::SWindowCoord&); - void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub); + void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, + const boo::SWindowRect& scissor); void draw(boo::IGraphicsCommandQueue* gfxQ); + + int nominalWidth() const {return m_menu.m_cWidth;} + int nominalHeight() const {return m_menu.m_cHeight;} }; std::unique_ptr m_content; ViewChild> m_scroll; @@ -48,12 +66,16 @@ class Menu : public View { Menu& m_menu; std::unique_ptr m_textView; - ItemView(ViewResources& res, Menu& menu, const std::string& text); + size_t m_idx; + ItemView(ViewResources& res, Menu& menu, const std::string& text, size_t idx); void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseEnter(const boo::SWindowCoord&); void mouseLeave(const boo::SWindowCoord&); + + void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub); + void draw(boo::IGraphicsCommandQueue* gfxQ); }; std::vector>> m_items; @@ -69,6 +91,7 @@ public: void mouseLeave(const boo::SWindowCoord&); void scroll(const boo::SWindowCoord&, const boo::SScrollDelta&); + void think(); void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub); void draw(boo::IGraphicsCommandQueue* gfxQ); }; diff --git a/specter/include/Specter/RootView.hpp b/specter/include/Specter/RootView.hpp index 256c6cecc..30c50067d 100644 --- a/specter/include/Specter/RootView.hpp +++ b/specter/include/Specter/RootView.hpp @@ -26,6 +26,7 @@ class RootView : public View ViewResources* m_viewRes; ITextInputView* m_activeTextView = nullptr; View* m_activeDragView = nullptr; + Button* m_activeMenuButton = nullptr; SplitView* m_hoverSplitDragView = nullptr; bool m_activeSplitDragView = false; @@ -82,6 +83,15 @@ public: { m_activeDragView = dragView; } + void setActiveMenuButton(Button* button) + { + m_activeMenuButton = button; + } + void unsetActiveMenuButton(Button* button) + { + if (button == m_activeMenuButton) + m_activeMenuButton = nullptr; + } void startSplitDrag(SplitView* sv, const boo::SWindowCoord& coord) { @@ -118,7 +128,7 @@ public: void resetTooltip(ViewResources& res); void displayTooltip(const std::string& name, const std::string& help); -private: +private: void _updateCursor() { if (m_spaceCornerHover) diff --git a/specter/lib/Button.cpp b/specter/lib/Button.cpp index 2a07c1e89..2bbed84fe 100644 --- a/specter/lib/Button.cpp +++ b/specter/lib/Button.cpp @@ -38,6 +38,12 @@ Button::Button(ViewResources& res, View& parentView, m_verts[4].m_color = res.themeData().button2Inactive(); for (int i=5 ; i<28 ; ++i) m_verts[i].m_color = res.themeData().button2Inactive(); + m_verts[31].m_color = rootView().themeData().button1Inactive(); + m_verts[32].m_color = rootView().themeData().button2Inactive(); + m_verts[33].m_color = rootView().themeData().button1Inactive(); + m_verts[34].m_color = rootView().themeData().button2Inactive(); + for (int i=35 ; i<39 ; ++i) + m_verts[i].m_color = res.themeData().button2Inactive(); } else { @@ -82,6 +88,10 @@ void Button::setText(const std::string& text, const Zeus::CColor& textColor) m_verts[3].m_pos.assign(width+1, 1, 0); m_verts[4].m_pos.assign(width+1, 1, 0); + m_textWidth = width; + if (m_menuStyle != IButtonBinding::MenuStyle::None) + width += 16*pf; + m_verts[5].m_pos.assign(1, height+1, 0); m_verts[6].m_pos.assign(1, height+1, 0); m_verts[7].m_pos.assign(0, height+1, 0); @@ -109,7 +119,21 @@ void Button::setText(const std::string& text, const Zeus::CColor& textColor) m_verts[26].m_pos.assign(width+1, 1, 0); m_verts[27].m_pos.assign(width+1, 0, 0); - m_textWidth = width; + int arrowX = m_textWidth + 5*pf; + int arrowY = 7*pf; + m_verts[28].m_pos.assign(arrowX + 4*pf, arrowY + 1*pf, 0); + m_verts[29].m_pos.assign(arrowX, arrowY + 5*pf, 0); + m_verts[30].m_pos.assign(arrowX + 8*pf, arrowY + 5*pf, 0); + + m_verts[31].m_pos.assign(m_textWidth+1, height+1, 0); + m_verts[32].m_pos.assign(m_textWidth+1, 1, 0); + m_verts[33].m_pos.assign(width+1, height+1, 0); + m_verts[34].m_pos.assign(width+1, 1, 0); + + m_verts[35].m_pos.assign(m_textWidth, height+1, 0); + m_verts[36].m_pos.assign(m_textWidth, 1, 0); + m_verts[37].m_pos.assign(m_textWidth+1, height+1, 0); + m_verts[38].m_pos.assign(m_textWidth+1, 1, 0); m_vertsBinding.load(m_verts, sizeof(m_verts)); } @@ -182,11 +206,10 @@ void Button::MenuTarget::setInactive() { if (m_button.m_style == Style::Block) { - m_button.m_verts[28].m_color = rootView().themeData().button1Inactive(); - m_button.m_verts[29].m_color = rootView().themeData().button2Inactive(); - m_button.m_verts[30].m_color = rootView().themeData().button1Inactive(); - m_button.m_verts[31].m_color = rootView().themeData().button2Inactive(); + m_button.m_verts[31].m_color = rootView().themeData().button1Inactive(); m_button.m_verts[32].m_color = rootView().themeData().button2Inactive(); + m_button.m_verts[33].m_color = rootView().themeData().button1Inactive(); + m_button.m_verts[34].m_color = rootView().themeData().button2Inactive(); m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts)); } else @@ -223,11 +246,10 @@ void Button::MenuTarget::setHover() { if (m_button.m_style == Style::Block) { - m_button.m_verts[28].m_color = rootView().themeData().button1Hover(); - m_button.m_verts[29].m_color = rootView().themeData().button2Hover(); - m_button.m_verts[30].m_color = rootView().themeData().button1Hover(); - m_button.m_verts[31].m_color = rootView().themeData().button2Hover(); + m_button.m_verts[31].m_color = rootView().themeData().button1Hover(); m_button.m_verts[32].m_color = rootView().themeData().button2Hover(); + m_button.m_verts[33].m_color = rootView().themeData().button1Hover(); + m_button.m_verts[34].m_color = rootView().themeData().button2Hover(); m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts)); } else @@ -264,11 +286,10 @@ void Button::MenuTarget::setPressed() { if (m_button.m_style == Style::Block) { - m_button.m_verts[28].m_color = rootView().themeData().button1Press(); - m_button.m_verts[29].m_color = rootView().themeData().button2Press(); - m_button.m_verts[30].m_color = rootView().themeData().button1Press(); - m_button.m_verts[31].m_color = rootView().themeData().button2Press(); + m_button.m_verts[31].m_color = rootView().themeData().button1Press(); m_button.m_verts[32].m_color = rootView().themeData().button2Press(); + m_button.m_verts[33].m_color = rootView().themeData().button1Press(); + m_button.m_verts[34].m_color = rootView().themeData().button2Press(); m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts)); } else @@ -307,11 +328,10 @@ void Button::MenuTarget::setDisabled() { if (m_button.m_style == Style::Block) { - m_button.m_verts[28].m_color = rootView().themeData().button1Disabled(); - m_button.m_verts[29].m_color = rootView().themeData().button2Disabled(); - m_button.m_verts[30].m_color = rootView().themeData().button1Disabled(); - m_button.m_verts[31].m_color = rootView().themeData().button2Disabled(); + m_button.m_verts[31].m_color = rootView().themeData().button1Disabled(); m_button.m_verts[32].m_color = rootView().themeData().button2Disabled(); + m_button.m_verts[33].m_color = rootView().themeData().button1Disabled(); + m_button.m_verts[34].m_color = rootView().themeData().button2Disabled(); m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts)); } else @@ -351,7 +371,8 @@ void Button::MenuTarget::mouseDown(const boo::SWindowCoord& coord, boo::EMouseBu if (m_button.m_controlBinding) { m_button.m_modalMenu.m_view = static_cast(*m_button.m_controlBinding).buildMenu(&m_button); - updateSize(); + rootView().setActiveMenuButton(&m_button); + m_button.updateSize(); } } } @@ -436,6 +457,19 @@ void Button::MenuTarget::mouseLeave(const boo::SWindowCoord& coord) setInactive(); } +void Button::closeMenu(const boo::SWindowCoord& coord) +{ + rootView().unsetActiveMenuButton(this); + m_modalMenu.m_view.reset(); + m_menuTarget.mouseMove(coord); +} + +void Button::think() +{ + if (m_modalMenu.m_view) + m_modalMenu.m_view->think(); +} + void Button::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { View::resized(root, sub); @@ -450,7 +484,23 @@ void Button::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) if (m_style == Style::Block) { - m_buttonTarget.m_view->resized(root, sub); + if (m_menuStyle == IButtonBinding::MenuStyle::None) + { + m_buttonTarget.m_view->resized(root, sub); + } + else if (m_menuStyle == IButtonBinding::MenuStyle::Primary) + { + m_menuTarget.m_view->resized(root, sub); + } + else + { + boo::SWindowRect targetRect = sub; + targetRect.size[0] = m_textWidth; + m_buttonTarget.m_view->resized(root, targetRect); + targetRect.location[0] += targetRect.size[0]; + targetRect.size[0] = 16*pf; + m_menuTarget.m_view->resized(root, targetRect); + } } else { @@ -474,7 +524,12 @@ void Button::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) } if (m_modalMenu.m_view) - m_modalMenu.m_view->resized(root, sub); + { + boo::SWindowRect menuRect = sub; + if (m_style == Style::Text) + menuRect.location[1] -= 6*pf; + m_modalMenu.m_view->resized(root, menuRect); + } } void Button::draw(boo::IGraphicsCommandQueue* gfxQ) @@ -483,7 +538,15 @@ void Button::draw(boo::IGraphicsCommandQueue* gfxQ) gfxQ->setShaderDataBinding(m_vertsBinding); gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); if (m_style == Style::Block) + { gfxQ->draw(0, 28); + if (m_menuStyle != IButtonBinding::MenuStyle::None) + { + gfxQ->draw(31, 4); + gfxQ->draw(28, 3); + gfxQ->draw(35, 4); + } + } else { gfxQ->draw(0, 4); diff --git a/specter/lib/Menu.cpp b/specter/lib/Menu.cpp index 407f7b6e7..5ef9ccd68 100644 --- a/specter/lib/Menu.cpp +++ b/specter/lib/Menu.cpp @@ -2,13 +2,16 @@ #include "Specter/RootView.hpp" #include "Specter/ViewResources.hpp" +#define ROW_HEIGHT 18 +#define ITEM_MARGIN 1 + namespace Specter { Menu::Menu(ViewResources& res, View& parentView, IMenuNode* rootNode) : View(res, parentView) { - m_vertsBinding.initSolid(res, 16, m_viewVertBlockBuf); + m_vertsBinding.initSolid(res, 8, m_viewVertBlockBuf); commitResources(res); m_headText.reset(new TextView(res, *this, res.m_mainFont)); m_scroll.m_view.reset(new ScrollView(res, *this, ScrollView::Style::ThinIndicator)); @@ -23,10 +26,9 @@ void Menu::reset(IMenuNode* rootNode) m_thisNode = rootNode; ViewResources& res = rootView().viewRes(); - for (int i=0 ; i<16 ; ++i) + for (int i=0 ; i<8 ; ++i) m_verts[i].m_color = res.themeData().tooltipBackground(); m_vertsBinding.load(m_verts, sizeof(m_verts)); - setBackground(Zeus::CColor::skBlue); m_subMenu.reset(); @@ -34,8 +36,10 @@ void Menu::reset(IMenuNode* rootNode) m_headText->typesetGlyphs(headText?*headText:"", rootView().themeData().uiText()); float pf = rootView().viewRes().pixelFactor(); + int itemAdv = (ROW_HEIGHT + ITEM_MARGIN*2) * pf; m_cWidth = m_headText->nominalWidth() + 10*pf; - m_cHeight = 22*pf; + m_cHeight = headText ? itemAdv : 0; + m_cTop = m_cHeight; size_t subCount = rootNode->subNodeCount(); m_items.clear(); @@ -52,11 +56,11 @@ void Menu::reset(IMenuNode* rootNode) if (nodeText) { - item.m_view.reset(new ItemView(res, *this, *nodeText)); + item.m_view.reset(new ItemView(res, *this, *nodeText, i)); m_cWidth = std::max(m_cWidth, int(item.m_view->m_textView->nominalWidth() + 10*pf)); } - m_cHeight += 22*pf; + m_cHeight += itemAdv; } } } @@ -64,7 +68,7 @@ void Menu::reset(IMenuNode* rootNode) Menu::Menu(ViewResources& res, View& parentView, IMenuNode* rootNode, IMenuNode* thisNode) : View(res, parentView), m_rootNode(rootNode), m_thisNode(thisNode) { - m_vertsBinding.initSolid(res, 16, m_viewVertBlockBuf); + m_vertsBinding.initSolid(res, 8, m_viewVertBlockBuf); commitResources(res); m_headText.reset(new TextView(res, *this, res.m_mainFont)); m_scroll.m_view.reset(new ScrollView(res, *this, ScrollView::Style::ThinIndicator)); @@ -72,22 +76,78 @@ Menu::Menu(ViewResources& res, View& parentView, IMenuNode* rootNode, IMenuNode* m_scroll.m_view->setContentView(m_content.get()); } -Menu::ItemView::ItemView(ViewResources& res, Menu& menu, const std::string& text) +Menu::ContentView::ContentView(ViewResources& res, Menu& menu) : View(res, menu), m_menu(menu) +{ + m_hlVertsBinding.initSolid(res, 4, m_viewVertBlockBuf); + commitResources(res); + + m_hlVerts[0].m_color = res.themeData().button1Hover(); + m_hlVerts[1].m_color = res.themeData().button2Hover(); + m_hlVerts[2].m_color = res.themeData().button1Hover(); + m_hlVerts[3].m_color = res.themeData().button2Hover(); +} + +Menu::ItemView::ItemView(ViewResources& res, Menu& menu, const std::string& text, size_t idx) +: View(res, menu), m_menu(menu), m_idx(idx) { commitResources(res); m_textView.reset(new Specter::TextView(res, *this, res.m_mainFont)); m_textView->typesetGlyphs(text, res.themeData().uiText()); } +void Menu::setVerts(int width, int height) +{ + m_verts[0].m_pos.assign(0, height-m_cTop, 0); + m_verts[1].m_pos.assign(0, 0, 0); + m_verts[2].m_pos.assign(width, height-m_cTop, 0); + m_verts[3].m_pos.assign(width, 0, 0); + + m_verts[4].m_pos.assign(0, height, 0); + m_verts[5].m_pos.assign(0, height-m_cTop, 0); + m_verts[6].m_pos.assign(width, height, 0); + m_verts[7].m_pos.assign(width, height-m_cTop, 0); + + m_vertsBinding.load(m_verts, sizeof(m_verts)); +} + +void Menu::ContentView::setHighlightedItem(size_t idx) +{ + if (idx == -1) + { + m_highlightedItem = -1; + return; + } + ViewChild>& vc = m_menu.m_items[idx]; + + if (!vc.m_view) + { + m_highlightedItem = -1; + return; + } + + m_highlightedItem = idx; + const boo::SWindowRect& bgRect = subRect(); + const boo::SWindowRect& itemRect = vc.m_view->subRect(); + int y = itemRect.location[1] - bgRect.location[1]; + + m_hlVerts[0].m_pos.assign(0, y+itemRect.size[1], 0); + m_hlVerts[1].m_pos.assign(0, y, 0); + m_hlVerts[2].m_pos.assign(itemRect.size[0], y+itemRect.size[1], 0); + m_hlVerts[3].m_pos.assign(itemRect.size[0], y, 0); + + m_hlVertsBinding.load(m_hlVerts, sizeof(m_hlVerts)); +} + void Menu::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) { - + m_scroll.mouseDown(coord, button, mod); } void Menu::ContentView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) { - + for (ViewChild>& v : m_menu.m_items) + v.mouseDown(coord, button, mod); } void Menu::ItemView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) @@ -97,12 +157,13 @@ void Menu::ItemView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton void Menu::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) { - + m_scroll.mouseUp(coord, button, mod); } void Menu::ContentView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) { - + for (ViewChild>& v : m_menu.m_items) + v.mouseUp(coord, button, mod); } void Menu::ItemView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) @@ -112,57 +173,134 @@ void Menu::ItemView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton b void Menu::mouseMove(const boo::SWindowCoord& coord) { - + m_scroll.mouseMove(coord); } void Menu::ContentView::mouseMove(const boo::SWindowCoord& coord) { - + for (ViewChild>& v : m_menu.m_items) + v.mouseMove(coord); } void Menu::ItemView::mouseEnter(const boo::SWindowCoord& coord) { - + m_menu.m_content->setHighlightedItem(m_idx); } void Menu::mouseLeave(const boo::SWindowCoord& coord) { - + m_scroll.mouseLeave(coord); } void Menu::ContentView::mouseLeave(const boo::SWindowCoord& coord) { - + for (ViewChild>& v : m_menu.m_items) + v.mouseLeave(coord); } void Menu::ItemView::mouseLeave(const boo::SWindowCoord& coord) { - + m_menu.m_content->unsetHighlightedItem(m_idx); } void Menu::scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll) { + m_scroll.scroll(coord, scroll); +} +void Menu::think() +{ + m_scroll.m_view->think(); } void Menu::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { + float pf = rootView().viewRes().pixelFactor(); boo::SWindowRect rect = sub; + rect.size[0] = m_cWidth; + if (rect.location[1] - m_cHeight < 0) + { + rect.location[1] += ROW_HEIGHT*pf; + rect.size[1] = std::min(root.size[1] - rect.location[1], m_cHeight); + } + else + { + rect.location[1] -= m_cHeight; + rect.size[1] = m_cHeight; + } + View::resized(root, rect); + m_scroll.m_view->resized(root, rect); + setVerts(rect.size[0], rect.size[1]); + + rect.location[0] += 5*pf; + rect.location[1] += rect.size[1] - (ROW_HEIGHT + ITEM_MARGIN - 5)*pf; + rect.size[0] = m_headText->nominalWidth(); + rect.size[1] = m_headText->nominalHeight(); + m_headText->resized(root, rect); } -void Menu::ContentView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) +void Menu::ContentView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, + const boo::SWindowRect& scissor) { + View::resized(root, sub); + float pf = rootView().viewRes().pixelFactor(); + m_scissorRect = scissor; + boo::SWindowRect itemRect = sub; + itemRect.size[0] = m_menu.m_cWidth; + itemRect.size[1] = ROW_HEIGHT*pf; + itemRect.location[1] += sub.size[1] - m_menu.m_cTop + ITEM_MARGIN*pf; + int itemAdv = (ROW_HEIGHT + ITEM_MARGIN*2) * pf; + for (ViewChild>& c : m_menu.m_items) + { + itemRect.location[1] -= itemAdv; + if (c.m_view) + c.m_view->resized(root, itemRect); + } +} + +void Menu::ItemView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) +{ + View::resized(root, sub); + float pf = rootView().viewRes().pixelFactor(); + boo::SWindowRect textRect = sub; + textRect.location[0] += 5*pf; + textRect.location[1] += 5*pf; + m_textView->resized(root, textRect); } void Menu::draw(boo::IGraphicsCommandQueue* gfxQ) { View::draw(gfxQ); + gfxQ->setShaderDataBinding(m_vertsBinding); + gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); + gfxQ->draw(0, 4); + m_scroll.m_view->draw(gfxQ); + gfxQ->setShaderDataBinding(m_vertsBinding); + gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); + gfxQ->draw(4, 4); + m_headText->draw(gfxQ); } void Menu::ContentView::draw(boo::IGraphicsCommandQueue* gfxQ) { View::draw(gfxQ); + gfxQ->setScissor(m_scissorRect); + if (m_highlightedItem != -1) + { + gfxQ->setShaderDataBinding(m_hlVertsBinding); + gfxQ->draw(0, 4); + } + for (ViewChild>& c : m_menu.m_items) + if (c.m_view) + c.m_view->draw(gfxQ); + gfxQ->setScissor(rootView().subRect()); +} + +void Menu::ItemView::draw(boo::IGraphicsCommandQueue* gfxQ) +{ + View::draw(gfxQ); + m_textView->draw(gfxQ); } } diff --git a/specter/lib/RootView.cpp b/specter/lib/RootView.cpp index f7de53643..657464870 100644 --- a/specter/lib/RootView.cpp +++ b/specter/lib/RootView.cpp @@ -36,6 +36,14 @@ void RootView::resized(const boo::SWindowRect& root, const boo::SWindowRect&) void RootView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) { + if (m_activeMenuButton) + { + ViewChild>& mv = m_activeMenuButton->getMenu(); + if (!mv.mouseDown(coord, button, mods)) + m_activeMenuButton->closeMenu(coord); + return; + } + if (m_hoverSplitDragView) { m_activeSplitDragView = true; @@ -51,6 +59,13 @@ void RootView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton butto void RootView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) { + if (m_activeMenuButton) + { + ViewChild>& mv = m_activeMenuButton->getMenu(); + mv.mouseUp(coord, button, mods); + return; + } + if (m_activeSplitDragView && button == boo::EMouseButton::Primary) { m_activeSplitDragView = false; @@ -84,6 +99,13 @@ SplitView* RootView::recursiveTestSplitHover(SplitView* sv, const boo::SWindowCo void RootView::mouseMove(const boo::SWindowCoord& coord) { + if (m_activeMenuButton) + { + ViewChild>& mv = m_activeMenuButton->getMenu(); + mv.mouseMove(coord); + return; + } + if (m_activeSplitDragView) { m_hoverSplitDragView->moveDragSplit(coord); @@ -150,12 +172,26 @@ void RootView::mouseEnter(const boo::SWindowCoord& coord) void RootView::mouseLeave(const boo::SWindowCoord& coord) { + if (m_activeMenuButton) + { + ViewChild>& mv = m_activeMenuButton->getMenu(); + mv.mouseLeave(coord); + return; + } + for (View* v : m_views) v->mouseLeave(coord); } void RootView::scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll) { + if (m_activeMenuButton) + { + ViewChild>& mv = m_activeMenuButton->getMenu(); + mv.scroll(coord, scroll); + return; + } + for (View* v : m_views) v->scroll(coord, scroll); }