/* src/imagepanel.cpp -- Image panel widget which shows a number of square-shaped icons NanoGUI was developed by Wenzel Jakob . The widget drawing code is based on the NanoVG demo application by Mikko Mononen. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE.txt file. */ #include #include NAMESPACE_BEGIN(nanogui) ImagePanel::ImagePanel(Widget *parent) : Widget(parent), mThumbSize(64), mSpacing(10), mMargin(10), mMouseIndex(-1) {} Vector2i ImagePanel::gridSize() const { int nCols = 1 + std::max(0, (int) ((mSize.x() - 2 * mMargin - mThumbSize) / (float) (mThumbSize + mSpacing))); int nRows = ((int) mImages.size() + nCols - 1) / nCols; return Vector2i(nCols, nRows); } int ImagePanel::indexForPosition(const Vector2i &p) const { Vector2f pp = ((p - mPos).cast() - Vector2f::Constant(mMargin)) / (float)(mThumbSize + mSpacing); float iconRegion = mThumbSize / (float)(mThumbSize + mSpacing); bool overImage = pp.x() - std::floor(pp.x()) < iconRegion && pp.y() - std::floor(pp.y()) < iconRegion; Vector2i gridPos = pp.cast(), grid = gridSize(); overImage &= ((gridPos.array() >= 0).all() && (gridPos.array() < grid.array()).all()); return overImage ? (gridPos.x() + gridPos.y() * grid.x()) : -1; } bool ImagePanel::mouseMotionEvent(const Vector2i &p, const Vector2i & /* rel */, int /* button */, int /* modifiers */) { mMouseIndex = indexForPosition(p); return true; } bool ImagePanel::mouseButtonEvent(const Vector2i &p, int /* button */, bool down, int /* modifiers */) { int index = indexForPosition(p); if (index >= 0 && mCallback && down) mCallback(index); return true; } Vector2i ImagePanel::preferredSize(NVGcontext *) const { Vector2i grid = gridSize(); return Vector2i( grid.x() * mThumbSize + (grid.x() - 1) * mSpacing + 2*mMargin, grid.y() * mThumbSize + (grid.y() - 1) * mSpacing + 2*mMargin ); } void ImagePanel::draw(NVGcontext* ctx) { Vector2i grid = gridSize(); for (size_t i=0; i