#pragma once #include #include #include #include "Common/Math/geom2d.h" #include "Common/Math/lin/vec3.h" #include "Common/Render/TextureAtlas.h" // Everything you need to draw a UI collected into a single unit that can be passed around. // Everything forward declared so this header is safe everywhere. namespace Draw { class DrawContext; class Pipeline; class DepthStencilState; class Texture; class BlendState; class SamplerState; class RasterState; } class Texture; class ManagedTexture; class DrawBuffer; class TextDrawer; namespace UI { struct Drawable; struct EventParams; struct Theme; struct FontStyle; class Event; class View; } class DrawBuffer; struct UITransform { // TODO: Or just use a matrix? Lin::Vec3 translate; Lin::Vec3 scale; float alpha; }; class UIContext { public: UIContext(); ~UIContext(); void Init(Draw::DrawContext *thin3d, Draw::Pipeline *uipipe, Draw::Pipeline *uipipenotex, DrawBuffer *uidrawbuffer, DrawBuffer *uidrawbufferTop); void BeginFrame(); void Begin(); void BeginNoTex(); void BeginPipeline(Draw::Pipeline *pipeline, Draw::SamplerState *samplerState); void Flush(); void RebindTexture() const; // TODO: Support transformed bounds using stencil void PushScissor(const Bounds &bounds); void PopScissor(); Bounds GetScissorBounds(); void ActivateTopScissor(); DrawBuffer *Draw() const { return uidrawbuffer_; } DrawBuffer *DrawTop() const { return uidrawbufferTop_; } const UI::Theme *theme; // Utility methods TextDrawer *Text() const { return textDrawer_; } void SetFontStyle(const UI::FontStyle &style); const UI::FontStyle &GetFontStyle() { return *fontStyle_; } void SetFontScale(float scaleX, float scaleY); void MeasureTextCount(const UI::FontStyle &style, float scaleX, float scaleY, const char *str, int count, float *x, float *y, int align = 0) const; void MeasureText(const UI::FontStyle &style, float scaleX, float scaleY, const char *str, float *x, float *y, int align = 0) const; void MeasureTextRect(const UI::FontStyle &style, float scaleX, float scaleY, const char *str, int count, const Bounds &bounds, float *x, float *y, int align = 0) const; void DrawText(const char *str, float x, float y, uint32_t color, int align = 0); void DrawTextShadow(const char *str, float x, float y, uint32_t color, int align = 0); void DrawTextRect(const char *str, const Bounds &bounds, uint32_t color, int align = 0); void DrawTextShadowRect(const char *str, const Bounds &bounds, uint32_t color, int align = 0); void FillRect(const UI::Drawable &drawable, const Bounds &bounds); void DrawImageVGradient(ImageID image, uint32_t color1, uint32_t color2, const Bounds &bounds); // in dps, like dp_xres and dp_yres void SetBounds(const Bounds &b) { bounds_ = b; } const Bounds &GetBounds() const { return bounds_; } Bounds GetLayoutBounds() const; Draw::DrawContext *GetDrawContext() { return draw_; } void SetCurZ(float curZ); void PushTransform(const UITransform &transform); void PopTransform(); Bounds TransformBounds(const Bounds &bounds); private: Draw::DrawContext *draw_ = nullptr; Bounds bounds_; float fontScaleX_ = 1.0f; float fontScaleY_ = 1.0f; UI::FontStyle *fontStyle_ = nullptr; TextDrawer *textDrawer_ = nullptr; Draw::SamplerState *sampler_ = nullptr; Draw::Pipeline *ui_pipeline_ = nullptr; Draw::Pipeline *ui_pipeline_notex_ = nullptr; std::unique_ptr uitexture_; DrawBuffer *uidrawbuffer_ = nullptr; DrawBuffer *uidrawbufferTop_ = nullptr; std::vector scissorStack_; std::vector transformStack_; };