Files
openglplayground/Widget.hh
2015-03-10 00:48:25 +01:00

133 lines
4.2 KiB
C++

#ifndef __OPENGLPLAYGROUND_WIDGET_HH__
#define __OPENGLPLAYGROUND_WIDGET_HH__
#include <memory>
#include <SDL2/SDL.h>
#include <glbinding/gl/types.h>
#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;
/* Size the widget to wrap the content size, expanding to fill parent when
parent is larger */
static const int WRAP_CONTENT_FILL = -3;
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);
int getLeftPadding() const { return padLeft_; }
int getTopPadding() const { return padTop_; }
int getRightPadding() const { return padRight_; }
int getBottomPadding() const { return padBottom_; }
virtual void setAlignment(int horiz, int vert);
void setContainerAlignment(int horiz, int vert);
int getContainerAlignmentHoriz() const { return alignContHoriz_; }
int getContainerAlignmentVert() const { return alignContVert_; }
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). Check caller to prevent recursion */
virtual void layout(Widget *caller = nullptr) = 0;
/* Inform the renderToGL() code that any cached presentations are now invalid */
void invalidateGL();
/* 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;
/* Helper to calculate layout height, width constraints
Returns width, height tuple with with width/height > 0 if fixed or
determined by parent layout, 0 if it should be based on widget contents.
Checks caller to prevent recursion */
std::tuple<int, int> baseLayout(Widget *caller);
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(this); }
std::string name_;
int width_, height_;
int realWidth_, realHeight_;
SDL_Surface *background_;
SDL_Color bg_, fg_;
int padLeft_, padTop_, padRight_, padBottom_;
int alignHoriz_, alignVert_;
int alignContHoriz_, alignContVert_;
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<Texture2D> renderTex_;
mutable VBOManager::VBOAlloc vbo_;
mutable gl::GLuint vaID_;
};
#endif