From 4866ac6d4c0fceec6eb13389b1eb0e6ca3a74dc6 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Tue, 29 Dec 2015 12:58:09 -1000 Subject: [PATCH] Working scroll wheel functionality --- specter/include/Specter/FileBrowser.hpp | 12 ++- specter/include/Specter/ScrollView.hpp | 7 ++ specter/include/Specter/Table.hpp | 21 +++-- specter/lib/ScrollView.cpp | 62 ++++++++++++- specter/lib/Table.cpp | 118 ++++++++++++++++-------- 5 files changed, 169 insertions(+), 51 deletions(-) diff --git a/specter/include/Specter/FileBrowser.hpp b/specter/include/Specter/FileBrowser.hpp index e91c83377..c20b56a99 100644 --- a/specter/include/Specter/FileBrowser.hpp +++ b/specter/include/Specter/FileBrowser.hpp @@ -108,8 +108,18 @@ class FileBrowser : public ModalWindow std::string m_sizeCol = "Size"; std::vector m_sizes = {"s1", "s2", "s3"}; + TableDataBind() + { + for (int i=0 ; i<100 ; ++i) + { + m_names.push_back(HECL::Format("%d", i)); + m_types.push_back(HECL::Format("%d", i)); + m_sizes.push_back(HECL::Format("%d", i)); + } + } + size_t columnCount() const {return 3;} - size_t rowCount() const {return 3;} + size_t rowCount() const {return 103;} const std::string* header(size_t cIdx) const { diff --git a/specter/include/Specter/ScrollView.hpp b/specter/include/Specter/ScrollView.hpp index 80029039a..e6d7fade8 100644 --- a/specter/include/Specter/ScrollView.hpp +++ b/specter/include/Specter/ScrollView.hpp @@ -18,6 +18,7 @@ public: private: View* m_contentView = nullptr; int m_scroll[2] = {}; + int m_targetScroll[2] = {}; public: ScrollView(ViewResources& res, View& parentView); @@ -28,7 +29,13 @@ public: } void scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll); + int getScrollX() const {return m_scroll[0];} + int getScrollY() const {return m_scroll[1];} + int nominalWidth() const {return subRect().size[0];} + int nominalHeight() const {return subRect().size[1];} + + void think(); void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub); void draw(boo::IGraphicsCommandQueue* gfxQ); }; diff --git a/specter/include/Specter/Table.hpp b/specter/include/Specter/Table.hpp index 703ce2ea2..d06a0fb87 100644 --- a/specter/include/Specter/Table.hpp +++ b/specter/include/Specter/Table.hpp @@ -51,20 +51,24 @@ class Table : public View std::vector>> m_cellViews; bool m_header = false; - SolidShaderVert m_verts[SPECTER_TABLE_MAX_ROWS * 6]; - boo::IGraphicsBufferD* m_vertsBuf = nullptr; - boo::IVertexFormat* m_vtxFmt = nullptr; /* OpenGL only */ - boo::IShaderDataBinding* m_shaderBinding = nullptr; - size_t m_visibleRows = 0; - void _setRowVerts(const boo::SWindowRect& rowsRect); - ViewChild> m_scroll; struct RowsView : public View { Table& m_t; - RowsView(Table& t, ViewResources& res) : View(res, t), m_t(t) {} + + SolidShaderVert m_verts[SPECTER_TABLE_MAX_ROWS * 6]; + boo::IGraphicsBufferD* m_vertsBuf = nullptr; + boo::IVertexFormat* m_vtxFmt = nullptr; /* OpenGL only */ + boo::IShaderDataBinding* m_shaderBinding = nullptr; + size_t m_visibleStart = 0; + size_t m_visibleRows = 0; + boo::SWindowRect m_scissorRect; + void _setRowVerts(const boo::SWindowRect& rowsRect, const boo::SWindowRect& scissor); + + RowsView(Table& t, ViewResources& res); int nominalHeight() const; + int nominalWidth() const {return m_t.m_scroll.m_view->nominalWidth();} void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, const boo::SWindowRect& scissor); void draw(boo::IGraphicsCommandQueue* gfxQ); @@ -82,6 +86,7 @@ public: void mouseLeave(const boo::SWindowCoord&); void scroll(const boo::SWindowCoord&, const boo::SScrollDelta&); + void think(); void updateData(); void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub); void draw(boo::IGraphicsCommandQueue* gfxQ); diff --git a/specter/lib/ScrollView.cpp b/specter/lib/ScrollView.cpp index 5cdcb44da..70fe0e063 100644 --- a/specter/lib/ScrollView.cpp +++ b/specter/lib/ScrollView.cpp @@ -2,6 +2,7 @@ namespace Specter { +#define MAX_SCROLL_SPEED 100 ScrollView::ScrollView(ViewResources& res, View& parentView) : View(res, parentView) @@ -11,9 +12,60 @@ ScrollView::ScrollView(ViewResources& res, View& parentView) void ScrollView::scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll) { - m_scroll[0] += scroll.delta[0]; - m_scroll[1] += scroll.delta[1]; - updateSize(); + if (m_contentView) + { + double mult = 10.0; + if (scroll.isFine) + mult = 1.0; + m_targetScroll[0] += scroll.delta[0] * mult; + m_targetScroll[1] += scroll.delta[1] * mult; + m_targetScroll[1] = std::min(m_targetScroll[1], 0); + if (scroll.isFine) + { + m_scroll[0] = m_targetScroll[0]; + m_scroll[1] = m_targetScroll[1]; + updateSize(); + } + } + else + { + m_scroll[0] = 0; + m_scroll[1] = 0; + m_targetScroll[0] = 0; + m_targetScroll[1] = 0; + updateSize(); + } +} + +void ScrollView::think() +{ + bool update = false; + + int xSpeed = std::max(1, std::min(abs(m_targetScroll[0] - m_scroll[0]) / 10, MAX_SCROLL_SPEED)); + if (m_scroll[0] < m_targetScroll[0]) + { + m_scroll[0] += xSpeed; + update = true; + } + else if (m_scroll[0] > m_targetScroll[0]) + { + m_scroll[0] -= xSpeed; + update = true; + } + + int ySpeed = std::max(1, std::min(abs(m_targetScroll[1] - m_scroll[1]) / 10, MAX_SCROLL_SPEED)); + if (m_scroll[1] < m_targetScroll[1]) + { + m_scroll[1] += ySpeed; + update = true; + } + else if (m_scroll[1] > m_targetScroll[1]) + { + m_scroll[1] -= ySpeed; + update = true; + } + if (update) + updateSize(); } void ScrollView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) @@ -23,7 +75,9 @@ void ScrollView::resized(const boo::SWindowRect& root, const boo::SWindowRect& s { boo::SWindowRect cRect = sub; cRect.location[0] += m_scroll[0]; - cRect.location[1] += sub.size[1] - m_contentView->nominalHeight() + m_scroll[1]; + cRect.location[1] += sub.size[1] - m_contentView->nominalHeight() - m_scroll[1]; + cRect.size[0] = m_contentView->nominalWidth(); + cRect.size[1] = m_contentView->nominalHeight(); m_contentView->resized(root, cRect, sub); } } diff --git a/specter/lib/Table.cpp b/specter/lib/Table.cpp index 7312d13dc..6f26e22ca 100644 --- a/specter/lib/Table.cpp +++ b/specter/lib/Table.cpp @@ -9,6 +9,16 @@ namespace Specter Table::Table(ViewResources& res, View& parentView, ITableDataBinding* data, ITableStateBinding* state) : View(res, parentView), m_data(data), m_state(state), m_rowsView(*this, res) +{ + commitResources(res); + + m_scroll.m_view.reset(new ScrollView(res, *this)); + m_scroll.m_view->setContentView(&m_rowsView); + updateData(); +} + +Table::RowsView::RowsView(Table& t, ViewResources& res) +: View(res, t), m_t(t) { m_vertsBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SolidShaderVert), SPECTER_TABLE_MAX_ROWS * 6); @@ -35,40 +45,49 @@ Table::Table(ViewResources& res, View& parentView, ITableDataBinding* data, ITab nullptr, 1, bufs, 0, nullptr); } commitResources(res); - - m_scroll.m_view.reset(new ScrollView(res, *this)); - m_scroll.m_view->setContentView(&m_rowsView); - updateData(); } Table::CellView::CellView(Table& t, ViewResources& res) : View(res, t), m_t(t), m_text(new TextView(res, *this, res.m_mainFont)) {} -void Table::_setRowVerts(const boo::SWindowRect& rowsRect) +void Table::RowsView::_setRowVerts(const boo::SWindowRect& sub, const boo::SWindowRect& scissor) { SolidShaderVert* v = m_verts; const ThemeData& theme = rootView().themeData(); + + if (m_t.m_cellViews.empty()) + return; + float pf = rootView().viewRes().pixelFactor(); + int div = sub.size[0] / m_t.m_cellViews.size(); + int spacing = (ROW_HEIGHT + ROW_SPACING) * pf; int rowHeight = ROW_HEIGHT * pf; - int rowSpace = ROW_SPACING * pf; - int hAdv = rowHeight + rowSpace; - int yOff = rowsRect.size[1] - hAdv; + int yOff = 0; + int idx = 0; + while (sub.location[1] + yOff < scissor.location[1] + scissor.size[1] || (idx & 1) != 0) + { + yOff += spacing; + ++idx; + } + int startIdx = std::max(0, int(m_t.m_rows) - idx); + size_t i; - for (i=0 ; i= 0 ; ++i) + for (i=0 ; i= scissor.location[1] ; ++i) { v[0].m_pos.assign(0, yOff, 0); v[0].m_color = (i&1) ? theme.tableCellBg1() : theme.tableCellBg2(); v[1] = v[0]; v[2].m_pos.assign(0, yOff - rowHeight, 0); v[2].m_color = v[0].m_color; - v[3].m_pos.assign(rowsRect.size[0], yOff, 0); + v[3].m_pos.assign(sub.size[0], yOff, 0); v[3].m_color = v[0].m_color; - v[4].m_pos.assign(rowsRect.size[0], yOff - rowHeight, 0); + v[4].m_pos.assign(sub.size[0], yOff - rowHeight, 0); v[4].m_color = v[0].m_color; v[5] = v[4]; - yOff -= hAdv; + yOff -= spacing; v += 6; } + m_visibleStart = startIdx; m_visibleRows = i; m_vertsBuf->load(m_verts, sizeof(SolidShaderVert) * 6 * i); } @@ -117,6 +136,12 @@ void Table::scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scro m_scroll.scroll(coord, scroll); } +void Table::think() +{ + if (m_scroll.m_view) + m_scroll.m_view->think(); +} + void Table::updateData() { m_header = false; @@ -183,21 +208,6 @@ void Table::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) hv->resized(root, cell); cell.location[0] += div; } - - int spacing = ROW_HEIGHT + ROW_SPACING * pf; - cell.location[0] = sub.location[0]; - int hStart = cell.location[1]; - for (auto& col : m_cellViews) - { - cell.location[1] = hStart; - for (std::unique_ptr& cv : col) - { - cell.location[1] -= spacing; - if (cv) - cv->resized(root, cell); - } - cell.location[0] += div; - } } int Table::RowsView::nominalHeight() const @@ -209,7 +219,33 @@ int Table::RowsView::nominalHeight() const void Table::RowsView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, const boo::SWindowRect& scissor) { - m_t._setRowVerts(sub); + View::resized(root, sub); + _setRowVerts(sub, scissor); + + if (m_t.m_cellViews.empty()) + return; + + float pf = rootView().viewRes().pixelFactor(); + int div = sub.size[0] / m_t.m_cellViews.size(); + boo::SWindowRect cell = sub; + cell.size[1] = ROW_HEIGHT * pf; + cell.location[1] += sub.size[1] - cell.size[1]; + int spacing = (ROW_HEIGHT + ROW_SPACING) * pf; + int hStart = cell.location[1]; + for (auto& col : m_t.m_cellViews) + { + cell.location[1] = hStart; + for (std::unique_ptr& cv : col) + { + cell.location[1] -= spacing; + if (cv) + cv->resized(root, cell); + } + cell.location[0] += div; + } + + m_scissorRect = scissor; + m_scissorRect.size[1] -= spacing; } void Table::CellView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) @@ -230,21 +266,27 @@ void Table::draw(boo::IGraphicsCommandQueue* gfxQ) void Table::RowsView::draw(boo::IGraphicsCommandQueue* gfxQ) { - gfxQ->setShaderDataBinding(m_t.m_shaderBinding); + gfxQ->setShaderDataBinding(m_shaderBinding); gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); - gfxQ->setScissor(subRect()); - size_t rows = std::min(m_t.m_visibleRows, m_t.m_rows); + + gfxQ->setScissor(m_scissorRect); + size_t rows = std::min(m_visibleRows, m_t.m_rows); gfxQ->draw(1, rows * 6 - 2); + for (auto& col : m_t.m_cellViews) + { + size_t idx = 0; + for (std::unique_ptr& cv : col) + { + if (cv && idx >= m_visibleStart && idx < m_visibleStart + m_visibleRows) + cv->draw(gfxQ); + ++idx; + } + } + gfxQ->setScissor(rootView().subRect()); + for (std::unique_ptr& hv : m_t.m_headerViews) if (hv) hv->draw(gfxQ); - for (auto& col : m_t.m_cellViews) - { - for (std::unique_ptr& cv : col) - if (cv) - cv->draw(gfxQ); - } - gfxQ->setScissor(rootView().subRect()); } void Table::CellView::draw(boo::IGraphicsCommandQueue* gfxQ)