initial commit

This commit is contained in:
2026-08-27 17:15:05 -07:00
commit 80e222fa04
71 changed files with 54456 additions and 0 deletions
+47
View File
@@ -0,0 +1,47 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
namespace ImXui {
class FontEngine {
public:
FontEngine();
~FontEngine();
bool loadFontFile(const std::string& path);
bool loadFontMemory(const void* data, size_t size);
bool loadSystemFont(const std::string& requestedName);
bool isLoaded() const { return m_font != nullptr; }
float measureText(const std::wstring& text, float sizePx) const;
float lineHeight(float sizePx) const;
bool renderText(const std::wstring& text, float sizePx,
std::vector<uint8_t>& outRgba, int& outW, int& outH) const;
const std::string& getLoadedPath() const { return m_path; }
private:
struct FontData;
FontData* m_font;
std::vector<uint8_t> m_blob;
const void* m_blobPtr;
size_t m_blobSize;
std::string m_path;
};
}
File diff suppressed because it is too large Load Diff
+833
View File
@@ -0,0 +1,833 @@
#pragma once
#include <string>
#include <vector>
#include <memory>
#include <functional>
#include <unordered_map>
#include <cstdint>
#include "XurFormat.h"
namespace ImXui {
const float BASE_SCENE_WIDTH = 1280.0f;
const float BASE_SCENE_HEIGHT = 720.0f;
enum AnchorStyle : uint32_t {
AnchorNone = 0,
AnchorLeft = 0x01,
AnchorTop = 0x02,
AnchorRight = 0x04,
AnchorBottom = 0x08,
AnchorCenterX = 0x10,
AnchorCenterY = 0x20,
};
enum class Result {
Success = 0,
Error_General = -1,
Error_NotFound = -2,
Error_InvalidParam = -3,
Error_OutOfMemory = -4,
Error_InvalidFile = -5,
Error_NotImplemented = -6,
};
struct Vec2 {
Vec2() : x(0), y(0) {}
Vec2(float x_, float y_) : x(x_), y(y_) {}
float x, y;
};
struct Vec3 {
Vec3() : x(0), y(0), z(0) {}
Vec3(float x_, float y_, float z_) : x(x_), y(y_), z(z_) {}
float x, y, z;
};
struct Rect {
Rect() : x(0), y(0), w(0), h(0) {}
Rect(float x_, float y_, float w_, float h_) : x(x_), y(y_), w(w_), h(h_) {}
float x, y, w, h;
float left() const { return x; }
float top() const { return y; }
float right() const { return x + w; }
float bottom() const { return y + h; }
Vec2 center() const { return Vec2(x + w * 0.5f, y + h * 0.5f); }
};
struct Color {
Color() : r(1.0f), g(1.0f), b(1.0f), a(1.0f) {}
Color(float r_, float g_, float b_, float a_) : r(r_), g(g_), b(b_), a(a_) {}
float r, g, b, a;
};
class Value {
public:
enum Type {
Null, Boolean, Number, StringUTF8, StringUTF16,
};
Value() : m_type(Null), m_number(0.0), m_bool(false) {}
explicit Value(bool v) : m_type(Boolean), m_number(0.0), m_bool(v) {}
explicit Value(double v) : m_type(Number), m_number(v), m_bool(false) {}
explicit Value(float v) : m_type(Number), m_number((double)v), m_bool(false) {}
explicit Value(int v) : m_type(Number), m_number((double)v), m_bool(false) {}
explicit Value(const char* utf8) : m_type(StringUTF8), m_number(0.0), m_bool(false), m_string8(utf8 ? utf8 : "") {}
explicit Value(const std::string& utf8) : m_type(StringUTF8), m_number(0.0), m_bool(false), m_string8(utf8) {}
explicit Value(const wchar_t* utf16) : m_type(StringUTF16), m_number(0.0), m_bool(false), m_string16(utf16 ? utf16 : L"") {}
explicit Value(const std::wstring& utf16) : m_type(StringUTF16), m_number(0.0), m_bool(false), m_string16(utf16) {}
Type type() const { return m_type; }
bool isNull() const { return m_type == Null; }
bool isBool() const { return m_type == Boolean; }
bool isNumber() const { return m_type == Number; }
bool isString() const { return m_type == StringUTF8 || m_type == StringUTF16; }
bool toBool() const { return m_type == Boolean ? m_bool : false; }
double toNumber() const { return m_type == Number ? m_number : 0.0; }
float toFloat() const { return (float)toNumber(); }
int toInt() const { return (int)toNumber(); }
const std::string& toString8() const { return m_string8; }
const std::wstring& toString16() const { return m_string16; }
private:
Type m_type;
double m_number;
bool m_bool;
std::string m_string8;
std::wstring m_string16;
};
enum class EventType {
None, Press, Release, FocusGained, FocusLost,
ValueChanged, SelectionChanged, SliderMove,
MouseEnter, MouseLeave, AnimationEnd,
};
class Element;
class Control;
class Scene;
class Canvas;
class Application;
typedef std::function<Result(Scene*, void*)> InitCallback;
typedef std::function<Result(Scene*, uint32_t)> TimerCallback;
typedef std::function<Result(Scene*, uint32_t key, bool down)> InputCallback;
typedef std::function<void(Scene*, void* region)> DrawCallback;
typedef std::function<Value(const std::vector<Value>&)> MethodCallback;
class Element {
public:
Element();
virtual ~Element();
void setId(const std::wstring& id) { m_id = id; }
const std::wstring& getId() const { return m_id; }
void setClassName(const std::wstring& name) { m_className = name; }
const std::wstring& getClassName() const { return m_className; }
void setParent(Element* parent) { m_parent = parent; }
Element* getParent() const { return m_parent; }
Element* getChildById(const std::wstring& id);
Element* findFirstChild(const std::wstring& id);
void setPosition(const Vec3& pos) { m_position = pos; markLayoutDirty(); }
Vec3 getPosition() const { return m_position; }
void setBounds(float w, float h) { m_bounds.w = w; m_bounds.h = h; markLayoutDirty(); }
Vec2 getBounds() const { return Vec2(m_bounds.w, m_bounds.h); }
void setAnchor(uint32_t anchor) { m_anchor = anchor; markLayoutDirty(); }
uint32_t getAnchor() const { return m_anchor; }
Rect getComputedRect() const { return m_computedRect; }
void markLayoutDirty() { m_layoutDirty = true; }
bool isLayoutDirty() const { return m_layoutDirty; }
void computeLayout(Rect parentRect);
void computeLayout() { computeLayout(Rect(0, 0, 1280, 720)); }
void setShow(bool show) { m_visible = show; }
bool isShown() const { return m_visible; }
void setOpacity(float opacity) { m_opacity = opacity; }
float getOpacity() const { return m_opacity; }
void setScale(const Vec3& scale) { m_scale = scale; }
Vec3 getScale() const { return m_scale; }
void setPivot(const Vec3& pivot) { m_pivot = pivot; }
Vec3 getPivot() const { return m_pivot; }
void setRotation(const Vec3& rotation) { m_rotation = rotation; }
Vec3 getRotation() const { return m_rotation; }
void setBlendMode(uint32_t mode) { m_blendMode = mode; }
uint32_t getBlendMode() const { return m_blendMode; }
void setClipChildren(bool clip) { m_clipChildren = clip; }
bool getClipChildren() const { return m_clipChildren; }
void setHittable(bool hittable) { m_hittable = hittable; }
bool isHittable() const { return m_hittable; }
void setLayoutLineBreak(bool lb) { m_layoutLineBreak = lb; markLayoutDirty(); }
bool getLayoutLineBreak() const { return m_layoutLineBreak; }
void setLayoutFloat(bool lf) { m_layoutFloat = lf; markLayoutDirty(); }
bool getLayoutFloat() const { return m_layoutFloat; }
void setColumn(uint32_t col) { m_column = col; markLayoutDirty(); }
uint32_t getColumn() const { return m_column; }
void setRow(uint32_t row) { m_row = row; markLayoutDirty(); }
uint32_t getRow() const { return m_row; }
void setColumnSpan(uint32_t span) { m_columnSpan = span; markLayoutDirty(); }
uint32_t getColumnSpan() const { return m_columnSpan; }
void setRowSpan(uint32_t span) { m_rowSpan = span; markLayoutDirty(); }
uint32_t getRowSpan() const { return m_rowSpan; }
void setColorFactor(const Color& c) { m_colorFactor = c; }
Color getColorFactor() const { return m_colorFactor; }
void setImagePath(const std::wstring& path) { m_imagePath = path; }
const std::wstring& getImagePath() const { return m_imagePath; }
void addChild(std::unique_ptr<Element> child);
bool removeChildById(const std::wstring& id);
const std::vector<std::unique_ptr<Element>>& getChildren() const { return m_children; }
virtual void onEvent(EventType type, const std::vector<Value>& args);
virtual bool isControl() const { return false; }
protected:
std::wstring m_id;
std::wstring m_className;
Element* m_parent;
std::vector<std::unique_ptr<Element>> m_children;
Vec3 m_position;
Rect m_bounds;
Vec3 m_scale;
Vec3 m_pivot;
Vec3 m_rotation;
float m_opacity;
bool m_visible;
Color m_colorFactor;
std::wstring m_imagePath;
uint32_t m_anchor;
uint32_t m_blendMode;
bool m_clipChildren;
bool m_hittable;
bool m_layoutLineBreak;
bool m_layoutFloat;
uint32_t m_column;
uint32_t m_row;
uint32_t m_columnSpan;
uint32_t m_rowSpan;
Rect m_computedRect;
bool m_layoutDirty;
bool m_isNineGrid;
uint32_t m_nineGridLeft;
uint32_t m_nineGridTop;
uint32_t m_nineGridRight;
uint32_t m_nineGridBottom;
bool m_nineGridNoCenter;
std::wstring m_nineGridTexture;
bool m_isFigure;
bool m_figureClosed;
uint32_t m_figureFillType;
Color m_figureFillColor;
std::wstring m_figureFillTexture;
float m_figureFillRotation;
Vec2 m_figureFillTranslation;
Vec2 m_figureFillScale;
uint32_t m_figureFillWrapX;
uint32_t m_figureFillWrapY;
float m_figureStrokeWidth;
Color m_figureStrokeColor;
std::vector<Vec2> m_figurePoints;
public:
void setIsNineGrid(bool v) { m_isNineGrid = v; }
bool getIsNineGrid() const { return m_isNineGrid; }
void setNineGridLeft(uint32_t v) { m_nineGridLeft = v; }
uint32_t getNineGridLeft() const { return m_nineGridLeft; }
void setNineGridTop(uint32_t v) { m_nineGridTop = v; }
uint32_t getNineGridTop() const { return m_nineGridTop; }
void setNineGridRight(uint32_t v) { m_nineGridRight = v; }
uint32_t getNineGridRight() const { return m_nineGridRight; }
void setNineGridBottom(uint32_t v) { m_nineGridBottom = v; }
uint32_t getNineGridBottom() const { return m_nineGridBottom; }
void setNineGridNoCenter(bool v) { m_nineGridNoCenter = v; }
bool getNineGridNoCenter() const { return m_nineGridNoCenter; }
void setNineGridTexture(const std::wstring& v) { m_nineGridTexture = v; }
const std::wstring& getNineGridTexture() const { return m_nineGridTexture; }
void setIsFigure(bool v) { m_isFigure = v; }
bool getIsFigure() const { return m_isFigure; }
void setFigureClosed(bool v) { m_figureClosed = v; }
bool getFigureClosed() const { return m_figureClosed; }
void setFigureFillType(uint32_t v) { m_figureFillType = v; }
uint32_t getFigureFillType() const { return m_figureFillType; }
void setFigureFillColor(const Color& c) { m_figureFillColor = c; }
Color getFigureFillColor() const { return m_figureFillColor; }
void setFigureFillTexture(const std::wstring& v) { m_figureFillTexture = v; }
const std::wstring& getFigureFillTexture() const { return m_figureFillTexture; }
void setFigureFillRotation(float v) { m_figureFillRotation = v; }
float getFigureFillRotation() const { return m_figureFillRotation; }
void setFigureFillTranslation(const Vec2& v) { m_figureFillTranslation = v; }
Vec2 getFigureFillTranslation() const { return m_figureFillTranslation; }
void setFigureFillScale(const Vec2& v) { m_figureFillScale = v; }
Vec2 getFigureFillScale() const { return m_figureFillScale; }
void setFigureFillWrapX(uint32_t v) { m_figureFillWrapX = v; }
uint32_t getFigureFillWrapX() const { return m_figureFillWrapX; }
void setFigureFillWrapY(uint32_t v) { m_figureFillWrapY = v; }
uint32_t getFigureFillWrapY() const { return m_figureFillWrapY; }
void setFigureStrokeWidth(float v) { m_figureStrokeWidth = v; }
float getFigureStrokeWidth() const { return m_figureStrokeWidth; }
void setFigureStrokeColor(const Color& c) { m_figureStrokeColor = c; }
Color getFigureStrokeColor() const { return m_figureStrokeColor; }
void setFigurePoints(const std::vector<Vec2>& pts) { m_figurePoints = pts; }
const std::vector<Vec2>& getFigurePoints() const { return m_figurePoints; }
};
class Control : public Element {
public:
Control();
explicit Control(const std::wstring& id);
~Control();
bool isControl() const override { return true; }
void setText(const std::wstring& text) { m_text = text; }
const std::wstring& getText() const { return m_text; }
void setFontName(const std::wstring& name) { m_fontName = name; }
const std::wstring& getFontName() const { return m_fontName; }
void setFontSize(float size) { m_fontSize = size; }
float getFontSize() const { return m_fontSize; }
void setEnable(bool enable) { m_enabled = enable; }
bool isEnabled() const { return m_enabled; }
void setFocused(bool focused);
bool isFocused() const { return m_focused; }
virtual void press();
void setOnPressCallback(const std::function<void()>& cb) { m_onPress = cb; }
virtual void onFocusGained();
virtual void onFocusLost();
void setOnFocusCallback(const std::function<void(bool)>& cb) { m_onFocus = cb; }
virtual void onValueChanged(const Value& newValue);
void setOnValueChangedCallback(const std::function<void(const Value&)>& cb) { m_onValueChanged = cb; }
virtual void onSelectionChanged(int newSelection);
void setOnSelectionChangedCallback(const std::function<void(int)>& cb) { m_onSelectionChanged = cb; }
void setVisual(const std::wstring& visual) { m_visual = visual; }
const std::wstring& getVisual() const { return m_visual; }
void setProgressValue(int value) { m_progressValue = value; }
int getProgressValue() const { return m_progressValue; }
void setProgressRange(int min, int max) { m_progressMin = min; m_progressMax = max; }
int getProgressMin() const { return m_progressMin; }
int getProgressMax() const { return m_progressMax; }
float getProgress() const {
if (m_progressMax <= m_progressMin) return 0;
return (float)(m_progressValue - m_progressMin) / (float)(m_progressMax - m_progressMin);
}
void setNavUp(const std::wstring& id) { m_navUp = id; }
const std::wstring& getNavUp() const { return m_navUp; }
void setNavDown(const std::wstring& id) { m_navDown = id; }
const std::wstring& getNavDown() const { return m_navDown; }
void setNavLeft(const std::wstring& id) { m_navLeft = id; }
const std::wstring& getNavLeft() const { return m_navLeft; }
void setNavRight(const std::wstring& id) { m_navRight = id; }
const std::wstring& getNavRight() const { return m_navRight; }
void setNavTabForward(const std::wstring& id) { m_navTabForward = id; }
const std::wstring& getNavTabForward() const { return m_navTabForward; }
void setNavTabBackward(const std::wstring& id) { m_navTabBackward = id; }
const std::wstring& getNavTabBackward() const { return m_navTabBackward; }
void setPressKey(uint32_t key) { m_pressKey = key; }
uint32_t getPressKey() const { return m_pressKey; }
void setPressAnimObject(const std::wstring& name) { m_pressAnimObject = name; }
const std::wstring& getPressAnimObject() const { return m_pressAnimObject; }
void setFocusAnimObject(const std::wstring& name) { m_focusAnimObject = name; }
const std::wstring& getFocusAnimObject() const { return m_focusAnimObject; }
void setStep(int step) { m_step = step; }
int getStep() const { return m_step; }
void setVertical(bool vert) { m_vertical = vert; }
bool isVertical() const { return m_vertical; }
void setAccelInc(int inc) { m_accelInc = inc; }
int getAccelInc() const { return m_accelInc; }
void setAccelTime(uint32_t time) { m_accelTime = time; }
uint32_t getAccelTime() const { return m_accelTime; }
virtual Value getProperty(const std::wstring& name);
virtual bool setProperty(const std::wstring& name, const Value& value);
void setUserData(void* data) { m_userData = data; }
void* getUserData() const { return m_userData; }
void onEvent(EventType type, const std::vector<Value>& args) override;
void setCustomDrawId(const std::wstring& id) { m_customDrawId = id; }
const std::wstring& getCustomDrawId() const { return m_customDrawId; }
Control* getNavTarget(int direction) const;
protected:
std::wstring m_text;
std::wstring m_fontName;
float m_fontSize;
std::wstring m_visual;
std::wstring m_customDrawId;
bool m_enabled;
bool m_focused;
int m_progressValue;
int m_progressMin;
int m_progressMax;
void* m_userData;
std::wstring m_navUp;
std::wstring m_navDown;
std::wstring m_navLeft;
std::wstring m_navRight;
std::wstring m_navTabForward;
std::wstring m_navTabBackward;
uint32_t m_pressKey;
std::wstring m_pressAnimObject;
std::wstring m_focusAnimObject;
int m_step;
bool m_vertical;
int m_accelInc;
uint32_t m_accelTime;
std::function<void()> m_onPress;
std::function<void(bool)> m_onFocus;
std::function<void(const Value&)> m_onValueChanged;
std::function<void(int)> m_onSelectionChanged;
};
class Scene {
public:
Scene();
virtual ~Scene();
virtual Result onCreate(void* initData = nullptr);
virtual Result onDestroy();
virtual Result onTick(float deltaTime);
virtual Result onKeyDown(uint32_t key);
virtual Result onKeyUp(uint32_t key);
virtual Result onTimer(uint32_t timerId);
virtual Result onTransitionStart(uint32_t transAction, uint32_t transType);
virtual Result onGetSourceText(int dataIndex, std::wstring& outText);
virtual Result onGetSourceImage(int dataIndex, std::wstring& outImagePath);
virtual Result onGetItemCount(int& outCount);
virtual Result onGetItemEnable(int itemIndex, bool& outEnabled);
Element* getRootElement() const { return m_root.get(); }
Control* findControl(const std::wstring& id);
Element* findElement(const std::wstring& id);
Element* findElementRecursive(Element* root, const std::wstring& id);
void setClassOverride(const std::wstring& className) { m_className = className; }
const std::wstring& getClassOverride() const { return m_className; }
void addSubScene(std::unique_ptr<Scene> subScene);
Scene* findSubScene(const std::wstring& id);
void setDisplaySize(float width, float height);
float getDisplayWidth() const { return m_displayWidth; }
float getDisplayHeight() const { return m_displayHeight; }
void setMovieWidth(float w) { m_movieWidth = w; }
float getMovieWidth() const { return m_movieWidth; }
void setMovieHeight(float h) { m_movieHeight = h; }
float getMovieHeight() const { return m_movieHeight; }
void setFrameRate(float fps) { m_frameRate = fps; }
float getFrameRate() const { return m_frameRate; }
void setUserData(void* data) { m_userData = data; }
void* getUserData() const { return m_userData; }
void setDefaultFocus(const std::wstring& id) { m_defaultFocus = id; }
const std::wstring& getDefaultFocus() const { return m_defaultFocus; }
void addTimer(uint32_t id, int intervalMs);
void killTimer(uint32_t id);
void updateTimers(float deltaTime);
void sendMessage(uint32_t msgId, void* data, Element* source = nullptr);
void broadcastMessage(uint32_t msgId, void* data, Element* source = nullptr);
void setOnMessageCallback(const std::function<bool(uint32_t, void*, Element*)>& cb) { m_messageCallback = cb; }
void playTimeline(const std::wstring& elementName, int startFrame, int endFrame, bool loop, bool pause);
void stopTimeline(const std::wstring& elementName, bool gotoEnd);
int findNamedFrame(const std::wstring& elementName, const std::wstring& frameName);
void loadTimelines(const std::vector<XurFormat::XurTimeline>& timelines,
const std::vector<XurFormat::XurNamedFrame>& namedFrames);
void startTimeline(const std::wstring& elementName);
void updateAnimations(float deltaTime);
void setFocusedControl(Control* ctrl);
Control* getFocusedControl() const { return m_focusedControl; }
void navigateFocus(int direction);
virtual Value callMethod(const std::wstring& methodName, const std::vector<Value>& args);
void registerMethod(const std::wstring& name, const MethodCallback& cb);
virtual void dispatchEvent(const std::wstring& targetId, EventType type, const std::vector<Value>& args);
typedef std::function<bool(const std::wstring& funcName, const std::vector<Value>& args)> ExternalCallback;
void setExternalCallback(const ExternalCallback& cb) { m_externalCallback = cb; }
protected:
std::unique_ptr<Element> m_root;
std::wstring m_className;
std::vector<std::unique_ptr<Scene>> m_subScenes;
struct TimerEntry {
uint32_t id;
int intervalMs;
float accumulated;
};
std::vector<TimerEntry> m_timers;
float m_displayWidth;
float m_displayHeight;
float m_movieWidth;
float m_movieHeight;
float m_frameRate;
void* m_userData;
std::wstring m_defaultFocus;
std::wstring m_transTo;
std::wstring m_transFrom;
std::wstring m_transBackTo;
std::wstring m_transBackFrom;
bool m_ignorePresses;
Control* m_focusedControl;
std::unordered_map<std::wstring, MethodCallback> m_methods;
ExternalCallback m_externalCallback;
std::function<bool(uint32_t, void*, Element*)> m_messageCallback;
struct AnimationState {
std::wstring elementName;
int currentFrame;
int startFrame;
int endFrame;
bool loop;
bool paused;
float timeAccum;
struct KFProp {
std::string name;
XurFormat::XurPropertyValue value;
};
struct Keyframe {
int time;
uint8_t interpolation;
uint8_t easeIn;
uint8_t easeOut;
std::vector<KFProp> properties;
};
std::vector<Keyframe> keyframes;
};
std::vector<AnimationState> m_animations;
struct NamedFrame {
std::wstring name;
int keyframe;
uint32_t command;
std::wstring targetParameter;
};
std::vector<NamedFrame> m_namedFrames;
struct TimelineData {
std::wstring elementName;
struct KFProperty {
std::string name;
XurFormat::XurPropertyValue value;
};
struct KeyframeData {
int time;
uint8_t interpolation;
uint8_t easeIn;
uint8_t easeOut;
std::vector<KFProperty> properties;
};
std::vector<KeyframeData> keyframes;
};
std::vector<TimelineData> m_timelines;
struct TransitionState {
bool active;
float elapsed;
float duration;
std::wstring transType;
std::wstring transScenePath;
std::unique_ptr<Scene> transScene;
};
TransitionState m_transition;
void applyKeyframeProperty(Element* target, const AnimationState::KFProp& prop);
void interpolateKeyframeProperty(Element* target,
const AnimationState::KFProp& propA,
const AnimationState::KFProp& propB,
float t);
public:
void setTransitionTo(const std::wstring& path) { m_transTo = path; }
const std::wstring& getTransitionTo() const { return m_transTo; }
void setTransitionFrom(const std::wstring& path) { m_transFrom = path; }
const std::wstring& getTransitionFrom() const { return m_transFrom; }
void setTransitionBackTo(const std::wstring& path) { m_transBackTo = path; }
const std::wstring& getTransitionBackTo() const { return m_transBackTo; }
void setTransitionBackFrom(const std::wstring& path) { m_transBackFrom = path; }
const std::wstring& getTransitionBackFrom() const { return m_transBackFrom; }
void setIgnorePresses(bool v) { m_ignorePresses = v; }
bool getIgnorePresses() const { return m_ignorePresses; }
void startTransition(const std::wstring& type, float duration = 0.5f);
void updateTransition(float deltaTime);
bool isTransitioning() const { return m_transition.active; }
float getTransitionProgress() const;
Scene* getTransitionScene() const { return m_transition.transScene.get(); }
Value builtinSetAlpha(const std::vector<Value>& args);
Value builtinSetFocus(const std::vector<Value>& args);
Value builtinSetSafeZone(const std::vector<Value>& args);
Value builtinRemoveObject(const std::vector<Value>& args);
Value builtinSlideLeft(const std::vector<Value>& args);
Value builtinSlideRight(const std::vector<Value>& args);
Value builtinDoHorizontalResizeCheck(const std::vector<Value>& args);
};
class Canvas {
public:
Canvas();
~Canvas();
Result loadFromXui(const std::string& path);
Result loadFromXuiString(const std::wstring& xmlContent);
Result loadFromXur(const std::string& path);
Result loadFromXurMemory(const void* data, size_t size);
float getWidth() const { return m_width; }
float getHeight() const { return m_height; }
Scene* getScene() const { return m_scene.get(); }
void setScene(std::unique_ptr<Scene> scene) { m_scene = std::move(scene); }
Result parseXuiXml(const std::wstring& xml);
private:
float m_width;
float m_height;
std::unique_ptr<Scene> m_scene;
std::unique_ptr<Element> parseElementNode(const std::wstring& xml, size_t& pos);
std::wstring readProperty(const std::wstring& xml, size_t& pos);
};
typedef void* HXUIBRUSH;
class Brush {
public:
Brush();
~Brush();
void setImagePath(const std::wstring& path) { m_imagePath = path; }
const std::wstring& getImagePath() const { return m_imagePath; }
void setColor(const Color& c) { m_color = c; }
Color getColor() const { return m_color; }
void setOpacity(float opacity) { m_opacity = opacity; }
float getOpacity() const { return m_opacity; }
private:
std::wstring m_imagePath;
Color m_color;
float m_opacity;
};
class ProgressBar : public Control {
public:
ProgressBar();
explicit ProgressBar(const std::wstring& id);
~ProgressBar();
void setRange(int min, int max) { setProgressRange(min, max); }
void setValue(int value) { setProgressValue(value); }
int getValue() const { return getProgressValue(); }
void getRange(int* min, int* max) const { *min = getProgressMin(); *max = getProgressMax(); }
};
class Slider : public Control {
public:
Slider();
explicit Slider(const std::wstring& id);
~Slider();
void setRange(int min, int max) { setProgressRange(min, max); }
void setValue(int value) { setProgressValue(value); }
int getValue() const { return getProgressValue(); }
void getRange(int* min, int* max) const { *min = getProgressMin(); *max = getProgressMax(); }
void setStep(int step) { Control::setStep(step); }
int getStep() const { return Control::getStep(); }
void setVertical(bool vert) { Control::setVertical(vert); }
bool isVertical() const { return Control::isVertical(); }
};
struct ListItemInfo {
std::wstring text;
std::wstring imagePath;
HXUIBRUSH brush;
bool checked;
bool enabled;
int userData;
int index;
int sortIndex;
ListItemInfo() : brush(0), checked(false), enabled(true), userData(0), index(0), sortIndex(0) {}
};
class List : public Control {
public:
List();
explicit List(const std::wstring& id);
~List();
void addItem(const ListItemInfo& item);
void removeAllItems();
void updateItemText(int item, const std::wstring& text);
void updateItemGraphic(int item, HXUIBRUSH brush);
void selectByUserData(int userData);
int getIndexByUserData(int userData) const;
ListItemInfo& getData(int index);
ListItemInfo& getDataByUserData(int userData);
int getItemCount() const { return (int)m_items.size(); }
void setSelectionChangedHandler(Control* handler) { m_selectionChangedHandler = handler; }
void setWrap(bool wrap) { m_wrap = wrap; }
bool getWrap() const { return m_wrap; }
void setOnGetSourceText(const std::function<std::wstring(int)>& cb) { m_onGetSourceText = cb; }
void setOnGetSourceImage(const std::function<std::wstring(int)>& cb) { m_onGetSourceImage = cb; }
void setOnGetItemCount(const std::function<int()>& cb) { m_onGetItemCount = cb; }
void setOnGetItemEnable(const std::function<bool(int)>& cb) { m_onGetItemEnable = cb; }
void setOnSelectionChanged(const std::function<void(int)>& cb) { m_onSelectionChangedIdx = cb; }
std::wstring getSourceText(int index);
std::wstring getSourceImage(int index);
bool getItemEnable(int index);
private:
std::vector<ListItemInfo> m_items;
Control* m_selectionChangedHandler;
bool m_wrap;
std::function<std::wstring(int)> m_onGetSourceText;
std::function<std::wstring(int)> m_onGetSourceImage;
std::function<int()> m_onGetItemCount;
std::function<bool(int)> m_onGetItemEnable;
std::function<void(int)> m_onSelectionChangedIdx;
};
class Sound : public Element {
public:
Sound();
~Sound();
void play();
void stop();
void setCue(const std::wstring& cue) { m_cue = cue; }
const std::wstring& getCue() const { return m_cue; }
void setSoundBank(const std::wstring& bank) { m_soundBank = bank; }
const std::wstring& getSoundBank() const { return m_soundBank; }
void setWaveBank(const std::wstring& bank) { m_waveBank = bank; }
const std::wstring& getWaveBank() const { return m_waveBank; }
void setVolume(float vol) { m_volume = vol; }
float getVolume() const { return m_volume; }
void setLoop(bool loop) { m_loop = loop; }
bool getLoop() const { return m_loop; }
private:
std::wstring m_cue;
std::wstring m_soundBank;
std::wstring m_waveBank;
float m_volume;
bool m_loop;
};
class ElementImplBase {
public:
virtual ~ElementImplBase() {}
virtual Result OnInit(void* initData) { (void)initData; return Result_Success; }
virtual Result OnDestroy() { return Result_Success; }
};
class ControlImplBase {
public:
virtual ~ControlImplBase() {}
virtual Result OnInit(void* hObj, void* initData) { (void)hObj; (void)initData; return Result_Success; }
virtual Result OnDestroy(void* hObj) { (void)hObj; return Result_Success; }
virtual Result OnControlNavigate(void* hObj, void* navData) { (void)hObj; (void)navData; return Result_Success; }
virtual Result OnKeyDown(void* hObj, void* inputData) { (void)hObj; (void)inputData; return Result_Success; }
virtual Result OnCustomMessage_GetSlotItem(void* hObj, void* pData) { (void)hObj; (void)pData; return Result_Success; }
};
class ListImpl : public Control {
public:
ListImpl();
~ListImpl();
};
class ProgressBarImpl : public ProgressBar {
public:
ProgressBarImpl();
~ProgressBarImpl();
};
class Application {
public:
Application();
~Application();
Result init();
Result shutdown();
Result navigateToScene(int pad, Scene* scene, void* initData = nullptr);
Result navigateBack(int pad);
Result closeScene(int pad, Scene* scene);
void tick(float deltaTime);
void render();
Result sendKeyEvent(int pad, uint32_t key, bool down);
void loadStringTable(const std::wstring& path);
const wchar_t* getString(int id) const;
static Application* getInstance() { return s_instance; }
private:
static Application* s_instance;
struct Impl;
std::unique_ptr<Impl> m_impl;
};
}
+61
View File
@@ -0,0 +1,61 @@
#pragma once
#include <cstdint>
#include <string>
#include <unordered_map>
#include <vector>
namespace ImXui {
struct ImageData {
ImageData() : w(0), h(0) {}
int w;
int h;
std::vector<uint8_t> rgba;
bool valid() const { return w > 0 && h > 0 && !rgba.empty(); }
};
struct MemoryTexture {
int w;
int h;
std::vector<uint8_t> rgba;
MemoryTexture() : w(0), h(0) {}
};
void registerMemoryTexture(const std::string& name, const void* rgba,
int w, int h);
const MemoryTexture* findMemoryTexture(const std::string& name);
void clearMemoryTextures();
struct MemoryTextureRaw {
std::vector<uint8_t> encoded;
};
void registerMemoryTextureRaw(const std::string& name, const void* data, size_t size);
const MemoryTextureRaw* findMemoryTextureRaw(const std::string& name);
bool unregisterMemoryTexture(const std::string& name);
class ImageManager {
public:
ImageManager();
~ImageManager();
void setBasePath(const std::string& path) { m_basePath = path; }
const std::string& getBasePath() const { return m_basePath; }
const ImageData* load(const std::string& path);
static bool decodeFile(const std::string& path, ImageData& out);
void clear();
private:
std::string m_basePath;
std::unordered_map<std::string, ImageData> m_cache;
};
}
+151
View File
@@ -0,0 +1,151 @@
#pragma once
#include "ImXui.h"
#include <cstdint>
#include <string>
#include <vector>
namespace ImXui {
enum RenderCommandType {
RenderCommandType_BeginScene,
RenderCommandType_PushTransform,
RenderCommandType_PopTransform,
RenderCommandType_PushClip,
RenderCommandType_PopClip,
RenderCommandType_ColoredQuad,
RenderCommandType_TexturedQuad,
RenderCommandType_NineGrid,
RenderCommandType_Figure,
RenderCommandType_Text,
RenderCommandType_CustomDraw,
RenderCommandType_SetBlendMode,
RenderCommandType_EndScene,
};
struct Transform2D {
float m00, m01, m10, m11, tx, ty;
Transform2D()
: m00(1.0f), m01(0.0f), m10(0.0f), m11(1.0f), tx(0.0f), ty(0.0f) {}
};
struct RenderCommand {
RenderCommandType type;
Rect rect;
Color color;
Color strokeColor;
float opacity;
float strokeWidth;
uint32_t blendMode;
uint32_t leftInset;
uint32_t topInset;
uint32_t rightInset;
uint32_t bottomInset;
bool noCenter;
bool closed;
Transform2D transform;
std::wstring resource;
std::wstring text;
std::wstring fontName;
float fontSize;
bool centered;
std::vector<Vec2> points;
RenderCommand()
: type(RenderCommandType_BeginScene)
, rect()
, color()
, strokeColor()
, opacity(1.0f)
, strokeWidth(0.0f)
, blendMode(0)
, leftInset(0)
, topInset(0)
, rightInset(0)
, bottomInset(0)
, noCenter(false)
, closed(false)
, transform()
, fontSize(0.0f)
, centered(false)
{
}
};
class IRenderCommandSink {
public:
virtual ~IRenderCommandSink() {}
virtual void beginScene(float width, float height) = 0;
virtual void drawColoredQuad(const Rect& rect, const Color& color, float opacity) = 0;
virtual void drawTexturedQuad(const Rect& rect, const std::wstring& resource,
const Color& color, float opacity) = 0;
virtual void drawText(const Rect& rect, const std::wstring& text,
const std::wstring& fontName, float fontSize,
const Color& color, float opacity, bool centered) = 0;
virtual void endScene() = 0;
virtual void pushTransform(const Transform2D&) {}
virtual void popTransform() {}
virtual void pushClip(const Rect&) {}
virtual void popClip() {}
virtual void drawNineGrid(const Rect&, const std::wstring&, const Color&, float,
uint32_t, uint32_t, uint32_t, uint32_t, bool) {}
virtual void drawFigure(const Rect&, const std::vector<Vec2>&, bool,
const Color&, const Color&, float, float, uint32_t) {}
virtual void setBlendMode(uint32_t) {}
virtual void drawCustom(const std::wstring& drawId, const Rect&, float opacity) {
(void)drawId; (void)opacity;
}
};
class RenderCommandBuffer : public IRenderCommandSink {
public:
RenderCommandBuffer() : m_width(0.0f), m_height(0.0f) {}
void clear();
const std::vector<RenderCommand>& getCommands() const { return m_commands; }
std::vector<RenderCommand>& getCommands() { return m_commands; }
float getWidth() const { return m_width; }
float getHeight() const { return m_height; }
void beginScene(float width, float height);
void drawColoredQuad(const Rect& rect, const Color& color, float opacity);
void drawTexturedQuad(const Rect& rect, const std::wstring& resource,
const Color& color, float opacity);
void drawText(const Rect& rect, const std::wstring& text,
const std::wstring& fontName, float fontSize,
const Color& color, float opacity, bool centered);
void endScene();
void pushTransform(const Transform2D& transform);
void popTransform();
void pushClip(const Rect& rect);
void popClip();
void drawNineGrid(const Rect& rect, const std::wstring& resource,
const Color& color, float opacity,
uint32_t leftInset, uint32_t topInset,
uint32_t rightInset, uint32_t bottomInset,
bool noCenter);
void drawFigure(const Rect& rect, const std::vector<Vec2>& points, bool closed,
const Color& fillColor, const Color& strokeColor,
float opacity, float strokeWidth, uint32_t blendMode);
void setBlendMode(uint32_t blendMode);
void drawCustom(const std::wstring& drawId, const Rect& rect, float opacity);
private:
float m_width;
float m_height;
std::vector<RenderCommand> m_commands;
};
void emitRenderCommands(const Scene* scene, IRenderCommandSink* sink);
}
+183
View File
@@ -0,0 +1,183 @@
#pragma once
#include "ImXui.h"
#include "TextureManager.h"
#include "Skin.h"
#include <cstdint>
#include <string>
#include <map>
#include <list>
#include <vector>
#include <stack>
struct ID3D11Device;
struct ID3D11DeviceContext;
struct ID3D11Buffer;
struct ID3D11VertexShader;
struct ID3D11PixelShader;
struct ID3D11InputLayout;
struct ID3D11BlendState;
struct ID3D11SamplerState;
struct ID3D11RasterizerState;
struct ID3D11ShaderResourceView;
struct IDWriteFactory;
struct ID2D1Factory;
struct IDXGIDevice;
struct IDXGIFactory2;
struct IDXGISwapChain1;
struct IDCompositionDevice;
struct IDCompositionTarget;
struct IDCompositionVisual;
namespace ImXui {
struct RendererVertex2D { float x, y, u, v, r, g, b, a; };
class Renderer {
public:
virtual ~Renderer() {}
virtual bool init(void* nativeWindow, int width, int height) = 0;
virtual void shutdown() = 0;
virtual bool resize(int width, int height) = 0;
virtual bool beginFrame(float clearR = 0, float clearG = 0, float clearB = 0, float clearA = 1) = 0;
virtual void endFrame(bool vsync = true) = 0;
virtual void renderScene(const Scene* scene) = 0;
virtual void setTextureManager(TextureManager* mgr) = 0;
virtual void setSkin(const Skin* skin) = 0;
virtual const Skin* getSkin() const = 0;
virtual bool loadFont(const wchar_t* path) = 0;
virtual bool initTextRendering() = 0;
virtual void shutdownTextRendering() = 0;
virtual void drawTexturedQuad(float x, float y, float w, float h, const wchar_t* texturePath,
float r = 1, float g = 1, float b = 1, float a = 1) = 0;
virtual void drawFigure(float x, float y, float w, float h,
const std::vector<Vec2>& points, bool closed,
float fillR, float fillG, float fillB, float fillA,
float strokeR, float strokeG, float strokeB, float strokeA,
float strokeWidth) = 0;
virtual void drawColoredQuad(float x, float y, float w, float h,
float r, float g, float b, float a) = 0;
virtual void drawTextString(float x, float y, float w, float h,
const std::wstring& text, const std::wstring& fontName, float fontSize,
float r = 1, float g = 1, float b = 1, float a = 1,
bool centered = false) = 0;
virtual int getWidth() const = 0;
virtual int getHeight() const = 0;
};
class D3D11Renderer : public Renderer {
public:
D3D11Renderer();
~D3D11Renderer();
bool init(void* hwnd, int width, int height) override;
bool initExternal(ID3D11Device* device, ID3D11DeviceContext* context);
void shutdown() override;
bool resize(int width, int height) override;
bool beginFrame(float clearR = 0, float clearG = 0, float clearB = 0, float clearA = 1) override;
void endFrame(bool vsync = true) override;
void renderScene(const Scene* scene) override;
void setTextureManager(TextureManager* mgr) override { m_textureMgr = mgr; }
void setSkin(const Skin* skin) override { m_skin = skin; }
const Skin* getSkin() const override { return m_skin; }
ID3D11Device* getDevice() const { return m_device; }
ID3D11DeviceContext* getContext() const { return m_context; }
bool loadFont(const wchar_t* path) override;
bool initTextRendering() override;
void shutdownTextRendering() override;
void drawTexturedQuad(float x, float y, float w, float h, const wchar_t* texturePath,
float r = 1, float g = 1, float b = 1, float a = 1) override;
void drawTexturedQuadSRV(float x, float y, float w, float h, ID3D11ShaderResourceView* srv,
float r = 1, float g = 1, float b = 1, float a = 1);
void drawNineGrid(float x, float y, float w, float h, ID3D11ShaderResourceView* srv,
uint32_t leftInset, uint32_t topInset, uint32_t rightInset, uint32_t bottomInset,
bool noCenter, float r = 1, float g = 1, float b = 1, float a = 1);
void drawFigure(float x, float y, float w, float h,
const std::vector<Vec2>& points, bool closed,
float fillR, float fillG, float fillB, float fillA,
float strokeR, float strokeG, float strokeB, float strokeA,
float strokeWidth) override;
void drawColoredQuad(float x, float y, float w, float h,
float r, float g, float b, float a) override;
void drawTextString(float x, float y, float w, float h,
const std::wstring& text, const std::wstring& fontName, float fontSize,
float r = 1, float g = 1, float b = 1, float a = 1,
bool centered = false) override;
int getWidth() const override { return m_width; }
int getHeight() const override { return m_height; }
private:
bool createShadersAndStates();
bool createQuadBuffer();
bool createWhiteTexture();
void drawElement(const Element* el);
void drawTexturedElement(const Element* el);
void drawVisualImages(const std::vector<VisualImage>& images, const Rect& elementRect, float offsetX, float offsetY, float alpha);
Rect computeImageRect(const VisualImage& img, const Rect& visualBounds, const Rect& elementRect);
ID3D11ShaderResourceView* getOrCreateTextTexture(const std::wstring& text, const std::wstring& fontName, float fontSize, uint32_t textStyle, float maxWidth, int& outW, int& outH);
void drawText(const Control* ctrl, const Rect& rect, float alpha, const std::wstring& fontName, float fontSize, float textR = 1, float textG = 1, float textB = 1, float textA = 1, uint32_t textStyle = 0);
ID3D11Device* m_device;
ID3D11DeviceContext* m_context;
bool m_ownsDevice;
void* m_swapChain;
IDCompositionDevice* m_dcompDevice;
IDCompositionTarget* m_dcompTarget;
IDCompositionVisual* m_dcompVisual;
ID3D11VertexShader* m_vs;
ID3D11PixelShader* m_psTex;
ID3D11InputLayout* m_inputLayout;
ID3D11BlendState* m_blendState;
ID3D11BlendState* m_textBlendState;
ID3D11SamplerState* m_sampler;
ID3D11ShaderResourceView* m_whiteSRV;
ID3D11RasterizerState* m_scissorRS;
ID3D11RasterizerState* m_normalRS;
std::stack<Rect> m_clipStack;
ID3D11Buffer* m_quadVB;
RendererVertex2D* m_batchPtr;
int m_batchCount;
int m_width;
int m_height;
TextureManager* m_textureMgr;
const Skin* m_skin;
IDWriteFactory* m_dwriteFactory;
ID2D1Factory* m_d2dFactory;
struct TextCacheEntry { ID3D11ShaderResourceView* srv; int w; int h; TextCacheEntry() : srv(nullptr), w(0), h(0) {} };
std::map<std::wstring, TextCacheEntry> m_textCache;
std::list<std::wstring> m_textLru;
static const size_t TEXT_CACHE_MAX = 128;
};
}
+56
View File
@@ -0,0 +1,56 @@
#pragma once
#include <string>
#include <vector>
#include <unordered_map>
#include <cstdint>
namespace ImXui {
struct VisualImage {
std::string imagePath;
float x, y, z, w, h;
uint32_t anchor;
VisualImage() : x(0), y(0), z(0), w(0), h(0), anchor(0) {}
};
struct TextProperties {
bool hasColor;
uint8_t textColorA, textColorR, textColorG, textColorB;
float pointSize;
bool hasPointSize;
std::string font;
bool hasFont;
uint32_t textStyle;
bool hasTextStyle;
TextProperties()
: hasColor(false), textColorA(255), textColorR(255), textColorG(255), textColorB(255)
, pointSize(12.0f), hasPointSize(false), hasFont(false), textStyle(0), hasTextStyle(false) {}
};
struct VisualEntry {
std::string id;
float templateWidth, templateHeight;
float posX, posY;
std::vector<VisualImage> images;
TextProperties textProps;
VisualEntry() : templateWidth(0), templateHeight(0), posX(0), posY(0) {}
};
class Skin {
public:
bool loadFromXui(const std::string& path);
bool loadFromString(const std::string& xml);
const std::vector<VisualImage>* getImages(const std::string& visualName) const;
const VisualEntry* getEntry(const std::string& visualName) const;
const std::vector<VisualEntry>& getAllEntries() const { return m_entries; }
int count() const { return (int)m_entryMap.size(); }
private:
void parseVisualBlock(const std::string& xml, size_t start, size_t end);
std::string readProp(const std::string& xml, const std::string& propName, size_t from, size_t to);
std::vector<VisualEntry> m_entries;
std::unordered_map<std::string, int> m_entryMap;
};
}
+92
View File
@@ -0,0 +1,92 @@
#pragma once
#include "Renderer.h"
#include "FontEngine.h"
#include "ImageManager.h"
#include <cstdint>
#include <string>
#include <vector>
#include <stack>
namespace ImXui {
class SoftwareRenderer : public Renderer {
public:
SoftwareRenderer();
~SoftwareRenderer();
bool init(void* nativeWindow, int width, int height) override;
void shutdown() override;
bool resize(int width, int height) override;
bool beginFrame(float clearR = 0, float clearG = 0, float clearB = 0, float clearA = 1) override;
void endFrame(bool vsync = true) override;
void renderScene(const Scene* scene) override;
void setTextureManager(TextureManager* mgr) override { (void)mgr; }
void setSkin(const Skin* skin) override { m_skin = skin; }
const Skin* getSkin() const override { return m_skin; }
bool loadFont(const wchar_t* path) override;
bool loadSystemFont(const std::string& name);
bool initTextRendering() override;
void shutdownTextRendering() override;
float measureText(const std::wstring& text, float sizePx) const;
float lineHeight(float sizePx) const;
void drawTexturedQuad(float x, float y, float w, float h, const wchar_t* texturePath,
float r = 1, float g = 1, float b = 1, float a = 1) override;
void drawFigure(float x, float y, float w, float h,
const std::vector<Vec2>& points, bool closed,
float fillR, float fillG, float fillB, float fillA,
float strokeR, float strokeG, float strokeB, float strokeA,
float strokeWidth) override;
void drawColoredQuad(float x, float y, float w, float h,
float r, float g, float b, float a) override;
void drawTextString(float x, float y, float w, float h,
const std::wstring& text, const std::wstring& fontName, float fontSize,
float r = 1, float g = 1, float b = 1, float a = 1,
bool centered = false) override;
int getWidth() const override { return m_width; }
int getHeight() const override { return m_height; }
const uint8_t* getFramebuffer() const { return m_fb.empty() ? nullptr : m_fb.data(); }
size_t getFramebufferSize() const { return m_fb.size(); }
uint32_t pixel(int x, int y) const;
bool savePng(const char* path) const;
bool saveBmp(const char* path) const;
private:
void drawElement(const Element* el);
void drawTexturedElement(const Element* el);
void drawNineGridRect(float x, float y, float w, float h, const ImageData& img,
uint32_t leftInset, uint32_t topInset, uint32_t rightInset, uint32_t bottomInset,
bool noCenter, float r, float g, float b, float a);
void fillRect(float x, float y, float w, float h, float r, float g, float b, float a);
void fillTriangle(float x0, float y0, float x1, float y1, float x2, float y2,
float r, float g, float b, float a);
void blitImage(int dx, int dy, int dw, int dh, const ImageData& img,
float tintR, float tintG, float tintB, float alpha);
void strokeSegment(float x0, float y0, float x1, float y1, float width,
float r, float g, float b, float a);
void pushClip(const Rect& r);
void popClip();
bool clipRect(Rect& r) const;
std::vector<uint8_t> m_fb;
int m_width;
int m_height;
FontEngine m_font;
ImageManager m_images;
const Skin* m_skin;
std::stack<Rect> m_clipStack;
};
}
+35
View File
@@ -0,0 +1,35 @@
#pragma once
#include <string>
#include <unordered_map>
#include <cstdint>
struct ID3D11Device;
struct ID3D11ShaderResourceView;
namespace ImXui {
class TextureManager {
public:
TextureManager() : m_device(nullptr) {}
~TextureManager() { shutdown(); }
bool init(ID3D11Device* device);
void shutdown();
void setBasePath(const std::string& path) { m_basePath = path; }
const std::string& getBasePath() const { return m_basePath; }
ID3D11ShaderResourceView* load(const std::string& relativePath);
bool getSize(const std::string& relativePath, int& w, int& h) const;
private:
ID3D11Device* m_device;
std::string m_basePath;
std::unordered_map<std::string, ID3D11ShaderResourceView*> m_cache;
std::unordered_map<std::string, int> m_widths;
std::unordered_map<std::string, int> m_heights;
};
}
+63
View File
@@ -0,0 +1,63 @@
#pragma once
#include "ImXui/RenderCommands.h"
#include "xui.h"
namespace ImXui {
class X360RenderSink : public IRenderCommandSink {
public:
X360RenderSink();
void setDevice(void* d3dDevice);
void setDelegateSink(IRenderCommandSink* sink);
void setFontRenderer(class IXuiFontRenderer* renderer);
void setFontTypeface(const wchar_t* typeface);
HXUIDC getDeviceContext() const { return m_hDC; }
void beginFrame(float width, float height);
void endFrame();
void beginScene(float width, float height);
void drawColoredQuad(const Rect& rect, const Color& color, float opacity);
void drawTexturedQuad(const Rect& rect, const std::wstring& resource,
const Color& color, float opacity);
void drawText(const Rect& rect, const std::wstring& text,
const std::wstring& fontName, float fontSize,
const Color& color, float opacity, bool centered);
void pushTransform(const Transform2D& t);
void popTransform();
void pushClip(const Rect& r);
void popClip();
void drawNineGrid(const Rect&, const std::wstring&, const Color&, float,
uint32_t, uint32_t, uint32_t, uint32_t, bool);
void drawFigure(const Rect&, const std::vector<Vec2>&, bool,
const Color&, const Color&, float, float, uint32_t);
void setBlendMode(uint32_t mode);
void drawCustom(const std::wstring& drawId, const Rect&, float opacity);
void endScene();
private:
bool drawQuadD3D(const Rect& rect, uint32_t abgr);
void flushText(const Rect& rect, const std::wstring& text,
const Color& color, float fontSize, bool centered);
void* m_device;
IRenderCommandSink* m_delegate;
class IXuiFontRenderer* m_fontRenderer;
HFONTOBJ m_font;
std::wstring m_typeface;
HXUIDC m_hDC;
Transform2D m_transform;
Rect m_clip;
uint32_t m_blendMode;
float m_width;
float m_height;
int m_clipDepth;
};
}
+25
View File
@@ -0,0 +1,25 @@
#pragma once
#include <string>
#include <fstream>
#include <sstream>
namespace ImXui {
class Element;
class Control;
class Scene;
class XuiXmlWriter {
public:
static bool writeFile(const std::string& path, const Scene* scene);
static std::string serialize(const Scene* scene);
private:
static void writeElement(std::ostringstream& out, const Element* el, int indent);
static void writeControlProps(std::ostringstream& out, const Control* ctrl, int indent);
static void writeSceneProps(std::ostringstream& out, const Scene* scene, int indent);
static void indentLine(std::ostringstream& out, int level);
};
}
+237
View File
@@ -0,0 +1,237 @@
#pragma once
#include <cstdint>
#include <cstring>
#include <string>
#include <vector>
#include <memory>
#include <unordered_map>
namespace ImXui {
namespace XurFormat {
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
# include <stdlib.h>
# define BSWAP16(x) _byteswap_ushort((unsigned short)(x))
# define BSWAP32(x) _byteswap_ulong((unsigned long)(x))
#else
# define BSWAP16(x) (((x) >> 8) | ((x) << 8))
# define BSWAP32(x) ((((x) >> 24) & 0xFF) | (((x) >> 8) & 0xFF00) | (((x) << 8) & 0xFF0000) | (((x) << 24) & 0xFF000000))
#endif
inline uint16_t swap16(uint16_t v) { return BSWAP16(v); }
inline uint32_t swap32(uint32_t v) { return BSWAP32(v); }
inline float swapFloat(uint32_t v) {
uint32_t swapped = swap32(v);
float result;
memcpy(&result, &swapped, 4);
return result;
}
const uint32_t MAGIC_XUIB = 0x58554942;
const uint32_t MAGIC_STRN = 0x5354524E;
const uint32_t MAGIC_VECT = 0x56454354;
const uint32_t MAGIC_QUAT = 0x51554154;
const uint32_t MAGIC_CUST = 0x43555354;
const uint32_t MAGIC_DATA = 0x44415441;
#pragma pack(push, 1)
struct XurHeader {
char magic[4];
uint32_t version;
uint32_t flags;
uint16_t toolVersion;
uint32_t fileSize;
uint16_t sectionsCount;
bool isValid() const {
return memcmp(magic, "XUIB", 4) == 0 && swap32(version) == 5;
}
uint32_t getFlags() const { return swap32(flags); }
uint32_t getFileSize() const { return swap32(fileSize); }
uint16_t getSectionsCount() const { return swap16(sectionsCount); }
};
struct XurCountHeader {
uint32_t totalObjectsCount;
uint32_t totalPropertiesCount;
uint32_t totalPropertiesArrayCount;
uint32_t keyframePropertiesCount;
uint32_t totalKeyframePropertyClassDepth;
uint32_t keyframePropertyDefinitionsCount;
uint32_t keyframesCount;
uint32_t timelinesCount;
uint32_t namedFramesCount;
uint32_t objectsWithChildrenCount;
void fromBE() {
totalObjectsCount = swap32(totalObjectsCount);
totalPropertiesCount = swap32(totalPropertiesCount);
totalPropertiesArrayCount = swap32(totalPropertiesArrayCount);
keyframePropertiesCount = swap32(keyframePropertiesCount);
totalKeyframePropertyClassDepth = swap32(totalKeyframePropertyClassDepth);
keyframePropertyDefinitionsCount = swap32(keyframePropertyDefinitionsCount);
keyframesCount = swap32(keyframesCount);
timelinesCount = swap32(timelinesCount);
namedFramesCount = swap32(namedFramesCount);
objectsWithChildrenCount = swap32(objectsWithChildrenCount);
}
};
struct XurSectionEntry {
uint32_t magic;
uint32_t offset;
uint32_t length;
void fromBE() {
magic = swap32(magic);
offset = swap32(offset);
length = swap32(length);
}
};
#pragma pack(pop)
struct XurVector { float x, y, z; };
struct XurQuaternion { float x, y, z, w; };
struct XurPoint { float x, y; };
struct XurBezierPoint { XurPoint point; XurPoint controlOne; XurPoint controlTwo; };
struct XurFigure { XurPoint boundingBox; std::vector<XurBezierPoint> points; };
struct XurColor { uint8_t a, r, g, b; };
enum XurPropertyType {
XurPropertyType_Bool = 0,
XurPropertyType_Integer = 1,
XurPropertyType_Unsigned = 2,
XurPropertyType_Float = 3,
XurPropertyType_String = 4,
XurPropertyType_Vector = 5,
XurPropertyType_Object = 6,
XurPropertyType_Colour = 7,
XurPropertyType_Custom = 8,
XurPropertyType_Quaternion = 9,
};
struct XurProperty;
class XurPropertyValue {
public:
XurPropertyType type;
bool boolVal;
int32_t intVal;
uint32_t uintVal;
float floatVal;
std::wstring stringVal;
XurVector vectorVal;
XurQuaternion quatVal;
XurColor colorVal;
XurFigure figureVal;
std::vector<XurProperty> compoundVal;
XurPropertyValue();
explicit XurPropertyValue(bool v);
explicit XurPropertyValue(int32_t v);
explicit XurPropertyValue(uint32_t v);
explicit XurPropertyValue(float v);
explicit XurPropertyValue(const std::wstring& v);
explicit XurPropertyValue(const XurVector& v);
explicit XurPropertyValue(const XurQuaternion& v);
explicit XurPropertyValue(const XurColor& v);
explicit XurPropertyValue(const XurFigure& v);
explicit XurPropertyValue(const std::vector<XurProperty>& v);
XurPropertyValue(const XurPropertyValue& other);
XurPropertyValue& operator=(const XurPropertyValue& other);
~XurPropertyValue();
};
struct XurProperty {
std::string name;
XurPropertyType type;
XurPropertyValue value;
};
enum XurNamedFrameCommand {
XurNamedFrameCommand_None = 0,
XurNamedFrameCommand_Stop = 1,
XurNamedFrameCommand_GotoAndStop = 2,
XurNamedFrameCommand_GotoAndPlay = 3,
XurNamedFrameCommand_Play = 4,
};
struct XurNamedFrame {
std::wstring name;
int32_t keyframe;
XurNamedFrameCommand command;
std::wstring targetParameter;
};
enum XurInterpolationType {
XurInterpolationType_None = 0,
XurInterpolationType_Linear = 1,
XurInterpolationType_EaseIn = 2,
XurInterpolationType_EaseOut = 3,
XurInterpolationType_EaseInOut = 4,
};
struct XurKeyframe {
int32_t time;
XurInterpolationType interpolation;
uint8_t easeIn;
uint8_t easeOut;
uint8_t easeScale;
std::vector<XurProperty> properties;
};
struct XurTimeline {
std::wstring elementName;
std::vector<XurKeyframe> keyframes;
};
struct XurObject {
std::string className;
std::vector<XurProperty> properties;
std::vector<XurObject> children;
std::vector<XurNamedFrame> namedFrames;
std::vector<XurTimeline> timelines;
};
struct XurDocument {
XurHeader header;
std::vector<std::wstring> strings;
std::vector<XurVector> vectors;
std::vector<XurQuaternion> quaternions;
std::vector<XurFigure> figures;
XurObject rootObject;
std::vector<uint8_t> rawData;
};
struct XuiPropDef {
std::string name;
XurPropertyType type;
bool indexed;
};
struct XuiClassInfo {
std::string name;
std::string baseClass;
std::vector<XuiPropDef> props;
};
class XuiClassRegistry {
public:
static const XuiClassInfo* findClass(const std::string& name);
static std::vector<const XuiClassInfo*> getHierarchy(const std::string& className);
static void initialize();
};
class XurParser {
public:
static std::unique_ptr<XurDocument> parse(const void* data, size_t size);
static std::unique_ptr<XurDocument> parseFromFile(const std::string& path);
static bool validate(const XurDocument* doc);
};
}
}
+60
View File
@@ -0,0 +1,60 @@
#pragma once
#include "XurFormat.h"
#include <string>
#include <vector>
#include <cstdint>
namespace ImXui {
class Element;
class Scene;
namespace XurFormat {
struct MemBuf {
std::vector<uint8_t> data;
void write(const void* d, size_t sz);
template<typename T> void writeBE(T v);
void writeU8(uint8_t v);
void writeU16BE(uint16_t v);
void writeU32BE(uint32_t v);
void writeS16BE(int16_t v);
void writeS32BE(int32_t v);
void writeFloatBE(float v);
uint32_t tell() const;
};
struct WriteContext {
std::vector<std::wstring> strings;
std::vector<XurVector> vectors;
std::vector<XurQuaternion> quaternions;
std::vector<XurFigure> figures;
int addString(const std::wstring& s);
int addVector(const XurVector& v);
int addQuaternion(const XurQuaternion& q);
int addFigure(const XurFigure& f);
};
class XurWriter {
public:
static bool writeToFile(const std::string& path, const XurObject& root);
static std::vector<uint8_t> serialize(const XurObject& root);
private:
static void writePropValue(MemBuf& buf, WriteContext& ctx, const XurPropertyValue& val);
static void writeProperties(MemBuf& buf, WriteContext& ctx, const XurObject& obj);
static void writeObject(MemBuf& buf, WriteContext& ctx, const XurObject& obj);
static void writeStrnSection(MemBuf& out, WriteContext& ctx);
static void writeVectSection(MemBuf& out, WriteContext& ctx);
static void writeQuatSection(MemBuf& out, WriteContext& ctx);
static void writeCustSection(MemBuf& out, WriteContext& ctx);
static void writeDataSection(MemBuf& out, WriteContext& ctx, const XurObject& root);
};
XurObject elementToXurObject(const Element* el);
XurObject sceneToXurObject(const Scene* scene);
}
}
+20
View File
@@ -0,0 +1,20 @@
#pragma once
#include "XurFormat.h"
#include <string>
namespace ImXui {
namespace XurFormat {
XurObject xuiXmlToObject(const std::string& xml);
std::string xurObjectToXuiXml(const XurObject& root);
bool xurObjectToXuiXml(const XurObject& root, const std::string& path);
XurObject xuiFileToObject(const std::string& path);
}
}
+66
View File
@@ -0,0 +1,66 @@
#pragma once
#include <cstdint>
#include <map>
#include <string>
#include <vector>
namespace ImXui {
class XzpPackage {
public:
struct Entry {
std::string name;
uint32_t offset;
uint32_t size;
Entry() : offset(0), size(0) {}
};
XzpPackage();
~XzpPackage();
bool openMemory(const void* data, size_t size);
bool openFile(const std::string& path);
bool isOpen() const { return m_open; }
int getVersion() const { return m_version; }
size_t getEntryCount() const { return m_entries.size(); }
const std::vector<Entry>& getEntries() const { return m_entries; }
const Entry* findEntry(const std::string& name) const;
bool readEntry(const Entry& entry, std::vector<uint8_t>& out) const;
bool readEntryByName(const std::string& name, std::vector<uint8_t>& out) const;
const uint8_t* entryData(const Entry& entry) const;
private:
void reset();
bool m_open;
int m_version;
std::vector<uint8_t> m_buffer;
std::vector<Entry> m_entries;
std::map<std::string, size_t> m_byName;
};
class XzpWriter {
public:
void addFile(const std::string& name, const void* data, size_t size);
bool build(std::vector<uint8_t>& out) const;
private:
struct Item {
std::string name;
std::vector<uint8_t> data;
};
std::vector<Item> m_items;
};
}