mirror of https://github.com/AxioDL/metaforce.git
TextField updates
This commit is contained in:
parent
95fd2f90a9
commit
49ff010a20
|
@ -21,7 +21,7 @@ class FileBrowser : public ModalWindow
|
|||
{
|
||||
FileBrowser& m_fb;
|
||||
size_t m_idx;
|
||||
Specter::ViewChild<Specter::Button> m_button;
|
||||
Specter::ViewChild<std::unique_ptr<Specter::Button>> 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<PathButton> m_pathButtons;
|
||||
|
||||
Specter::ViewChild<Specter::TextField> m_fileField;
|
||||
Specter::ViewChild<std::unique_ptr<Specter::TextField>> m_fileField;
|
||||
struct FileFieldBind : Specter::IStringBinding
|
||||
{
|
||||
FileBrowser& m_browser;
|
||||
|
@ -45,8 +45,8 @@ class FileBrowser : public ModalWindow
|
|||
}
|
||||
} m_fileFieldBind;
|
||||
|
||||
Specter::ViewChild<Specter::ScrollView> m_fileScroll;
|
||||
Specter::ViewChild<Specter::Table> m_fileListing;
|
||||
Specter::ViewChild<std::unique_ptr<Specter::ScrollView>> m_fileScroll;
|
||||
Specter::ViewChild<std::unique_ptr<Specter::Table>> m_fileListing;
|
||||
|
||||
public:
|
||||
FileBrowser(ViewResources& res, View& parentView)
|
||||
|
|
|
@ -28,6 +28,7 @@ class RootView : public View
|
|||
IViewManager& m_viewMan;
|
||||
ViewResources* m_viewRes;
|
||||
View* m_activeTextView = nullptr;
|
||||
View* m_activeDragView = nullptr;
|
||||
|
||||
DeferredWindowEvents<RootView> 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);
|
||||
|
|
|
@ -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<View*> m_views[2];
|
||||
ViewBlock m_splitBlock;
|
||||
boo::IGraphicsBufferD* m_splitBlockBuf;
|
||||
TexShaderVert m_splitVerts[4];
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -66,6 +66,16 @@ public:
|
|||
|
||||
RenderGlyph(int& adv, const FontAtlas::Glyph& glyph, const Zeus::CColor& defaultColor);
|
||||
};
|
||||
struct RenderGlyphInfo
|
||||
{
|
||||
uint32_t m_char;
|
||||
std::pair<int,int> 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<RenderGlyph>& accessGlyphs() {return m_glyphs;}
|
||||
const std::vector<RenderGlyph>& accessGlyphs() const {return m_glyphs;}
|
||||
void updateGlyphs() {m_valid = false;}
|
||||
|
@ -88,11 +98,11 @@ public:
|
|||
std::pair<int,int> queryGlyphDimensions(size_t pos) const;
|
||||
size_t reverseSelectGlyph(int x) const;
|
||||
int queryReverseAdvance(size_t idx) const;
|
||||
std::pair<size_t,size_t> queryWholeWordRange(size_t idx) const;
|
||||
|
||||
private:
|
||||
std::vector<RenderGlyph> m_glyphs;
|
||||
std::vector<std::pair<int,int>> m_glyphDims;
|
||||
std::vector<int> m_glyphAdvs;
|
||||
std::vector<RenderGlyphInfo> m_glyphInfo;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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<Child> m_children;
|
||||
std::vector<ViewChild<View*>> 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;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -209,12 +209,12 @@ public:
|
|||
virtual void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
};
|
||||
|
||||
template <class ViewType>
|
||||
template <class ViewPtrType>
|
||||
struct ViewChild
|
||||
{
|
||||
std::unique_ptr<ViewType> 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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<size_t,size_t> 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();
|
||||
|
|
|
@ -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<int,int> 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<size_t,size_t> 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};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<View*>& 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<View*>& 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<View*>& c : m_children)
|
||||
c.mouseMove(coord);
|
||||
}
|
||||
|
||||
void Toolbar::mouseEnter(const boo::SWindowCoord& coord)
|
||||
{
|
||||
for (ViewChild<View*>& 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<View*>& 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<View*>& 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<View*>& c : m_children)
|
||||
c.m_view->draw(gfxQ);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue