Program Listing for File widget.h

Return to documentation for file (nanogui/widget.h)

/*
    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)