/*
nanogui/widget.h -- Base class of all widgets
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.
*/
#pragma once
#include <nanogui/object.h>
#include <nanogui/theme.h>
#include <vector>
NAMESPACE_BEGIN(nanogui)
enum class Cursor;// do not put a docstring, this is already documented
class NANOGUI_EXPORT Widget : public Object {
public:
Widget(Widget *parent);
Widget *parent() { return mParent; }
const Widget *parent() const { return mParent; }
void setParent(Widget *parent) { mParent = parent; }
Layout *layout() { return mLayout; }
const Layout *layout() const { return mLayout.get(); }
void setLayout(Layout *layout) { mLayout = layout; }
Theme *theme() { return mTheme; }
const Theme *theme() const { return mTheme.get(); }
virtual void setTheme(Theme *theme);
const Vector2i &position() const { return mPos; }
void setPosition(const Vector2i &pos) { mPos = pos; }
Vector2i absolutePosition() const {
return mParent ?
(parent()->absolutePosition() + mPos) : mPos;
}
const Vector2i &size() const { return mSize; }
void setSize(const Vector2i &size) { mSize = size; }
int width() const { return mSize.x(); }
void setWidth(int width) { mSize.x() = width; }
int height() const { return mSize.y(); }
void setHeight(int height) { mSize.y() = height; }
void setFixedSize(const Vector2i &fixedSize) { mFixedSize = fixedSize; }
const Vector2i &fixedSize() const { return mFixedSize; }
// Return the fixed width (see \ref setFixedSize())
int fixedWidth() const { return mFixedSize.x(); }
// Return the fixed height (see \ref setFixedSize())
int fixedHeight() const { return mFixedSize.y(); }
void setFixedWidth(int width) { mFixedSize.x() = width; }
void setFixedHeight(int height) { mFixedSize.y() = height; }
bool visible() const { return mVisible; }
void setVisible(bool visible) { mVisible = visible; }
bool visibleRecursive() const {
bool visible = true;
const Widget *widget = this;
while (widget) {
visible &= widget->visible();
widget = widget->parent();
}
return visible;
}
int childCount() const { return (int) mChildren.size(); }
const std::vector<Widget *> &children() const { return mChildren; }
virtual void addChild(int index, Widget *widget);
void addChild(Widget *widget);
void removeChild(int index);
void removeChild(const Widget *widget);
const Widget* childAt(int index) const { return mChildren[index]; }
Widget* childAt(int index) { return mChildren[index]; }
int childIndex(Widget* widget) const;
template<typename WidgetClass, typename... Args>
WidgetClass* add(const Args&... args) {
return new WidgetClass(this, args...);
}
Window *window();
Screen *screen();
void setId(const std::string &id) { mId = id; }
const std::string &id() const { return mId; }
bool enabled() const { return mEnabled; }
void setEnabled(bool enabled) { mEnabled = enabled; }
bool focused() const { return mFocused; }
void setFocused(bool focused) { mFocused = focused; }
void requestFocus();
const std::string &tooltip() const { return mTooltip; }
void setTooltip(const std::string &tooltip) { mTooltip = tooltip; }
int fontSize() const;
void setFontSize(int fontSize) { mFontSize = fontSize; }
bool hasFontSize() const { return mFontSize > 0; }
float iconExtraScale() const { return mIconExtraScale; }
void setIconExtraScale(float scale) { mIconExtraScale = scale; }
Cursor cursor() const { return mCursor; }
void setCursor(Cursor cursor) { mCursor = cursor; }
bool contains(const Vector2i &p) const {
auto d = (p-mPos).array();
return (d >= 0).all() && (d < mSize.array()).all();
}
Widget *findWidget(const Vector2i &p);
virtual bool mouseButtonEvent(const Vector2i &p, int button, bool down, int modifiers);
virtual bool mouseMotionEvent(const Vector2i &p, const Vector2i &rel, int button, int modifiers);
virtual bool mouseDragEvent(const Vector2i &p, const Vector2i &rel, int button, int modifiers);
virtual bool mouseEnterEvent(const Vector2i &p, bool enter);
virtual bool scrollEvent(const Vector2i &p, const Vector2f &rel);
virtual bool focusEvent(bool focused);
virtual bool keyboardEvent(int key, int scancode, int action, int modifiers);
virtual bool keyboardCharacterEvent(unsigned int codepoint);
virtual Vector2i preferredSize(NVGcontext *ctx) const;
virtual void performLayout(NVGcontext *ctx);
virtual void draw(NVGcontext *ctx);
virtual void save(Serializer &s) const;
virtual bool load(Serializer &s);
protected:
virtual ~Widget();
inline float icon_scale() const { return mTheme->mIconScale * mIconExtraScale; }
protected:
Widget *mParent;
ref<Theme> mTheme;
ref<Layout> mLayout;
std::string mId;
Vector2i mPos, mSize, mFixedSize;
std::vector<Widget *> mChildren;
bool mVisible;
bool mEnabled;
bool mFocused, mMouseFocus;
std::string mTooltip;
int mFontSize;
float mIconExtraScale;
Cursor mCursor;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
NAMESPACE_END(nanogui)