reactphysics3d/testbed/nanogui/include/nanogui/imageview.h

175 lines
6.4 KiB
C++

/*
nanogui/imageview.h -- Widget used to display images.
The image view widget was contributed by Stefan Ivanov.
NanoGUI was developed by Wenzel Jakob <wenzel.jakob@epfl.ch>.
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.
*/
/** \file */
#pragma once
#include <nanogui/widget.h>
#include <nanogui/glutil.h>
#include <functional>
NAMESPACE_BEGIN(nanogui)
/**
* \class ImageView imageview.h nanogui/imageview.h
*
* \brief Widget used to display images.
*/
class NANOGUI_EXPORT ImageView : public Widget {
public:
ImageView(Widget* parent, GLuint imageID);
~ImageView();
void bindImage(GLuint imageId);
GLShader& imageShader() { return mShader; }
Vector2f positionF() const { return mPos.cast<float>(); }
Vector2f sizeF() const { return mSize.cast<float>(); }
const Vector2i& imageSize() const { return mImageSize; }
Vector2i scaledImageSize() const { return (mScale * mImageSize.cast<float>()).cast<int>(); }
Vector2f imageSizeF() const { return mImageSize.cast<float>(); }
Vector2f scaledImageSizeF() const { return (mScale * mImageSize.cast<float>()); }
const Vector2f& offset() const { return mOffset; }
void setOffset(const Vector2f& offset) { mOffset = offset; }
float scale() const { return mScale; }
void setScale(float scale) { mScale = scale > 0.01f ? scale : 0.01f; }
bool fixedOffset() const { return mFixedOffset; }
void setFixedOffset(bool fixedOffset) { mFixedOffset = fixedOffset; }
bool fixedScale() const { return mFixedScale; }
void setFixedScale(bool fixedScale) { mFixedScale = fixedScale; }
float zoomSensitivity() const { return mZoomSensitivity; }
void setZoomSensitivity(float zoomSensitivity) { mZoomSensitivity = zoomSensitivity; }
float gridThreshold() const { return mGridThreshold; }
void setGridThreshold(float gridThreshold) { mGridThreshold = gridThreshold; }
float pixelInfoThreshold() const { return mPixelInfoThreshold; }
void setPixelInfoThreshold(float pixelInfoThreshold) { mPixelInfoThreshold = pixelInfoThreshold; }
#ifndef DOXYGEN_SHOULD_SKIP_THIS
void setPixelInfoCallback(const std::function<std::pair<std::string, Color>(const Vector2i&)>& callback) {
mPixelInfoCallback = callback;
}
const std::function<std::pair<std::string, Color>(const Vector2i&)>& pixelInfoCallback() const {
return mPixelInfoCallback;
}
#endif // DOXYGEN_SHOULD_SKIP_THIS
void setFontScaleFactor(float fontScaleFactor) { mFontScaleFactor = fontScaleFactor; }
float fontScaleFactor() const { return mFontScaleFactor; }
// Image transformation functions.
/// Calculates the image coordinates of the given pixel position on the widget.
Vector2f imageCoordinateAt(const Vector2f& position) const;
/**
* Calculates the image coordinates of the given pixel position on the widget.
* If the position provided corresponds to a coordinate outside the range of
* the image, the coordinates are clamped to edges of the image.
*/
Vector2f clampedImageCoordinateAt(const Vector2f& position) const;
/// Calculates the position inside the widget for the given image coordinate.
Vector2f positionForCoordinate(const Vector2f& imageCoordinate) const;
/**
* Modifies the internal state of the image viewer widget so that the pixel at the provided
* position on the widget has the specified image coordinate. Also clamps the values of offset
* to the sides of the widget.
*/
void setImageCoordinateAt(const Vector2f& position, const Vector2f& imageCoordinate);
/// Centers the image without affecting the scaling factor.
void center();
/// Centers and scales the image so that it fits inside the widgets.
void fit();
/// Set the scale while keeping the image centered
void setScaleCentered(float scale);
/// Moves the offset by the specified amount. Does bound checking.
void moveOffset(const Vector2f& delta);
/**
* Changes the scale factor by the provided amount modified by the zoom sensitivity member variable.
* The scaling occurs such that the image coordinate under the focused position remains in
* the same position before and after the scaling.
*/
void zoom(int amount, const Vector2f& focusPosition);
bool keyboardEvent(int key, int scancode, int action, int modifiers) override;
bool keyboardCharacterEvent(unsigned int codepoint) override;
bool mouseDragEvent(const Vector2i &p, const Vector2i &rel, int button, int modifiers) override;
bool scrollEvent(const Vector2i &p, const Vector2f &rel) override;
/// Function indicating whether the grid is currently visible.
bool gridVisible() const;
/// Function indicating whether the pixel information is currently visible.
bool pixelInfoVisible() const;
/// Function indicating whether any of the overlays are visible.
bool helpersVisible() const;
Vector2i preferredSize(NVGcontext* ctx) const override;
void performLayout(NVGcontext* ctx) override;
void draw(NVGcontext* ctx) override;
private:
// Helper image methods.
void updateImageParameters();
// Helper drawing methods.
void drawWidgetBorder(NVGcontext* ctx) const;
void drawImageBorder(NVGcontext* ctx) const;
void drawHelpers(NVGcontext* ctx) const;
static void drawPixelGrid(NVGcontext* ctx, const Vector2f& upperLeftCorner,
const Vector2f& lowerRightCorner, float stride);
void drawPixelInfo(NVGcontext* ctx, float stride) const;
void writePixelInfo(NVGcontext* ctx, const Vector2f& cellPosition,
const Vector2i& pixel, float stride, float fontSize) const;
// Image parameters.
GLShader mShader;
GLuint mImageID;
Vector2i mImageSize;
// Image display parameters.
float mScale;
Vector2f mOffset;
bool mFixedScale;
bool mFixedOffset;
// Fine-tuning parameters.
float mZoomSensitivity = 1.1f;
// Image info parameters.
float mGridThreshold = -1;
float mPixelInfoThreshold = -1;
// Image pixel data display members.
std::function<std::pair<std::string, Color>(const Vector2i&)> mPixelInfoCallback;
float mFontScaleFactor = 0.2f;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
NAMESPACE_END(nanogui)