diff --git a/specter/include/Specter/FileBrowser.hpp b/specter/include/Specter/FileBrowser.hpp index 8f929e352..c537c4de6 100644 --- a/specter/include/Specter/FileBrowser.hpp +++ b/specter/include/Specter/FileBrowser.hpp @@ -21,7 +21,7 @@ class FileBrowser : public ModalWindow { FileBrowser& m_fb; size_t m_idx; - Specter::ViewChild m_button; + Specter::ViewChild> m_button; PathButton(FileBrowser& fb, ViewResources& res, size_t idx, const HECL::SystemString& str) : m_fb(fb), m_idx(idx) { @@ -34,7 +34,7 @@ class FileBrowser : public ModalWindow friend struct PathButton; std::vector m_pathButtons; - Specter::ViewChild m_fileField; + Specter::ViewChild> m_fileField; struct FileFieldBind : Specter::IStringBinding { FileBrowser& m_browser; @@ -45,8 +45,8 @@ class FileBrowser : public ModalWindow } } m_fileFieldBind; - Specter::ViewChild m_fileScroll; - Specter::ViewChild m_fileListing; + Specter::ViewChild> m_fileScroll; + Specter::ViewChild> m_fileListing; public: FileBrowser(ViewResources& res, View& parentView) diff --git a/specter/include/Specter/RootView.hpp b/specter/include/Specter/RootView.hpp index de3f53f98..9bd0e5675 100644 --- a/specter/include/Specter/RootView.hpp +++ b/specter/include/Specter/RootView.hpp @@ -28,6 +28,7 @@ class RootView : public View IViewManager& m_viewMan; ViewResources* m_viewRes; View* m_activeTextView = nullptr; + View* m_activeDragView = nullptr; DeferredWindowEvents m_events; @@ -71,7 +72,12 @@ public: if (m_activeTextView) m_activeTextView->setActive(false); m_activeTextView = textView; - textView->setActive(true); + if (textView) + textView->setActive(true); + } + void setActiveDragView(View* dragView) + { + m_activeDragView = dragView; } void resetTooltip(ViewResources& res); diff --git a/specter/include/Specter/SplitView.hpp b/specter/include/Specter/SplitView.hpp index 400285b2b..fc36b1425 100644 --- a/specter/include/Specter/SplitView.hpp +++ b/specter/include/Specter/SplitView.hpp @@ -34,13 +34,7 @@ private: updateSize(); } - struct Child - { - View* m_view = nullptr; - bool m_mouseIn = false; - bool m_mouseDown = false; - }; - Child m_views[2]; + ViewChild m_views[2]; ViewBlock m_splitBlock; boo::IGraphicsBufferD* m_splitBlockBuf; TexShaderVert m_splitVerts[4]; diff --git a/specter/include/Specter/TextField.hpp b/specter/include/Specter/TextField.hpp index a4745ed6a..6fcdec85b 100644 --- a/specter/include/Specter/TextField.hpp +++ b/specter/include/Specter/TextField.hpp @@ -24,6 +24,11 @@ class TextField : public Control size_t m_selectionCount = 0; size_t m_cursorPos = 0; size_t m_cursorFrames = 0; + size_t m_clickFrames = 15; + size_t m_clickFrames2 = 15; + + size_t m_dragStart = 0; + size_t m_dragging = 0; bool m_active = false; diff --git a/specter/include/Specter/TextView.hpp b/specter/include/Specter/TextView.hpp index 4464fd69c..60c376e44 100644 --- a/specter/include/Specter/TextView.hpp +++ b/specter/include/Specter/TextView.hpp @@ -66,6 +66,16 @@ public: RenderGlyph(int& adv, const FontAtlas::Glyph& glyph, const Zeus::CColor& defaultColor); }; + struct RenderGlyphInfo + { + uint32_t m_char; + std::pair m_dims; + int m_adv; + bool m_space = false; + + RenderGlyphInfo(uint32_t ch, int width, int height, int adv) + : m_char(ch), m_dims(width, height), m_adv(adv), m_space(iswspace(ch)) {} + }; std::vector& accessGlyphs() {return m_glyphs;} const std::vector& accessGlyphs() const {return m_glyphs;} void updateGlyphs() {m_valid = false;} @@ -88,11 +98,11 @@ public: std::pair queryGlyphDimensions(size_t pos) const; size_t reverseSelectGlyph(int x) const; int queryReverseAdvance(size_t idx) const; + std::pair queryWholeWordRange(size_t idx) const; private: std::vector m_glyphs; - std::vector> m_glyphDims; - std::vector m_glyphAdvs; + std::vector m_glyphInfo; }; } diff --git a/specter/include/Specter/Toolbar.hpp b/specter/include/Specter/Toolbar.hpp index 36fffa92a..e878c2fee 100644 --- a/specter/include/Specter/Toolbar.hpp +++ b/specter/include/Specter/Toolbar.hpp @@ -25,14 +25,7 @@ public: }; private: Position m_tbPos; - struct Child - { - View* m_view = nullptr; - bool m_mouseIn = false; - bool m_mouseDown = false; - Child(View* v) : m_view(v) {} - }; - std::vector m_children; + std::vector> m_children; ViewBlock m_tbBlock; boo::IGraphicsBufferD* m_tbBlockBuf; @@ -106,7 +99,11 @@ public: int nominalHeight() const {return m_nomHeight;} void clear() {m_children.clear();} - void push_back(View* v) {m_children.push_back(v);} + void push_back(View* v) + { + m_children.emplace_back(); + m_children.back().m_view = v; + } }; } diff --git a/specter/include/Specter/View.hpp b/specter/include/Specter/View.hpp index affbedd50..5a1c202cd 100644 --- a/specter/include/Specter/View.hpp +++ b/specter/include/Specter/View.hpp @@ -209,12 +209,12 @@ public: virtual void draw(boo::IGraphicsCommandQueue* gfxQ); }; -template +template struct ViewChild { - std::unique_ptr m_view; + ViewPtrType m_view; bool m_mouseIn = false; - bool m_mouseDown = false; + int m_mouseDown = 0; void mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) { @@ -222,10 +222,10 @@ struct ViewChild return; if (m_view->subRect().coordInRect(coord)) { - if (!m_mouseDown) + if ((m_mouseDown & 1 << int(button)) == 0) { m_view->mouseDown(coord, button, mod); - m_mouseDown = true; + m_mouseDown |= 1 << int(button); } } } @@ -234,10 +234,10 @@ struct ViewChild { if (!m_view) return; - if (m_mouseDown) + if ((m_mouseDown & 1 << int(button)) != 0) { m_view->mouseUp(coord, button, mod); - m_mouseDown = false; + m_mouseDown &= ~(1 << int(button)); } } diff --git a/specter/lib/RootView.cpp b/specter/lib/RootView.cpp index c0bbefeb0..fb474402c 100644 --- a/specter/lib/RootView.cpp +++ b/specter/lib/RootView.cpp @@ -38,6 +38,8 @@ 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_activeTextView && !m_activeTextView->subRect().coordInRect(coord)) + setActiveTextView(nullptr); if (m_view) m_view->mouseDown(coord, button, mods); } @@ -52,6 +54,8 @@ void RootView::mouseMove(const boo::SWindowCoord& coord) { if (m_view) m_view->mouseMove(coord); + if (m_activeDragView) + m_activeDragView->mouseMove(coord); boo::SWindowRect ttrect = m_rootRect; ttrect.location[0] = coord.pixel[0]; diff --git a/specter/lib/SplitView.cpp b/specter/lib/SplitView.cpp index 4d40bbefb..0b91894ed 100644 --- a/specter/lib/SplitView.cpp +++ b/specter/lib/SplitView.cpp @@ -57,7 +57,7 @@ View* SplitView::setContentView(int slot, View* view) Log.report(LogVisor::FatalError, "out-of-range slot to RootView::SplitView::setContentView"); View* ret = m_views[slot].m_view; m_views[slot].m_view = view; - m_views[slot].m_mouseDown = false; + m_views[slot].m_mouseDown = 0; m_views[slot].m_mouseIn = false; updateSize(); return ret; @@ -99,34 +99,16 @@ void SplitView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton butt return; } } - if (m_views[0].m_view && !m_views[0].m_mouseDown && - m_views[0].m_view->subRect().coordInRect(coord)) - { - m_views[0].m_view->mouseDown(coord, button, mod); - m_views[0].m_mouseDown = true; - } - if (m_views[1].m_view && !m_views[1].m_mouseDown && - m_views[1].m_view->subRect().coordInRect(coord)) - { - m_views[1].m_view->mouseDown(coord, button, mod); - m_views[1].m_mouseDown = true; - } + m_views[0].mouseDown(coord, button, mod); + m_views[1].mouseDown(coord, button, mod); } void SplitView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) { if (button == boo::EMouseButton::Primary) m_dragging = false; - if (m_views[0].m_view && m_views[0].m_mouseDown) - { - m_views[0].m_view->mouseUp(coord, button, mod); - m_views[0].m_mouseDown = false; - } - if (m_views[1].m_view && m_views[1].m_mouseDown) - { - m_views[1].m_view->mouseUp(coord, button, mod); - m_views[1].m_mouseDown = false; - } + m_views[0].mouseUp(coord, button, mod); + m_views[1].mouseUp(coord, button, mod); } void SplitView::mouseMove(const boo::SWindowCoord& coord) @@ -152,64 +134,20 @@ void SplitView::mouseMove(const boo::SWindowCoord& coord) rootView().window()->setCursor(boo::EMouseCursor::Pointer); } - if (m_views[0].m_view) - { - if (m_views[0].m_view->subRect().coordInRect(coord)) - { - if (!m_views[0].m_mouseIn) - { - m_views[0].m_view->mouseEnter(coord); - m_views[0].m_mouseIn = true; - } - m_views[0].m_view->mouseMove(coord); - } - else - { - if (m_views[0].m_mouseIn) - { - m_views[0].m_view->mouseLeave(coord); - m_views[0].m_mouseIn = false; - } - } - } - if (m_views[1].m_view) - { - if (m_views[1].m_view->subRect().coordInRect(coord)) - { - if (!m_views[1].m_mouseIn) - { - m_views[1].m_view->mouseEnter(coord); - m_views[1].m_mouseIn = true; - } - m_views[1].m_view->mouseMove(coord); - } - else - { - if (m_views[1].m_mouseIn) - { - m_views[1].m_view->mouseLeave(coord); - m_views[1].m_mouseIn = false; - } - } - } + m_views[0].mouseMove(coord); + m_views[1].mouseMove(coord); } void SplitView::mouseEnter(const boo::SWindowCoord& coord) { + m_views[0].mouseEnter(coord); + m_views[1].mouseEnter(coord); } void SplitView::mouseLeave(const boo::SWindowCoord& coord) { - if (m_views[0].m_view && m_views[0].m_mouseIn) - { - m_views[0].m_view->mouseLeave(coord); - m_views[0].m_mouseIn = false; - } - if (m_views[1].m_view && m_views[1].m_mouseIn) - { - m_views[1].m_view->mouseLeave(coord); - m_views[1].m_mouseIn = false; - } + m_views[0].mouseLeave(coord); + m_views[1].mouseLeave(coord); } void SplitView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) diff --git a/specter/lib/TextField.cpp b/specter/lib/TextField.cpp index 8a97cdac3..ae15e43eb 100644 --- a/specter/lib/TextField.cpp +++ b/specter/lib/TextField.cpp @@ -45,17 +45,17 @@ TextField::TextField(ViewResources& res, View& parentView, IStringBinding* strBi m_bVertsBuf->load(m_verts, sizeof(m_verts)); m_text.reset(new TextView(res, *this, res.m_mainFont, TextView::Alignment::Left, 1024)); - setText("Test"); + setText("ใƒ†ใ‚นใƒˆ"); } void TextField::setText(const std::string& str) { clearSelectionRange(); - auto it = str.cbegin(); - for (; it != str.cend() ; ++it) - if (*it == '\n') + UTF8Iterator it(str.cbegin()); + for (; it.iter() != str.cend() ; ++it) + if (*it.iter() == '\n') break; - m_textStr.assign(str.cbegin(), it); + m_textStr.assign(str.cbegin(), it.iter()); m_text->typesetGlyphs(m_textStr, rootView().themeData().fieldText()); } @@ -95,18 +95,49 @@ void TextField::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton butt { rootView().setActiveTextView(this); if (!m_selectionCount) - setSelectionRange(0, m_textStr.size()); + setSelectionRange(0, m_text->accessGlyphs().size()); + } + else if (m_clickFrames2 < 15) + { + setSelectionRange(0, m_text->accessGlyphs().size()); + } + else if (m_clickFrames < 15) + { + size_t startPos = m_text->reverseSelectGlyph(coord.pixel[0] - m_text->subRect().location[0]); + std::pair range = m_text->queryWholeWordRange(startPos); + setSelectionRange(range.first, range.second); + m_clickFrames2 = 0; } else - setCursorPos(m_text->reverseSelectGlyph(coord.pixel[0] - m_text->subRect().location[0])); + { + size_t startPos = m_text->reverseSelectGlyph(coord.pixel[0] - m_text->subRect().location[0]); + setCursorPos(startPos); + m_dragging |= 1 << int(button); + m_dragStart = startPos; + rootView().setActiveDragView(this); + } + m_clickFrames = 0; } void TextField::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) { + m_dragging &= ~(1 << int(button)); + if (m_dragging == 0) + rootView().setActiveDragView(nullptr); } void TextField::mouseMove(const boo::SWindowCoord& coord) { + if (m_dragging != 0) + { + size_t thisPos = m_text->reverseSelectGlyph(coord.pixel[0] - m_text->subRect().location[0]); + size_t minPos = std::min(m_dragStart, thisPos); + size_t maxPos = std::max(m_dragStart, thisPos); + if (minPos != maxPos) + setSelectionRange(minPos, maxPos-minPos); + else + setCursorPos(minPos); + } } void TextField::mouseEnter(const boo::SWindowCoord& coord) @@ -125,23 +156,26 @@ void TextField::charKeyDown(unsigned long charCode, boo::EModifierKey mods, bool { if (m_selectionCount) { - std::string newStr(m_textStr.cbegin(), m_textStr.cbegin() + m_selectionStart); + std::string newStr(m_textStr.cbegin(), (UTF8Iterator(m_textStr.cbegin()) + m_selectionStart).iter()); utf8proc_uint8_t theChar[5] = {}; utf8proc_ssize_t sz = utf8proc_encode_char(charCode, theChar); if (sz > 0) newStr += (char*)theChar; - newStr.append(m_textStr.cbegin() + m_selectionStart + m_selectionCount, m_textStr.cend()); + newStr.append((UTF8Iterator(m_textStr.cbegin()) + m_selectionStart + m_selectionCount).iter(), m_textStr.cend()); + size_t selStart = m_selectionStart; setText(newStr); + setCursorPos(selStart + 1); } else { - std::string newStr(m_textStr.cbegin(), m_textStr.cbegin() + m_cursorPos); + std::string newStr(m_textStr.cbegin(), (UTF8Iterator(m_textStr.cbegin()) + m_cursorPos).iter()); utf8proc_uint8_t theChar[5] = {}; utf8proc_ssize_t sz = utf8proc_encode_char(charCode, theChar); if (sz > 0) newStr += (char*)theChar; - newStr.append(m_textStr.cbegin() + m_cursorPos, m_textStr.cend()); + newStr.append((UTF8Iterator(m_textStr.cbegin()) + m_cursorPos).iter(), m_textStr.cend()); setText(newStr); + setCursorPos(m_cursorPos + 1); } } @@ -159,11 +193,49 @@ void TextField::specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods, boo m_cursorPos = m_selectionStart + m_selectionCount - 1; setCursorPos(m_cursorPos+1); } + else if (key == boo::ESpecialKey::Backspace) + { + if (m_selectionCount) + { + std::string newStr(m_textStr.cbegin(), (UTF8Iterator(m_textStr.cbegin()) + m_selectionStart).iter()); + newStr.append((UTF8Iterator(m_textStr.cbegin()) + m_selectionStart + m_selectionCount).iter(), m_textStr.cend()); + size_t selStart = m_selectionStart; + setText(newStr); + setCursorPos(selStart); + } + else if (m_cursorPos > 0) + { + std::string newStr(m_textStr.cbegin(), (UTF8Iterator(m_textStr.cbegin()) + (m_cursorPos-1)).iter()); + newStr.append((UTF8Iterator(m_textStr.cbegin()) + m_cursorPos).iter(), m_textStr.cend()); + setText(newStr); + setCursorPos(m_cursorPos-1); + } + } + else if (key == boo::ESpecialKey::Delete) + { + if (m_selectionCount) + { + std::string newStr(m_textStr.cbegin(), (UTF8Iterator(m_textStr.cbegin()) + m_selectionStart).iter()); + newStr.append((UTF8Iterator(m_textStr.cbegin()) + m_selectionStart + m_selectionCount).iter(), m_textStr.cend()); + size_t selStart = m_selectionStart; + setText(newStr); + setCursorPos(selStart); + } + else if (m_cursorPos < m_text->accessGlyphs().size()) + { + std::string newStr(m_textStr.cbegin(), (UTF8Iterator(m_textStr.cbegin()) + m_cursorPos).iter()); + newStr.append((UTF8Iterator(m_textStr.cbegin()) + (m_cursorPos+1)).iter(), m_textStr.cend()); + setText(newStr); + setCursorPos(m_cursorPos); + } + } } void TextField::think() { ++m_cursorFrames; + ++m_clickFrames; + ++m_clickFrames2; } void TextField::setActive(bool active) @@ -176,7 +248,7 @@ void TextField::setActive(bool active) void TextField::setCursorPos(size_t pos) { clearSelectionRange(); - m_cursorPos = std::min(pos, m_textStr.size()); + m_cursorPos = std::min(pos, m_text->accessGlyphs().size()); m_cursorFrames = 0; float pf = rootView().viewRes().pixelFactor(); @@ -191,8 +263,8 @@ void TextField::setCursorPos(size_t pos) void TextField::setSelectionRange(size_t start, size_t count) { - m_selectionStart = std::min(start, m_textStr.size()-1); - m_selectionCount = std::min(count, m_textStr.size()-m_selectionStart); + m_selectionStart = std::min(start, m_text->accessGlyphs().size()-1); + m_selectionCount = std::min(count, m_text->accessGlyphs().size()-m_selectionStart); ViewResources& res = rootView().viewRes(); float pf = res.pixelFactor(); diff --git a/specter/lib/TextView.cpp b/specter/lib/TextView.cpp index 6207d9fb7..858fb0145 100644 --- a/specter/lib/TextView.cpp +++ b/specter/lib/TextView.cpp @@ -353,10 +353,8 @@ void TextView::typesetGlyphs(const std::string& str, const Zeus::CColor& default uint32_t lCh = -1; m_glyphs.clear(); m_glyphs.reserve(str.size()); - m_glyphDims.clear(); - m_glyphDims.reserve(str.size()); - m_glyphAdvs.clear(); - m_glyphAdvs.reserve(str.size()); + m_glyphInfo.clear(); + m_glyphInfo.reserve(str.size()); int adv = 0; while (rem) @@ -379,8 +377,7 @@ void TextView::typesetGlyphs(const std::string& str, const Zeus::CColor& default if (lCh != -1) adv += DoKern(m_fontAtlas.lookupKern(lCh, glyph->m_glyphIdx), m_fontAtlas); m_glyphs.emplace_back(adv, *glyph, defaultColor); - m_glyphDims.emplace_back(glyph->m_width, glyph->m_height); - m_glyphAdvs.push_back(adv); + m_glyphInfo.emplace_back(ch, glyph->m_width, glyph->m_height, adv); lCh = glyph->m_glyphIdx; rem -= sz; @@ -423,10 +420,8 @@ void TextView::typesetGlyphs(const std::wstring& str, const Zeus::CColor& defaul uint32_t lCh = -1; m_glyphs.clear(); m_glyphs.reserve(str.size()); - m_glyphDims.clear(); - m_glyphDims.reserve(str.size()); - m_glyphAdvs.clear(); - m_glyphAdvs.reserve(str.size()); + m_glyphInfo.clear(); + m_glyphInfo.reserve(str.size()); int adv = 0; for (wchar_t ch : str) @@ -441,8 +436,7 @@ void TextView::typesetGlyphs(const std::wstring& str, const Zeus::CColor& defaul if (lCh != -1) adv += DoKern(m_fontAtlas.lookupKern(lCh, glyph->m_glyphIdx), m_fontAtlas); m_glyphs.emplace_back(adv, *glyph, defaultColor); - m_glyphDims.emplace_back(glyph->m_width, glyph->m_height); - m_glyphAdvs.push_back(adv); + m_glyphInfo.emplace_back(ch, glyph->m_width, glyph->m_height, adv); lCh = glyph->m_glyphIdx; @@ -514,12 +508,12 @@ void TextView::draw(boo::IGraphicsCommandQueue* gfxQ) std::pair TextView::queryGlyphDimensions(size_t pos) const { - if (pos >= m_glyphDims.size()) + if (pos >= m_glyphInfo.size()) Log.report(LogVisor::FatalError, "TextView::queryGlyphWidth(%" PRISize ") out of bounds: %" PRISize, - pos, m_glyphDims.size()); + pos, m_glyphInfo.size()); - return m_glyphDims[pos]; + return m_glyphInfo[pos].m_dims; } size_t TextView::reverseSelectGlyph(int x) const @@ -527,9 +521,9 @@ size_t TextView::reverseSelectGlyph(int x) const size_t ret = 0; size_t idx = 1; int minDelta = abs(x); - for (int adv : m_glyphAdvs) + for (const RenderGlyphInfo& info : m_glyphInfo) { - int thisDelta = abs(adv-x); + int thisDelta = abs(info.m_adv-x); if (thisDelta < minDelta) { minDelta = thisDelta; @@ -542,12 +536,35 @@ size_t TextView::reverseSelectGlyph(int x) const int TextView::queryReverseAdvance(size_t idx) const { - if (idx > m_glyphAdvs.size()) + if (idx > m_glyphInfo.size()) Log.report(LogVisor::FatalError, "TextView::queryReverseGlyph(%" PRISize ") out of inclusive bounds: %" PRISize, - idx, m_glyphAdvs.size()); + idx, m_glyphInfo.size()); if (!idx) return 0; - return m_glyphAdvs[idx-1]; + return m_glyphInfo[idx-1].m_adv; +} + +std::pair TextView::queryWholeWordRange(size_t idx) const +{ + if (idx > m_glyphInfo.size()) + Log.report(LogVisor::FatalError, + "TextView::queryWholeWordRange(%" PRISize ") out of inclusive bounds: %" PRISize, + idx, m_glyphInfo.size()); + if (m_glyphInfo.empty()) + return {0,0}; + + if (idx == m_glyphInfo.size()) + --idx; + + size_t begin = idx; + while (begin > 0 && !m_glyphInfo[begin-1].m_space) + --begin; + + size_t end = idx; + while (end < m_glyphInfo.size() && !m_glyphInfo[end].m_space) + ++end; + + return {begin, end-begin}; } } diff --git a/specter/lib/Toolbar.cpp b/specter/lib/Toolbar.cpp index f43285bfa..06b10861f 100644 --- a/specter/lib/Toolbar.cpp +++ b/specter/lib/Toolbar.cpp @@ -59,83 +59,32 @@ Toolbar::Toolbar(ViewResources& res, View& parentView, Position tbPos) void Toolbar::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) { - boo::SWindowRect childRect = subRect(); - int subLoc1 = childRect.location[1]; - for (Child& c : m_children) - { - childRect.size[0] = c.m_view->nominalWidth(); - childRect.size[1] = c.m_view->nominalHeight(); - childRect.location[0] += m_padding; - childRect.location[1] = subLoc1 + (m_nomHeight - childRect.size[1]) / 2 - 1; - if (childRect.coordInRect(coord)) - { - if (!c.m_mouseDown) - { - c.m_view->mouseDown(coord, button, mod); - c.m_mouseDown = true; - } - } - childRect.location[0] += childRect.size[0]; - } + for (ViewChild& c : m_children) + c.mouseDown(coord, button, mod); } void Toolbar::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) { - for (Child& c : m_children) - { - if (c.m_mouseDown) - { - c.m_view->mouseUp(coord, button, mod); - c.m_mouseDown = false; - } - } + for (ViewChild& c : m_children) + c.mouseUp(coord, button, mod); } void Toolbar::mouseMove(const boo::SWindowCoord& coord) { - boo::SWindowRect childRect = subRect(); - int subLoc1 = childRect.location[1]; - for (Child& c : m_children) - { - childRect.size[0] = c.m_view->nominalWidth(); - childRect.size[1] = c.m_view->nominalHeight(); - childRect.location[0] += m_padding; - childRect.location[1] = subLoc1 + (m_nomHeight - childRect.size[1]) / 2 - 1; - if (childRect.coordInRect(coord)) - { - if (!c.m_mouseIn) - { - c.m_view->mouseEnter(coord); - c.m_mouseIn = true; - } - c.m_view->mouseMove(coord); - } - else - { - if (c.m_mouseIn) - { - c.m_view->mouseLeave(coord); - c.m_mouseIn = false; - } - } - childRect.location[0] += childRect.size[0]; - } + for (ViewChild& c : m_children) + c.mouseMove(coord); } void Toolbar::mouseEnter(const boo::SWindowCoord& coord) { + for (ViewChild& c : m_children) + c.mouseEnter(coord); } void Toolbar::mouseLeave(const boo::SWindowCoord& coord) { - for (Child& c : m_children) - { - if (c.m_mouseIn) - { - c.m_view->mouseLeave(coord); - c.m_mouseIn = false; - } - } + for (ViewChild& c : m_children) + c.mouseLeave(coord); } void Toolbar::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) @@ -147,7 +96,7 @@ void Toolbar::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) m_tbBlockBuf->load(&m_tbBlock, sizeof(ViewBlock)); boo::SWindowRect childRect = sub; - for (Child& c : m_children) + for (ViewChild& c : m_children) { childRect.size[0] = c.m_view->nominalWidth(); childRect.size[1] = c.m_view->nominalHeight(); @@ -165,7 +114,7 @@ void Toolbar::draw(boo::IGraphicsCommandQueue* gfxQ) gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); gfxQ->draw(0, 10); - for (Child& c : m_children) + for (ViewChild& c : m_children) c.m_view->draw(gfxQ); }