#ifndef __OPENGLPLAYGROUND_WIDGET_HH__ #define __OPENGLPLAYGROUND_WIDGET_HH__ #include #include #include #include "common.hh" #include "VBOManager.hh" /* Size the widget to wrap the content size */ static const int WRAP_CONTENT = -1; /* Size the widget to match the parent. If there is no parent, behaves like WRAP_CONTENT */ static const int MATCH_PARENT = -2; static const int ALIGN_TOP = 0; static const int ALIGN_BOTTOM = 1; static const int ALIGN_CENTER = 2; static const int ALIGN_LEFT = 0; static const int ALIGN_RIGHT = 1; class Texture2D; class Widget { public: Widget(int width = WRAP_CONTENT, int height = WRAP_CONTENT, std::string name = ""); Widget(Widget const& copy) = delete; Widget& operator=(Widget const& copy) = delete; virtual ~Widget(); std::string const& getName() const { return name_; } Widget* getParent() { return parent_; } int getWidth() const { return width_; } int getHeight() const { return height_; } int getRealWidth() const { return realWidth_; } int getRealHeight() const { return realHeight_; } virtual void setSize(int width, int height); /* Set background image. The image is scaled to the widgets actual size*/ void setBackground(SDL_Surface* surf); /* Set background color. Only takes effect when the background image is NULL */ void setBackgroundColor(SDL_Color bg); /* Set foreground color. Effect depends on widget type */ virtual void setForegroundColor(SDL_Color fg); /* Set the padding between the widget position and the content Exact effect depends on widget type. In general, when a widget is rendered the background is applied to the entire dstRect, and the content is rendered with padding*/ void setPadding(int left, int top, int right, int bottom); virtual void setAlignment(int horiz, int vert); void setGLRenderPos(int left, int top); virtual void render(SDL_Surface *dst, SDL_Rect *dstRect) const; void renderToGL() const; protected: /* Update realWidth_ and realHeight_ where necessary (width_ or height_ == WRAP_CONTENT) */ virtual void layout() = 0; /* Inform the renderToGL() code that any cached presentations are now invalid */ void invalidateGL() { renderTexValid_ = false; } /* Helper to calculate the SDL_Rect with which to render the content, respecting alignment and padding */ SDL_Rect calcContentRect(SDL_Surface *dst, SDL_Rect *dstRect, SDL_Rect contentRect) const; void setParent(Widget *parent); /* Helpers to allow Views to access protected methods of other Widgets */ void _setParent(Widget& child) { child.setParent(this); } void _clearParent(Widget& child) { child.setParent(nullptr); } void _layout(Widget& child) { child.layout(); } std::string name_; int width_, height_; int realWidth_, realHeight_; SDL_Surface *background_; SDL_Color bg_, fg_; int padLeft_, padTop_, padRight_, padBottom_; int alignHoriz_, alignVert_; Widget *parent_; private: struct VertexAttribs { int16_t vertex[2]; uint16_t texCoords[2]; } __attribute__((__packed__)); int renderTop_, renderLeft_; mutable bool renderTexValid_, renderAttribsValid_; mutable std::unique_ptr renderTex_; mutable VBOManager::VBOAlloc vbo_; mutable gl::GLuint vaID_; }; #endif