refactor(ui): 移除UI组件的链式调用方法并重构文档注释
重构所有UI组件头文件,移除链式调用构建器方法 为UI组件添加详细的文档注释,说明各方法和属性的用途 调整部分实现文件的结构,使其更加清晰易读
This commit is contained in:
parent
b78c493590
commit
866fd4b1ff
|
|
@ -32,35 +32,6 @@ public:
|
|||
static Ptr<Button> create(const std::string &text);
|
||||
static Ptr<Button> create(const std::string &text, Ptr<FontAtlas> font);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用构建器方法
|
||||
// ------------------------------------------------------------------------
|
||||
Button *withPosition(float x, float y);
|
||||
Button *withPosition(const Vec2 &pos);
|
||||
Button *withAnchor(float x, float y);
|
||||
Button *withAnchor(const Vec2 &anchor);
|
||||
Button *withText(const std::string &text);
|
||||
Button *withFont(Ptr<FontAtlas> font);
|
||||
Button *withTextColor(const Color &color);
|
||||
Button *withBackgroundColor(const Color &normal, const Color &hover,
|
||||
const Color &pressed);
|
||||
Button *withSize(float width, float height);
|
||||
Button *withPadding(const Vec2 &padding);
|
||||
Button *withPadding(float x, float y);
|
||||
Button *withBorder(const Color &color, float width);
|
||||
Button *withCornerRadius(float radius);
|
||||
Button *withRoundedCornersEnabled(bool enabled);
|
||||
Button *withHoverCursor(CursorShape cursor);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用 - 坐标空间设置
|
||||
// ------------------------------------------------------------------------
|
||||
Button *withCoordinateSpace(CoordinateSpace space);
|
||||
Button *withScreenPosition(float x, float y);
|
||||
Button *withScreenPosition(const Vec2 &pos);
|
||||
Button *withCameraOffset(float x, float y);
|
||||
Button *withCameraOffset(const Vec2 &offset);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 文字内容
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
@ -77,6 +48,7 @@ public:
|
|||
// 内边距
|
||||
// ------------------------------------------------------------------------
|
||||
void setPadding(const Vec2 &padding);
|
||||
void setPadding(float x, float y);
|
||||
Vec2 getPadding() const { return padding_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -18,45 +18,45 @@ public:
|
|||
static Ptr<CheckBox> create(const std::string &label);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用构建器方法
|
||||
// 选中状态
|
||||
// ------------------------------------------------------------------------
|
||||
CheckBox *withPosition(float x, float y);
|
||||
CheckBox *withPosition(const Vec2 &pos);
|
||||
CheckBox *withAnchor(float x, float y);
|
||||
CheckBox *withAnchor(const Vec2 &anchor);
|
||||
CheckBox *withText(const std::string &text);
|
||||
CheckBox *withFont(Ptr<FontAtlas> font);
|
||||
CheckBox *withTextColor(const Color &color);
|
||||
CheckBox *withSize(float width, float height);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用 - 坐标空间设置
|
||||
// ------------------------------------------------------------------------
|
||||
CheckBox *withCoordinateSpace(CoordinateSpace space);
|
||||
CheckBox *withScreenPosition(float x, float y);
|
||||
CheckBox *withScreenPosition(const Vec2 &pos);
|
||||
CheckBox *withCameraOffset(float x, float y);
|
||||
CheckBox *withCameraOffset(const Vec2 &offset);
|
||||
|
||||
void setChecked(bool checked);
|
||||
bool isChecked() const { return checked_; }
|
||||
void toggle();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 标签设置
|
||||
// ------------------------------------------------------------------------
|
||||
void setLabel(const std::string &label);
|
||||
const std::string &getLabel() const { return label_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 字体设置
|
||||
// ------------------------------------------------------------------------
|
||||
void setFont(Ptr<FontAtlas> font);
|
||||
Ptr<FontAtlas> getFont() const { return font_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 文字颜色
|
||||
// ------------------------------------------------------------------------
|
||||
void setTextColor(const Color &color);
|
||||
Color getTextColor() const { return textColor_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 复选框尺寸
|
||||
// ------------------------------------------------------------------------
|
||||
void setBoxSize(float size);
|
||||
float getBoxSize() const { return boxSize_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 间距
|
||||
// ------------------------------------------------------------------------
|
||||
void setSpacing(float spacing);
|
||||
float getSpacing() const { return spacing_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 颜色设置
|
||||
// ------------------------------------------------------------------------
|
||||
void setCheckedColor(const Color &color);
|
||||
Color getCheckedColor() const { return checkedColor_; }
|
||||
|
||||
|
|
@ -66,6 +66,9 @@ public:
|
|||
void setCheckMarkColor(const Color &color);
|
||||
Color getCheckMarkColor() const { return checkMarkColor_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 回调设置
|
||||
// ------------------------------------------------------------------------
|
||||
void setOnStateChange(Function<void(bool)> callback);
|
||||
|
||||
Rect getBoundingBox() const override;
|
||||
|
|
|
|||
|
|
@ -23,27 +23,6 @@ public:
|
|||
static Ptr<Label> create(const std::string &text);
|
||||
static Ptr<Label> create(const std::string &text, Ptr<FontAtlas> font);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用构建器方法
|
||||
// ------------------------------------------------------------------------
|
||||
Label *withPosition(float x, float y);
|
||||
Label *withPosition(const Vec2 &pos);
|
||||
Label *withAnchor(float x, float y);
|
||||
Label *withAnchor(const Vec2 &anchor);
|
||||
Label *withText(const std::string &text);
|
||||
Label *withFont(Ptr<FontAtlas> font);
|
||||
Label *withTextColor(const Color &color);
|
||||
Label *withFontSize(int size);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 坐标空间设置(链式调用)
|
||||
// ------------------------------------------------------------------------
|
||||
Label *withCoordinateSpace(CoordinateSpace space);
|
||||
Label *withScreenPosition(float x, float y);
|
||||
Label *withScreenPosition(const Vec2 &pos);
|
||||
Label *withCameraOffset(float x, float y);
|
||||
Label *withCameraOffset(const Vec2 &offset);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 文本内容
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
@ -143,17 +122,14 @@ private:
|
|||
HorizontalAlign hAlign_ = HorizontalAlign::Left;
|
||||
VerticalAlign vAlign_ = VerticalAlign::Top;
|
||||
|
||||
// 阴影
|
||||
bool shadowEnabled_ = false;
|
||||
Color shadowColor_ = Color(0.0f, 0.0f, 0.0f, 0.5f);
|
||||
Vec2 shadowOffset_ = Vec2(2.0f, 2.0f);
|
||||
|
||||
// 描边
|
||||
bool outlineEnabled_ = false;
|
||||
Color outlineColor_ = Colors::Black;
|
||||
float outlineWidth_ = 1.0f;
|
||||
|
||||
// 多行
|
||||
bool multiLine_ = false;
|
||||
float lineSpacing_ = 1.0f;
|
||||
float maxWidth_ = 0.0f;
|
||||
|
|
|
|||
|
|
@ -21,21 +21,6 @@ public:
|
|||
static Ptr<ProgressBar> create();
|
||||
static Ptr<ProgressBar> create(float min, float max, float value);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用构建器方法 - 坐标空间支持
|
||||
// ------------------------------------------------------------------------
|
||||
ProgressBar *withPosition(float x, float y);
|
||||
ProgressBar *withPosition(const Vec2 &pos);
|
||||
ProgressBar *withAnchor(float x, float y);
|
||||
ProgressBar *withAnchor(const Vec2 &anchor);
|
||||
ProgressBar *withSize(float width, float height);
|
||||
ProgressBar *withProgress(float progress);
|
||||
ProgressBar *withCoordinateSpace(CoordinateSpace space);
|
||||
ProgressBar *withScreenPosition(float x, float y);
|
||||
ProgressBar *withScreenPosition(const Vec2 &pos);
|
||||
ProgressBar *withCameraOffset(float x, float y);
|
||||
ProgressBar *withCameraOffset(const Vec2 &offset);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 数值范围
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -18,40 +18,44 @@ public:
|
|||
static Ptr<RadioButton> create(const std::string &label);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用构建器方法
|
||||
// 选择状态
|
||||
// ------------------------------------------------------------------------
|
||||
RadioButton *withPosition(float x, float y);
|
||||
RadioButton *withPosition(const Vec2 &pos);
|
||||
RadioButton *withAnchor(float x, float y);
|
||||
RadioButton *withAnchor(const Vec2 &anchor);
|
||||
RadioButton *withText(const std::string &text);
|
||||
RadioButton *withFont(Ptr<FontAtlas> font);
|
||||
RadioButton *withTextColor(const Color &color);
|
||||
RadioButton *withSize(float width, float height);
|
||||
RadioButton *withCoordinateSpace(CoordinateSpace space);
|
||||
RadioButton *withScreenPosition(float x, float y);
|
||||
RadioButton *withScreenPosition(const Vec2 &pos);
|
||||
RadioButton *withCameraOffset(float x, float y);
|
||||
RadioButton *withCameraOffset(const Vec2 &offset);
|
||||
|
||||
void setSelected(bool selected);
|
||||
bool isSelected() const { return selected_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 标签设置
|
||||
// ------------------------------------------------------------------------
|
||||
void setLabel(const std::string &label);
|
||||
const std::string &getLabel() const { return label_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 字体设置
|
||||
// ------------------------------------------------------------------------
|
||||
void setFont(Ptr<FontAtlas> font);
|
||||
Ptr<FontAtlas> getFont() const { return font_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 文字颜色
|
||||
// ------------------------------------------------------------------------
|
||||
void setTextColor(const Color &color);
|
||||
Color getTextColor() const { return textColor_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 圆形尺寸
|
||||
// ------------------------------------------------------------------------
|
||||
void setCircleSize(float size);
|
||||
float getCircleSize() const { return circleSize_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 间距
|
||||
// ------------------------------------------------------------------------
|
||||
void setSpacing(float spacing);
|
||||
float getSpacing() const { return spacing_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 颜色设置
|
||||
// ------------------------------------------------------------------------
|
||||
void setSelectedColor(const Color &color);
|
||||
Color getSelectedColor() const { return selectedColor_; }
|
||||
|
||||
|
|
@ -61,9 +65,15 @@ public:
|
|||
void setDotColor(const Color &color);
|
||||
Color getDotColor() const { return dotColor_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 分组
|
||||
// ------------------------------------------------------------------------
|
||||
void setGroupId(int groupId);
|
||||
int getGroupId() const { return groupId_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 回调设置
|
||||
// ------------------------------------------------------------------------
|
||||
void setOnStateChange(Function<void(bool)> callback);
|
||||
|
||||
Rect getBoundingBox() const override;
|
||||
|
|
@ -86,7 +96,7 @@ private:
|
|||
Color unselectedColor_ = Color(0.3f, 0.3f, 0.3f, 1.0f);
|
||||
Color dotColor_ = Colors::White;
|
||||
|
||||
int groupId_ = 0; // 用于分组,同组内只能选一个
|
||||
int groupId_ = 0;
|
||||
|
||||
bool pressed_ = false;
|
||||
Function<void(bool)> onStateChange_;
|
||||
|
|
|
|||
|
|
@ -18,41 +18,45 @@ public:
|
|||
static Ptr<Slider> create(float min, float max, float value);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用构建器方法
|
||||
// 数值范围
|
||||
// ------------------------------------------------------------------------
|
||||
Slider *withPosition(float x, float y);
|
||||
Slider *withPosition(const Vec2 &pos);
|
||||
Slider *withAnchor(float x, float y);
|
||||
Slider *withAnchor(const Vec2 &anchor);
|
||||
Slider *withSize(float width, float height);
|
||||
Slider *withMinValue(float min);
|
||||
Slider *withMaxValue(float max);
|
||||
Slider *withValue(float value);
|
||||
Slider *withCoordinateSpace(CoordinateSpace space);
|
||||
Slider *withScreenPosition(float x, float y);
|
||||
Slider *withScreenPosition(const Vec2 &pos);
|
||||
Slider *withCameraOffset(float x, float y);
|
||||
Slider *withCameraOffset(const Vec2 &offset);
|
||||
|
||||
void setRange(float min, float max);
|
||||
float getMin() const { return min_; }
|
||||
float getMax() const { return max_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 当前值
|
||||
// ------------------------------------------------------------------------
|
||||
void setValue(float value);
|
||||
float getValue() const { return value_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 步进值
|
||||
// ------------------------------------------------------------------------
|
||||
void setStep(float step);
|
||||
float getStep() const { return step_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 方向
|
||||
// ------------------------------------------------------------------------
|
||||
void setVertical(bool vertical);
|
||||
bool isVertical() const { return vertical_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 轨道尺寸
|
||||
// ------------------------------------------------------------------------
|
||||
void setTrackSize(float size);
|
||||
float getTrackSize() const { return trackSize_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 滑块尺寸
|
||||
// ------------------------------------------------------------------------
|
||||
void setThumbSize(float size);
|
||||
float getThumbSize() const { return thumbSize_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 颜色设置
|
||||
// ------------------------------------------------------------------------
|
||||
void setTrackColor(const Color &color);
|
||||
Color getTrackColor() const { return trackColor_; }
|
||||
|
||||
|
|
@ -68,12 +72,18 @@ public:
|
|||
void setThumbPressedColor(const Color &color);
|
||||
Color getThumbPressedColor() const { return thumbPressedColor_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 显示设置
|
||||
// ------------------------------------------------------------------------
|
||||
void setShowThumb(bool show);
|
||||
bool isShowThumb() const { return showThumb_; }
|
||||
|
||||
void setShowFill(bool show);
|
||||
bool isShowFill() const { return showFill_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 文本显示
|
||||
// ------------------------------------------------------------------------
|
||||
void setTextEnabled(bool enabled);
|
||||
bool isTextEnabled() const { return textEnabled_; }
|
||||
|
||||
|
|
@ -86,6 +96,9 @@ public:
|
|||
void setTextFormat(const std::string &format);
|
||||
const std::string &getTextFormat() const { return textFormat_; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 回调设置
|
||||
// ------------------------------------------------------------------------
|
||||
void setOnValueChange(Function<void(float)> callback);
|
||||
void setOnDragStart(Function<void()> callback);
|
||||
void setOnDragEnd(Function<void()> callback);
|
||||
|
|
@ -104,7 +117,7 @@ private:
|
|||
float min_ = 0.0f;
|
||||
float max_ = 100.0f;
|
||||
float value_ = 50.0f;
|
||||
float step_ = 0.0f; // 0表示无步进
|
||||
float step_ = 0.0f;
|
||||
|
||||
bool vertical_ = false;
|
||||
float trackSize_ = 6.0f;
|
||||
|
|
|
|||
|
|
@ -41,19 +41,6 @@ public:
|
|||
static Ptr<Text> createFormat(const char *fmt, ...);
|
||||
static Ptr<Text> createFormat(Ptr<FontAtlas> font, const char *fmt, ...);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用构建器方法
|
||||
// ------------------------------------------------------------------------
|
||||
Text *withPosition(float x, float y);
|
||||
Text *withPosition(const Vec2 &pos);
|
||||
Text *withAnchor(float x, float y);
|
||||
Text *withAnchor(const Vec2 &anchor);
|
||||
Text *withTextColor(const Color &color);
|
||||
Text *withFont(Ptr<FontAtlas> font);
|
||||
Text *withFontSize(int size);
|
||||
Text *withAlignment(Alignment align);
|
||||
Text *withVerticalAlignment(VerticalAlignment align);
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 文字内容
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
@ -78,20 +65,6 @@ public:
|
|||
updateSpatialIndex();
|
||||
}
|
||||
|
||||
// 链式调用的格式化方法
|
||||
// 注意:由于C++可变参数的限制,链式调用需要单独设置格式和值
|
||||
Text *withFormattedText(const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
char buffer[256];
|
||||
vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||
va_end(args);
|
||||
text_ = buffer;
|
||||
sizeDirty_ = true;
|
||||
updateSpatialIndex();
|
||||
return this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 字体
|
||||
// ------------------------------------------------------------------------
|
||||
|
|
@ -127,15 +100,6 @@ public:
|
|||
|
||||
Rect getBoundingBox() const override;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用 - 坐标空间设置
|
||||
// ------------------------------------------------------------------------
|
||||
Text *withCoordinateSpace(CoordinateSpace space);
|
||||
Text *withScreenPosition(float x, float y);
|
||||
Text *withScreenPosition(const Vec2 &pos);
|
||||
Text *withCameraOffset(float x, float y);
|
||||
Text *withCameraOffset(const Vec2 &offset);
|
||||
|
||||
protected:
|
||||
void onDrawWidget(RenderBackend &renderer) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,10 @@ namespace extra2d {
|
|||
// Button 实现
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief 默认构造函数
|
||||
*/
|
||||
Button::Button() {
|
||||
// 按钮默认锚点为左上角,这样setPosition(0, 0)会在左上角显示
|
||||
setAnchor(0.0f, 0.0f);
|
||||
setSpatialIndexed(false);
|
||||
|
||||
|
|
@ -46,133 +48,49 @@ Button::Button() {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 带文本的构造函数
|
||||
* @param text 按钮文本
|
||||
*/
|
||||
Button::Button(const std::string &text) : Button() { text_ = text; }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 静态创建方法
|
||||
// ------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief 创建空按钮对象
|
||||
* @return 按钮对象指针
|
||||
*/
|
||||
Ptr<Button> Button::create() { return makePtr<Button>(); }
|
||||
|
||||
/**
|
||||
* @brief 创建带文本的按钮对象
|
||||
* @param text 按钮文本
|
||||
* @return 按钮对象指针
|
||||
*/
|
||||
Ptr<Button> Button::create(const std::string &text) {
|
||||
return makePtr<Button>(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 创建带文本和字体的按钮对象
|
||||
* @param text 按钮文本
|
||||
* @param font 字体图集
|
||||
* @return 按钮对象指针
|
||||
*/
|
||||
Ptr<Button> Button::create(const std::string &text, Ptr<FontAtlas> font) {
|
||||
auto btn = makePtr<Button>(text);
|
||||
btn->setFont(font);
|
||||
return btn;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用构建器方法
|
||||
// ------------------------------------------------------------------------
|
||||
Button *Button::withPosition(float x, float y) {
|
||||
setPosition(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withPosition(const Vec2 &pos) {
|
||||
setPosition(pos);
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withAnchor(float x, float y) {
|
||||
setAnchor(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withAnchor(const Vec2 &anchor) {
|
||||
setAnchor(anchor);
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withText(const std::string &text) {
|
||||
setText(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withFont(Ptr<FontAtlas> font) {
|
||||
setFont(font);
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withTextColor(const Color &color) {
|
||||
setTextColor(color);
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withBackgroundColor(const Color &normal, const Color &hover,
|
||||
const Color &pressed) {
|
||||
setBackgroundColor(normal, hover, pressed);
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withSize(float width, float height) {
|
||||
setSize(width, height);
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withPadding(const Vec2 &padding) {
|
||||
setPadding(padding);
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withPadding(float x, float y) {
|
||||
setPadding(Vec2(x, y));
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withBorder(const Color &color, float width) {
|
||||
setBorder(color, width);
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withCornerRadius(float radius) {
|
||||
setCornerRadius(radius);
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withRoundedCornersEnabled(bool enabled) {
|
||||
setRoundedCornersEnabled(enabled);
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withHoverCursor(CursorShape cursor) {
|
||||
setHoverCursor(cursor);
|
||||
return this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用 - 坐标空间设置
|
||||
// ------------------------------------------------------------------------
|
||||
Button *Button::withCoordinateSpace(CoordinateSpace space) {
|
||||
setCoordinateSpace(space);
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withScreenPosition(float x, float y) {
|
||||
setScreenPosition(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withScreenPosition(const Vec2 &pos) {
|
||||
setScreenPosition(pos);
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withCameraOffset(float x, float y) {
|
||||
setCameraOffset(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
Button *Button::withCameraOffset(const Vec2 &offset) {
|
||||
setCameraOffset(offset);
|
||||
return this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 普通设置方法
|
||||
// ------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief 设置按钮文本
|
||||
* @param text 文本内容
|
||||
*/
|
||||
void Button::setText(const std::string &text) {
|
||||
text_ = text;
|
||||
if (font_ && getSize().empty()) {
|
||||
|
|
@ -181,6 +99,10 @@ void Button::setText(const std::string &text) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置字体
|
||||
* @param font 字体图集指针
|
||||
*/
|
||||
void Button::setFont(Ptr<FontAtlas> font) {
|
||||
font_ = font;
|
||||
if (font_ && getSize().empty() && !text_.empty()) {
|
||||
|
|
@ -189,6 +111,10 @@ void Button::setFont(Ptr<FontAtlas> font) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置内边距(Vec2版本)
|
||||
* @param padding 内边距向量
|
||||
*/
|
||||
void Button::setPadding(const Vec2 &padding) {
|
||||
padding_ = padding;
|
||||
if (font_ && getSize().empty() && !text_.empty()) {
|
||||
|
|
@ -197,8 +123,27 @@ void Button::setPadding(const Vec2 &padding) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置内边距(分量版本)
|
||||
* @param x X方向内边距
|
||||
* @param y Y方向内边距
|
||||
*/
|
||||
void Button::setPadding(float x, float y) {
|
||||
setPadding(Vec2(x, y));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置文本颜色
|
||||
* @param color 文本颜色
|
||||
*/
|
||||
void Button::setTextColor(const Color &color) { textColor_ = color; }
|
||||
|
||||
/**
|
||||
* @brief 设置背景颜色
|
||||
* @param normal 普通状态颜色
|
||||
* @param hover 悬停状态颜色
|
||||
* @param pressed 按下状态颜色
|
||||
*/
|
||||
void Button::setBackgroundColor(const Color &normal, const Color &hover,
|
||||
const Color &pressed) {
|
||||
bgNormal_ = normal;
|
||||
|
|
@ -206,29 +151,58 @@ void Button::setBackgroundColor(const Color &normal, const Color &hover,
|
|||
bgPressed_ = pressed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置边框
|
||||
* @param color 边框颜色
|
||||
* @param width 边框宽度
|
||||
*/
|
||||
void Button::setBorder(const Color &color, float width) {
|
||||
borderColor_ = color;
|
||||
borderWidth_ = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置圆角半径
|
||||
* @param radius 圆角半径
|
||||
*/
|
||||
void Button::setCornerRadius(float radius) {
|
||||
cornerRadius_ = std::max(0.0f, radius);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置是否启用圆角
|
||||
* @param enabled 是否启用
|
||||
*/
|
||||
void Button::setRoundedCornersEnabled(bool enabled) {
|
||||
roundedCornersEnabled_ = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置是否使用Alpha遮罩进行点击检测
|
||||
* @param enabled 是否启用
|
||||
*/
|
||||
void Button::setUseAlphaMaskForHitTest(bool enabled) {
|
||||
useAlphaMaskForHitTest_ = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置点击回调
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
void Button::setOnClick(Function<void()> callback) {
|
||||
onClick_ = std::move(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置是否为切换模式
|
||||
* @param enabled 是否启用
|
||||
*/
|
||||
void Button::setToggleMode(bool enabled) { toggleMode_ = enabled; }
|
||||
|
||||
/**
|
||||
* @brief 设置开关状态
|
||||
* @param on 是否开启
|
||||
*/
|
||||
void Button::setOn(bool on) {
|
||||
if (isOn_ != on) {
|
||||
isOn_ = on;
|
||||
|
|
@ -238,12 +212,24 @@ void Button::setOn(bool on) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 切换状态
|
||||
*/
|
||||
void Button::toggle() { setOn(!isOn_); }
|
||||
|
||||
/**
|
||||
* @brief 设置状态改变回调
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
void Button::setOnStateChange(Function<void(bool)> callback) {
|
||||
onStateChange_ = std::move(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置状态文字
|
||||
* @param textOff 关闭状态文字
|
||||
* @param textOn 开启状态文字
|
||||
*/
|
||||
void Button::setStateText(const std::string &textOff,
|
||||
const std::string &textOn) {
|
||||
textOff_ = textOff;
|
||||
|
|
@ -251,14 +237,29 @@ void Button::setStateText(const std::string &textOff,
|
|||
useStateText_ = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置状态文字颜色
|
||||
* @param colorOff 关闭状态颜色
|
||||
* @param colorOn 开启状态颜色
|
||||
*/
|
||||
void Button::setStateTextColor(const Color &colorOff, const Color &colorOn) {
|
||||
textColorOff_ = colorOff;
|
||||
textColorOn_ = colorOn;
|
||||
useStateTextColor_ = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置悬停光标
|
||||
* @param cursor 光标形状
|
||||
*/
|
||||
void Button::setHoverCursor(CursorShape cursor) { hoverCursor_ = cursor; }
|
||||
|
||||
/**
|
||||
* @brief 设置背景图片
|
||||
* @param normal 普通状态图片
|
||||
* @param hover 悬停状态图片
|
||||
* @param pressed 按下状态图片
|
||||
*/
|
||||
void Button::setBackgroundImage(Ptr<Texture> normal, Ptr<Texture> hover,
|
||||
Ptr<Texture> pressed) {
|
||||
imgNormal_ = normal;
|
||||
|
|
@ -273,6 +274,11 @@ void Button::setBackgroundImage(Ptr<Texture> normal, Ptr<Texture> hover,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置背景图片(带矩形区域)
|
||||
* @param texture 纹理
|
||||
* @param rect 矩形区域
|
||||
*/
|
||||
void Button::setBackgroundImage(Ptr<Texture> texture, const Rect &rect) {
|
||||
imgNormal_ = texture;
|
||||
imgHover_ = texture;
|
||||
|
|
@ -289,6 +295,15 @@ void Button::setBackgroundImage(Ptr<Texture> texture, const Rect &rect) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置状态背景图片
|
||||
* @param offNormal 关闭状态普通图片
|
||||
* @param onNormal 开启状态普通图片
|
||||
* @param offHover 关闭状态悬停图片
|
||||
* @param onHover 开启状态悬停图片
|
||||
* @param offPressed 关闭状态按下图片
|
||||
* @param onPressed 开启状态按下图片
|
||||
*/
|
||||
void Button::setStateBackgroundImage(
|
||||
Ptr<Texture> offNormal, Ptr<Texture> onNormal, Ptr<Texture> offHover,
|
||||
Ptr<Texture> onHover, Ptr<Texture> offPressed, Ptr<Texture> onPressed) {
|
||||
|
|
@ -309,6 +324,10 @@ void Button::setStateBackgroundImage(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置背景图片缩放模式
|
||||
* @param mode 缩放模式
|
||||
*/
|
||||
void Button::setBackgroundImageScaleMode(ImageScaleMode mode) {
|
||||
scaleMode_ = mode;
|
||||
if (useImageBackground_ && scaleMode_ == ImageScaleMode::Original &&
|
||||
|
|
@ -318,12 +337,25 @@ void Button::setBackgroundImageScaleMode(ImageScaleMode mode) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置自定义尺寸(Vec2版本)
|
||||
* @param size 尺寸向量
|
||||
*/
|
||||
void Button::setCustomSize(const Vec2 &size) { setSize(size.x, size.y); }
|
||||
|
||||
/**
|
||||
* @brief 设置自定义尺寸(分量版本)
|
||||
* @param width 宽度
|
||||
* @param height 高度
|
||||
*/
|
||||
void Button::setCustomSize(float width, float height) {
|
||||
setSize(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取边界框
|
||||
* @return 边界矩形
|
||||
*/
|
||||
Rect Button::getBoundingBox() const {
|
||||
auto pos = getRenderPosition();
|
||||
auto anchor = getAnchor();
|
||||
|
|
@ -342,6 +374,12 @@ Rect Button::getBoundingBox() const {
|
|||
return Rect(x0, y0, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 计算图片尺寸
|
||||
* @param buttonSize 按钮尺寸
|
||||
* @param imageSize 图片尺寸
|
||||
* @return 计算后的图片尺寸
|
||||
*/
|
||||
Vec2 Button::calculateImageSize(const Vec2 &buttonSize, const Vec2 &imageSize) {
|
||||
switch (scaleMode_) {
|
||||
case ImageScaleMode::Original:
|
||||
|
|
@ -367,11 +405,15 @@ Vec2 Button::calculateImageSize(const Vec2 &buttonSize, const Vec2 &imageSize) {
|
|||
return imageSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 绘制背景图片
|
||||
* @param renderer 渲染后端
|
||||
* @param rect 绘制区域
|
||||
*/
|
||||
void Button::drawBackgroundImage(RenderBackend &renderer, const Rect &rect) {
|
||||
Texture *texture = nullptr;
|
||||
Rect srcRect;
|
||||
|
||||
// 如果使用状态图片,根据 isOn_ 状态选择对应的图片
|
||||
if (useStateImages_) {
|
||||
if (isOn_) {
|
||||
if (pressed_ && imgOnPressed_) {
|
||||
|
|
@ -395,7 +437,6 @@ void Button::drawBackgroundImage(RenderBackend &renderer, const Rect &rect) {
|
|||
static_cast<float>(texture->getHeight()));
|
||||
}
|
||||
} else {
|
||||
// 使用普通图片背景
|
||||
if (pressed_ && imgPressed_) {
|
||||
texture = imgPressed_.get();
|
||||
srcRect = useTextureRect_
|
||||
|
|
@ -433,6 +474,13 @@ void Button::drawBackgroundImage(RenderBackend &renderer, const Rect &rect) {
|
|||
Vec2::Zero());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 绘制圆角矩形边框
|
||||
* @param renderer 渲染后端
|
||||
* @param rect 矩形区域
|
||||
* @param color 颜色
|
||||
* @param radius 圆角半径
|
||||
*/
|
||||
void Button::drawRoundedRect(RenderBackend &renderer, const Rect &rect,
|
||||
const Color &color, float radius) {
|
||||
float maxRadius = std::min(rect.size.width, rect.size.height) * 0.5f;
|
||||
|
|
@ -489,6 +537,13 @@ void Button::drawRoundedRect(RenderBackend &renderer, const Rect &rect,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 填充圆角矩形
|
||||
* @param renderer 渲染后端
|
||||
* @param rect 矩形区域
|
||||
* @param color 颜色
|
||||
* @param radius 圆角半径
|
||||
*/
|
||||
void Button::fillRoundedRect(RenderBackend &renderer, const Rect &rect,
|
||||
const Color &color, float radius) {
|
||||
float maxRadius = std::min(rect.size.width, rect.size.height) * 0.5f;
|
||||
|
|
@ -556,6 +611,10 @@ void Button::fillRoundedRect(RenderBackend &renderer, const Rect &rect,
|
|||
renderer.fillPolygon(vertices, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 绘制组件
|
||||
* @param renderer 渲染后端
|
||||
*/
|
||||
void Button::onDrawWidget(RenderBackend &renderer) {
|
||||
Rect rect = getBoundingBox();
|
||||
if (rect.empty()) {
|
||||
|
|
@ -563,7 +622,6 @@ void Button::onDrawWidget(RenderBackend &renderer) {
|
|||
}
|
||||
|
||||
if (useImageBackground_) {
|
||||
// 使用图片背景时不绘制纯色背景和边框
|
||||
drawBackgroundImage(renderer, rect);
|
||||
} else {
|
||||
renderer.endSpriteBatch();
|
||||
|
|
@ -583,7 +641,6 @@ void Button::onDrawWidget(RenderBackend &renderer) {
|
|||
|
||||
renderer.beginSpriteBatch();
|
||||
|
||||
// 纯色背景模式下才绘制边框
|
||||
renderer.endSpriteBatch();
|
||||
|
||||
if (borderWidth_ > 0.0f) {
|
||||
|
|
@ -598,7 +655,6 @@ void Button::onDrawWidget(RenderBackend &renderer) {
|
|||
}
|
||||
|
||||
if (font_) {
|
||||
// 确定要显示的文字
|
||||
std::string textToDraw;
|
||||
if (useStateText_) {
|
||||
textToDraw = isOn_ ? textOn_ : textOff_;
|
||||
|
|
@ -606,7 +662,6 @@ void Button::onDrawWidget(RenderBackend &renderer) {
|
|||
textToDraw = text_;
|
||||
}
|
||||
|
||||
// 确定文字颜色
|
||||
Color colorToUse;
|
||||
if (useStateTextColor_) {
|
||||
colorToUse = isOn_ ? textColorOn_ : textColorOff_;
|
||||
|
|
|
|||
|
|
@ -4,92 +4,37 @@
|
|||
|
||||
namespace extra2d {
|
||||
|
||||
/**
|
||||
* @brief 默认构造函数
|
||||
*/
|
||||
CheckBox::CheckBox() {
|
||||
setAnchor(0.0f, 0.0f);
|
||||
setSize(boxSize_, boxSize_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 创建复选框对象
|
||||
* @return 复选框对象指针
|
||||
*/
|
||||
Ptr<CheckBox> CheckBox::create() {
|
||||
return makePtr<CheckBox>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 创建带标签的复选框对象
|
||||
* @param label 标签文本
|
||||
* @return 复选框对象指针
|
||||
*/
|
||||
Ptr<CheckBox> CheckBox::create(const std::string &label) {
|
||||
auto cb = makePtr<CheckBox>();
|
||||
cb->setLabel(label);
|
||||
return cb;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用构建器方法
|
||||
// ------------------------------------------------------------------------
|
||||
CheckBox *CheckBox::withPosition(float x, float y) {
|
||||
setPosition(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
CheckBox *CheckBox::withPosition(const Vec2 &pos) {
|
||||
setPosition(pos);
|
||||
return this;
|
||||
}
|
||||
|
||||
CheckBox *CheckBox::withAnchor(float x, float y) {
|
||||
setAnchor(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
CheckBox *CheckBox::withAnchor(const Vec2 &anchor) {
|
||||
setAnchor(anchor);
|
||||
return this;
|
||||
}
|
||||
|
||||
CheckBox *CheckBox::withText(const std::string &text) {
|
||||
setLabel(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
CheckBox *CheckBox::withFont(Ptr<FontAtlas> font) {
|
||||
setFont(font);
|
||||
return this;
|
||||
}
|
||||
|
||||
CheckBox *CheckBox::withTextColor(const Color &color) {
|
||||
setTextColor(color);
|
||||
return this;
|
||||
}
|
||||
|
||||
CheckBox *CheckBox::withSize(float width, float height) {
|
||||
setSize(width, height);
|
||||
return this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用 - 坐标空间设置
|
||||
// ------------------------------------------------------------------------
|
||||
CheckBox *CheckBox::withCoordinateSpace(CoordinateSpace space) {
|
||||
setCoordinateSpace(space);
|
||||
return this;
|
||||
}
|
||||
|
||||
CheckBox *CheckBox::withScreenPosition(float x, float y) {
|
||||
setScreenPosition(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
CheckBox *CheckBox::withScreenPosition(const Vec2 &pos) {
|
||||
setScreenPosition(pos);
|
||||
return this;
|
||||
}
|
||||
|
||||
CheckBox *CheckBox::withCameraOffset(float x, float y) {
|
||||
setCameraOffset(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
CheckBox *CheckBox::withCameraOffset(const Vec2 &offset) {
|
||||
setCameraOffset(offset);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置选中状态
|
||||
* @param checked 是否选中
|
||||
*/
|
||||
void CheckBox::setChecked(bool checked) {
|
||||
if (checked_ != checked) {
|
||||
checked_ = checked;
|
||||
|
|
@ -99,46 +44,89 @@ void CheckBox::setChecked(bool checked) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 切换选中状态
|
||||
*/
|
||||
void CheckBox::toggle() {
|
||||
setChecked(!checked_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置标签文本
|
||||
* @param label 标签文本
|
||||
*/
|
||||
void CheckBox::setLabel(const std::string &label) {
|
||||
label_ = label;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置字体
|
||||
* @param font 字体图集指针
|
||||
*/
|
||||
void CheckBox::setFont(Ptr<FontAtlas> font) {
|
||||
font_ = font;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置文本颜色
|
||||
* @param color 文本颜色
|
||||
*/
|
||||
void CheckBox::setTextColor(const Color &color) {
|
||||
textColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置复选框尺寸
|
||||
* @param size 复选框尺寸
|
||||
*/
|
||||
void CheckBox::setBoxSize(float size) {
|
||||
boxSize_ = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置间距
|
||||
* @param spacing 间距值
|
||||
*/
|
||||
void CheckBox::setSpacing(float spacing) {
|
||||
spacing_ = spacing;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置选中颜色
|
||||
* @param color 选中颜色
|
||||
*/
|
||||
void CheckBox::setCheckedColor(const Color &color) {
|
||||
checkedColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置未选中颜色
|
||||
* @param color 未选中颜色
|
||||
*/
|
||||
void CheckBox::setUncheckedColor(const Color &color) {
|
||||
uncheckedColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置勾选标记颜色
|
||||
* @param color 勾选标记颜色
|
||||
*/
|
||||
void CheckBox::setCheckMarkColor(const Color &color) {
|
||||
checkMarkColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置状态改变回调
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
void CheckBox::setOnStateChange(Function<void(bool)> callback) {
|
||||
onStateChange_ = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取边界框
|
||||
* @return 边界矩形
|
||||
*/
|
||||
Rect CheckBox::getBoundingBox() const {
|
||||
Vec2 pos = getPosition();
|
||||
float width = boxSize_;
|
||||
|
|
@ -151,16 +139,18 @@ Rect CheckBox::getBoundingBox() const {
|
|||
return Rect(pos.x, pos.y, width, boxSize_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 绘制组件
|
||||
* @param renderer 渲染后端
|
||||
*/
|
||||
void CheckBox::onDrawWidget(RenderBackend &renderer) {
|
||||
Vec2 pos = getPosition();
|
||||
|
||||
// 绘制复选框
|
||||
Rect boxRect(pos.x, pos.y + (getSize().height - boxSize_) * 0.5f, boxSize_, boxSize_);
|
||||
Color boxColor = checked_ ? checkedColor_ : uncheckedColor_;
|
||||
renderer.fillRect(boxRect, boxColor);
|
||||
renderer.drawRect(boxRect, Colors::White, 1.0f);
|
||||
|
||||
// 绘制勾选标记
|
||||
if (checked_) {
|
||||
float padding = boxSize_ * 0.2f;
|
||||
float x1 = boxRect.origin.x + padding;
|
||||
|
|
@ -170,18 +160,21 @@ void CheckBox::onDrawWidget(RenderBackend &renderer) {
|
|||
float x3 = boxRect.origin.x + boxSize_ - padding;
|
||||
float y3 = boxRect.origin.y + padding;
|
||||
|
||||
// 简化的勾选标记绘制
|
||||
renderer.drawLine(Vec2(x1, y1), Vec2(x2, y2), checkMarkColor_, 2.0f);
|
||||
renderer.drawLine(Vec2(x2, y2), Vec2(x3, y3), checkMarkColor_, 2.0f);
|
||||
}
|
||||
|
||||
// 绘制标签
|
||||
if (!label_.empty() && font_) {
|
||||
Vec2 textPos(pos.x + boxSize_ + spacing_, pos.y);
|
||||
renderer.drawText(*font_, label_, textPos, textColor_);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 鼠标按下事件处理
|
||||
* @param event 鼠标事件
|
||||
* @return 是否处理了事件
|
||||
*/
|
||||
bool CheckBox::onMousePress(const MouseEvent &event) {
|
||||
if (event.button == MouseButton::Left) {
|
||||
pressed_ = true;
|
||||
|
|
@ -190,6 +183,11 @@ bool CheckBox::onMousePress(const MouseEvent &event) {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 鼠标释放事件处理
|
||||
* @param event 鼠标事件
|
||||
* @return 是否处理了事件
|
||||
*/
|
||||
bool CheckBox::onMouseRelease(const MouseEvent &event) {
|
||||
if (event.button == MouseButton::Left && pressed_) {
|
||||
pressed_ = false;
|
||||
|
|
|
|||
|
|
@ -4,178 +4,196 @@
|
|||
|
||||
namespace extra2d {
|
||||
|
||||
/**
|
||||
* @brief 默认构造函数
|
||||
*/
|
||||
Label::Label() {
|
||||
// 标签默认锚点为左上角
|
||||
setAnchor(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 带文本的构造函数
|
||||
* @param text 初始文本内容
|
||||
*/
|
||||
Label::Label(const std::string &text) : text_(text) {
|
||||
setAnchor(0.0f, 0.0f);
|
||||
sizeDirty_ = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 创建空标签对象
|
||||
* @return 标签对象指针
|
||||
*/
|
||||
Ptr<Label> Label::create() {
|
||||
return makePtr<Label>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 创建带文本的标签对象
|
||||
* @param text 文本内容
|
||||
* @return 标签对象指针
|
||||
*/
|
||||
Ptr<Label> Label::create(const std::string &text) {
|
||||
return makePtr<Label>(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 创建带文本和字体的标签对象
|
||||
* @param text 文本内容
|
||||
* @param font 字体图集
|
||||
* @return 标签对象指针
|
||||
*/
|
||||
Ptr<Label> Label::create(const std::string &text, Ptr<FontAtlas> font) {
|
||||
auto label = makePtr<Label>(text);
|
||||
label->setFont(font);
|
||||
return label;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用构建器方法
|
||||
// ------------------------------------------------------------------------
|
||||
Label *Label::withPosition(float x, float y) {
|
||||
setPosition(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
Label *Label::withPosition(const Vec2 &pos) {
|
||||
setPosition(pos);
|
||||
return this;
|
||||
}
|
||||
|
||||
Label *Label::withAnchor(float x, float y) {
|
||||
setAnchor(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
Label *Label::withAnchor(const Vec2 &anchor) {
|
||||
setAnchor(anchor);
|
||||
return this;
|
||||
}
|
||||
|
||||
Label *Label::withText(const std::string &text) {
|
||||
setText(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
Label *Label::withFont(Ptr<FontAtlas> font) {
|
||||
setFont(font);
|
||||
return this;
|
||||
}
|
||||
|
||||
Label *Label::withTextColor(const Color &color) {
|
||||
setTextColor(color);
|
||||
return this;
|
||||
}
|
||||
|
||||
Label *Label::withFontSize(int size) {
|
||||
setFontSize(size);
|
||||
return this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 坐标空间设置(链式调用)
|
||||
// ------------------------------------------------------------------------
|
||||
Label *Label::withCoordinateSpace(CoordinateSpace space) {
|
||||
setCoordinateSpace(space);
|
||||
return this;
|
||||
}
|
||||
|
||||
Label *Label::withScreenPosition(float x, float y) {
|
||||
setScreenPosition(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
Label *Label::withScreenPosition(const Vec2 &pos) {
|
||||
setScreenPosition(pos);
|
||||
return this;
|
||||
}
|
||||
|
||||
Label *Label::withCameraOffset(float x, float y) {
|
||||
setCameraOffset(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
Label *Label::withCameraOffset(const Vec2 &offset) {
|
||||
setCameraOffset(offset);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置文本内容
|
||||
* @param text 新的文本内容
|
||||
*/
|
||||
void Label::setText(const std::string &text) {
|
||||
text_ = text;
|
||||
sizeDirty_ = true;
|
||||
updateSpatialIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置字体
|
||||
* @param font 字体图集指针
|
||||
*/
|
||||
void Label::setFont(Ptr<FontAtlas> font) {
|
||||
font_ = font;
|
||||
sizeDirty_ = true;
|
||||
updateSpatialIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置文本颜色
|
||||
* @param color 文本颜色
|
||||
*/
|
||||
void Label::setTextColor(const Color &color) {
|
||||
textColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置字体大小
|
||||
* @param size 字体大小
|
||||
*/
|
||||
void Label::setFontSize(int size) {
|
||||
fontSize_ = size;
|
||||
sizeDirty_ = true;
|
||||
updateSpatialIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置水平对齐方式
|
||||
* @param align 对齐方式
|
||||
*/
|
||||
void Label::setHorizontalAlign(HorizontalAlign align) {
|
||||
hAlign_ = align;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置垂直对齐方式
|
||||
* @param align 垂直对齐方式
|
||||
*/
|
||||
void Label::setVerticalAlign(VerticalAlign align) {
|
||||
vAlign_ = align;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置阴影是否启用
|
||||
* @param enabled 是否启用
|
||||
*/
|
||||
void Label::setShadowEnabled(bool enabled) {
|
||||
shadowEnabled_ = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置阴影颜色
|
||||
* @param color 阴影颜色
|
||||
*/
|
||||
void Label::setShadowColor(const Color &color) {
|
||||
shadowColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置阴影偏移
|
||||
* @param offset 偏移向量
|
||||
*/
|
||||
void Label::setShadowOffset(const Vec2 &offset) {
|
||||
shadowOffset_ = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置描边是否启用
|
||||
* @param enabled 是否启用
|
||||
*/
|
||||
void Label::setOutlineEnabled(bool enabled) {
|
||||
outlineEnabled_ = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置描边颜色
|
||||
* @param color 描边颜色
|
||||
*/
|
||||
void Label::setOutlineColor(const Color &color) {
|
||||
outlineColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置描边宽度
|
||||
* @param width 描边宽度
|
||||
*/
|
||||
void Label::setOutlineWidth(float width) {
|
||||
outlineWidth_ = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置是否多行模式
|
||||
* @param multiLine 是否多行
|
||||
*/
|
||||
void Label::setMultiLine(bool multiLine) {
|
||||
multiLine_ = multiLine;
|
||||
sizeDirty_ = true;
|
||||
updateSpatialIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置行间距
|
||||
* @param spacing 行间距倍数
|
||||
*/
|
||||
void Label::setLineSpacing(float spacing) {
|
||||
lineSpacing_ = spacing;
|
||||
sizeDirty_ = true;
|
||||
updateSpatialIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置最大宽度
|
||||
* @param maxWidth 最大宽度
|
||||
*/
|
||||
void Label::setMaxWidth(float maxWidth) {
|
||||
maxWidth_ = maxWidth;
|
||||
sizeDirty_ = true;
|
||||
updateSpatialIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取文本尺寸
|
||||
* @return 文本的宽度和高度
|
||||
*/
|
||||
Vec2 Label::getTextSize() const {
|
||||
updateCache();
|
||||
return cachedSize_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取行高
|
||||
* @return 行高值
|
||||
*/
|
||||
float Label::getLineHeight() const {
|
||||
if (font_) {
|
||||
return font_->getLineHeight() * lineSpacing_;
|
||||
|
|
@ -183,6 +201,9 @@ float Label::getLineHeight() const {
|
|||
return static_cast<float>(fontSize_) * lineSpacing_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 更新缓存
|
||||
*/
|
||||
void Label::updateCache() const {
|
||||
if (!sizeDirty_ || !font_) {
|
||||
return;
|
||||
|
|
@ -208,6 +229,10 @@ void Label::updateCache() const {
|
|||
sizeDirty_ = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 分割文本为多行
|
||||
* @return 分割后的行列表
|
||||
*/
|
||||
std::vector<std::string> Label::splitLines() const {
|
||||
std::vector<std::string> lines;
|
||||
if (text_.empty()) {
|
||||
|
|
@ -219,17 +244,14 @@ std::vector<std::string> Label::splitLines() const {
|
|||
return lines;
|
||||
}
|
||||
|
||||
// 按换行符分割
|
||||
size_t start = 0;
|
||||
size_t end = text_.find('\n');
|
||||
|
||||
while (end != std::string::npos) {
|
||||
std::string line = text_.substr(start, end - start);
|
||||
|
||||
// 如果单行超过最大宽度,需要自动换行
|
||||
Vec2 lineSize = font_->measureText(line);
|
||||
if (lineSize.x > maxWidth_) {
|
||||
// 简单实现:按字符逐个尝试
|
||||
std::string currentLine;
|
||||
for (size_t i = 0; i < line.length(); ++i) {
|
||||
std::string testLine = currentLine + line[i];
|
||||
|
|
@ -252,7 +274,6 @@ std::vector<std::string> Label::splitLines() const {
|
|||
end = text_.find('\n', start);
|
||||
}
|
||||
|
||||
// 处理最后一行
|
||||
if (start < text_.length()) {
|
||||
std::string line = text_.substr(start);
|
||||
Vec2 lineSize = font_->measureText(line);
|
||||
|
|
@ -279,16 +300,18 @@ std::vector<std::string> Label::splitLines() const {
|
|||
return lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 计算绘制位置
|
||||
* @return 绘制位置坐标
|
||||
*/
|
||||
Vec2 Label::calculateDrawPosition() const {
|
||||
Vec2 pos = getPosition();
|
||||
Vec2 size = getTextSize();
|
||||
Size widgetSize = getSize();
|
||||
|
||||
// 如果设置了控件大小,使用控件大小作为对齐参考
|
||||
float refWidth = widgetSize.empty() ? size.x : widgetSize.width;
|
||||
float refHeight = widgetSize.empty() ? size.y : widgetSize.height;
|
||||
|
||||
// 水平对齐
|
||||
switch (hAlign_) {
|
||||
case HorizontalAlign::Center:
|
||||
pos.x += (refWidth - size.x) * 0.5f;
|
||||
|
|
@ -301,7 +324,6 @@ Vec2 Label::calculateDrawPosition() const {
|
|||
break;
|
||||
}
|
||||
|
||||
// 垂直对齐
|
||||
switch (vAlign_) {
|
||||
case VerticalAlign::Middle:
|
||||
pos.y += (refHeight - size.y) * 0.5f;
|
||||
|
|
@ -317,6 +339,12 @@ Vec2 Label::calculateDrawPosition() const {
|
|||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 绘制文本
|
||||
* @param renderer 渲染后端
|
||||
* @param position 绘制位置
|
||||
* @param color 文本颜色
|
||||
*/
|
||||
void Label::drawText(RenderBackend &renderer, const Vec2 &position, const Color &color) {
|
||||
if (!font_ || text_.empty()) {
|
||||
return;
|
||||
|
|
@ -336,6 +364,10 @@ void Label::drawText(RenderBackend &renderer, const Vec2 &position, const Color
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取边界框
|
||||
* @return 边界矩形
|
||||
*/
|
||||
Rect Label::getBoundingBox() const {
|
||||
if (!font_ || text_.empty()) {
|
||||
return Rect();
|
||||
|
|
@ -351,6 +383,10 @@ Rect Label::getBoundingBox() const {
|
|||
return Rect(pos.x, pos.y, size.x, size.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 绘制组件
|
||||
* @param renderer 渲染后端
|
||||
*/
|
||||
void Label::onDrawWidget(RenderBackend &renderer) {
|
||||
if (!font_ || text_.empty()) {
|
||||
return;
|
||||
|
|
@ -358,13 +394,11 @@ void Label::onDrawWidget(RenderBackend &renderer) {
|
|||
|
||||
Vec2 pos = calculateDrawPosition();
|
||||
|
||||
// 绘制阴影
|
||||
if (shadowEnabled_) {
|
||||
Vec2 shadowPos = pos + shadowOffset_;
|
||||
drawText(renderer, shadowPos, shadowColor_);
|
||||
}
|
||||
|
||||
// 绘制描边(简化实现:向8个方向偏移绘制)
|
||||
if (outlineEnabled_) {
|
||||
float w = outlineWidth_;
|
||||
drawText(renderer, pos + Vec2(-w, -w), outlineColor_);
|
||||
|
|
@ -377,7 +411,6 @@ void Label::onDrawWidget(RenderBackend &renderer) {
|
|||
drawText(renderer, pos + Vec2(w, w), outlineColor_);
|
||||
}
|
||||
|
||||
// 绘制主文本
|
||||
drawText(renderer, pos, textColor_);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,15 +5,29 @@
|
|||
|
||||
namespace extra2d {
|
||||
|
||||
/**
|
||||
* @brief 默认构造函数
|
||||
*/
|
||||
ProgressBar::ProgressBar() {
|
||||
setAnchor(0.0f, 0.0f);
|
||||
setSize(200.0f, 20.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 创建进度条对象
|
||||
* @return 进度条对象指针
|
||||
*/
|
||||
Ptr<ProgressBar> ProgressBar::create() {
|
||||
return makePtr<ProgressBar>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 创建带范围的进度条对象
|
||||
* @param min 最小值
|
||||
* @param max 最大值
|
||||
* @param value 当前值
|
||||
* @return 进度条对象指针
|
||||
*/
|
||||
Ptr<ProgressBar> ProgressBar::create(float min, float max, float value) {
|
||||
auto bar = makePtr<ProgressBar>();
|
||||
bar->setRange(min, max);
|
||||
|
|
@ -21,71 +35,21 @@ Ptr<ProgressBar> ProgressBar::create(float min, float max, float value) {
|
|||
return bar;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 链式调用构建器方法实现
|
||||
// ============================================================================
|
||||
|
||||
ProgressBar *ProgressBar::withPosition(float x, float y) {
|
||||
setPosition(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
ProgressBar *ProgressBar::withPosition(const Vec2 &pos) {
|
||||
setPosition(pos);
|
||||
return this;
|
||||
}
|
||||
|
||||
ProgressBar *ProgressBar::withAnchor(float x, float y) {
|
||||
setAnchor(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
ProgressBar *ProgressBar::withAnchor(const Vec2 &anchor) {
|
||||
setAnchor(anchor);
|
||||
return this;
|
||||
}
|
||||
|
||||
ProgressBar *ProgressBar::withSize(float width, float height) {
|
||||
setSize(width, height);
|
||||
return this;
|
||||
}
|
||||
|
||||
ProgressBar *ProgressBar::withProgress(float progress) {
|
||||
setValue(min_ + progress * (max_ - min_));
|
||||
return this;
|
||||
}
|
||||
|
||||
ProgressBar *ProgressBar::withCoordinateSpace(CoordinateSpace space) {
|
||||
setCoordinateSpace(space);
|
||||
return this;
|
||||
}
|
||||
|
||||
ProgressBar *ProgressBar::withScreenPosition(float x, float y) {
|
||||
setScreenPosition(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
ProgressBar *ProgressBar::withScreenPosition(const Vec2 &pos) {
|
||||
setScreenPosition(pos);
|
||||
return this;
|
||||
}
|
||||
|
||||
ProgressBar *ProgressBar::withCameraOffset(float x, float y) {
|
||||
setCameraOffset(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
ProgressBar *ProgressBar::withCameraOffset(const Vec2 &offset) {
|
||||
setCameraOffset(offset);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置数值范围
|
||||
* @param min 最小值
|
||||
* @param max 最大值
|
||||
*/
|
||||
void ProgressBar::setRange(float min, float max) {
|
||||
min_ = min;
|
||||
max_ = max;
|
||||
setValue(value_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置当前值
|
||||
* @param value 新值
|
||||
*/
|
||||
void ProgressBar::setValue(float value) {
|
||||
value_ = std::clamp(value, min_, max_);
|
||||
|
||||
|
|
@ -98,85 +62,165 @@ void ProgressBar::setValue(float value) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取百分比
|
||||
* @return 百分比值(0.0-1.0)
|
||||
*/
|
||||
float ProgressBar::getPercent() const {
|
||||
if (max_ <= min_) return 0.0f;
|
||||
return (displayValue_ - min_) / (max_ - min_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置方向
|
||||
* @param dir 方向枚举
|
||||
*/
|
||||
void ProgressBar::setDirection(Direction dir) {
|
||||
direction_ = dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置背景颜色
|
||||
* @param color 背景颜色
|
||||
*/
|
||||
void ProgressBar::setBackgroundColor(const Color &color) {
|
||||
bgColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置填充颜色
|
||||
* @param color 填充颜色
|
||||
*/
|
||||
void ProgressBar::setFillColor(const Color &color) {
|
||||
fillColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置是否启用渐变填充
|
||||
* @param enabled 是否启用
|
||||
*/
|
||||
void ProgressBar::setGradientFillEnabled(bool enabled) {
|
||||
gradientEnabled_ = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置渐变结束颜色
|
||||
* @param color 结束颜色
|
||||
*/
|
||||
void ProgressBar::setFillColorEnd(const Color &color) {
|
||||
fillColorEnd_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置是否启用分段颜色
|
||||
* @param enabled 是否启用
|
||||
*/
|
||||
void ProgressBar::setSegmentedColorsEnabled(bool enabled) {
|
||||
segmentedColorsEnabled_ = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 添加颜色分段
|
||||
* @param percentThreshold 百分比阈值
|
||||
* @param color 颜色
|
||||
*/
|
||||
void ProgressBar::addColorSegment(float percentThreshold, const Color &color) {
|
||||
colorSegments_.push_back({percentThreshold, color});
|
||||
std::sort(colorSegments_.begin(), colorSegments_.end(),
|
||||
[](const auto &a, const auto &b) { return a.first > b.first; });
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 清除所有颜色分段
|
||||
*/
|
||||
void ProgressBar::clearColorSegments() {
|
||||
colorSegments_.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置圆角半径
|
||||
* @param radius 圆角半径
|
||||
*/
|
||||
void ProgressBar::setCornerRadius(float radius) {
|
||||
cornerRadius_ = radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置是否启用圆角
|
||||
* @param enabled 是否启用
|
||||
*/
|
||||
void ProgressBar::setRoundedCornersEnabled(bool enabled) {
|
||||
roundedCornersEnabled_ = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置是否启用边框
|
||||
* @param enabled 是否启用
|
||||
*/
|
||||
void ProgressBar::setBorderEnabled(bool enabled) {
|
||||
borderEnabled_ = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置边框颜色
|
||||
* @param color 边框颜色
|
||||
*/
|
||||
void ProgressBar::setBorderColor(const Color &color) {
|
||||
borderColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置边框宽度
|
||||
* @param width 边框宽度
|
||||
*/
|
||||
void ProgressBar::setBorderWidth(float width) {
|
||||
borderWidth_ = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置内边距
|
||||
* @param padding 内边距值
|
||||
*/
|
||||
void ProgressBar::setPadding(float padding) {
|
||||
padding_ = padding;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置是否启用文本显示
|
||||
* @param enabled 是否启用
|
||||
*/
|
||||
void ProgressBar::setTextEnabled(bool enabled) {
|
||||
textEnabled_ = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置字体
|
||||
* @param font 字体图集指针
|
||||
*/
|
||||
void ProgressBar::setFont(Ptr<FontAtlas> font) {
|
||||
font_ = font;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置文本颜色
|
||||
* @param color 文本颜色
|
||||
*/
|
||||
void ProgressBar::setTextColor(const Color &color) {
|
||||
textColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置文本格式
|
||||
* @param format 格式字符串
|
||||
*/
|
||||
void ProgressBar::setTextFormat(const std::string &format) {
|
||||
textFormat_ = format;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置是否启用动画变化
|
||||
* @param enabled 是否启用
|
||||
*/
|
||||
void ProgressBar::setAnimatedChangeEnabled(bool enabled) {
|
||||
animatedChangeEnabled_ = enabled;
|
||||
if (!enabled) {
|
||||
|
|
@ -184,34 +228,66 @@ void ProgressBar::setAnimatedChangeEnabled(bool enabled) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置动画速度
|
||||
* @param speed 每秒变化量
|
||||
*/
|
||||
void ProgressBar::setAnimationSpeed(float speed) {
|
||||
animationSpeed_ = speed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置是否启用延迟显示
|
||||
* @param enabled 是否启用
|
||||
*/
|
||||
void ProgressBar::setDelayedDisplayEnabled(bool enabled) {
|
||||
delayedDisplayEnabled_ = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置延迟时间
|
||||
* @param seconds 延迟秒数
|
||||
*/
|
||||
void ProgressBar::setDelayTime(float seconds) {
|
||||
delayTime_ = seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置延迟显示填充颜色
|
||||
* @param color 填充颜色
|
||||
*/
|
||||
void ProgressBar::setDelayedFillColor(const Color &color) {
|
||||
delayedFillColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置是否启用条纹效果
|
||||
* @param enabled 是否启用
|
||||
*/
|
||||
void ProgressBar::setStripedEnabled(bool enabled) {
|
||||
stripedEnabled_ = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置条纹颜色
|
||||
* @param color 条纹颜色
|
||||
*/
|
||||
void ProgressBar::setStripeColor(const Color &color) {
|
||||
stripeColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置条纹移动速度
|
||||
* @param speed 移动速度
|
||||
*/
|
||||
void ProgressBar::setStripeSpeed(float speed) {
|
||||
stripeSpeed_ = speed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取当前填充颜色
|
||||
* @return 当前填充颜色
|
||||
*/
|
||||
Color ProgressBar::getCurrentFillColor() const {
|
||||
if (segmentedColorsEnabled_ && !colorSegments_.empty()) {
|
||||
float percent = getPercent();
|
||||
|
|
@ -224,6 +300,10 @@ Color ProgressBar::getCurrentFillColor() const {
|
|||
return fillColor_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 格式化文本
|
||||
* @return 格式化后的文本
|
||||
*/
|
||||
std::string ProgressBar::formatText() const {
|
||||
std::string result = textFormat_;
|
||||
|
||||
|
|
@ -246,10 +326,18 @@ std::string ProgressBar::formatText() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取边界框
|
||||
* @return 边界矩形
|
||||
*/
|
||||
Rect ProgressBar::getBoundingBox() const {
|
||||
return Rect(getPosition().x, getPosition().y, getSize().width, getSize().height);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 更新函数
|
||||
* @param deltaTime 帧间隔时间
|
||||
*/
|
||||
void ProgressBar::onUpdate(float deltaTime) {
|
||||
if (animatedChangeEnabled_ && displayValue_ != value_) {
|
||||
float diff = value_ - displayValue_;
|
||||
|
|
@ -285,25 +373,26 @@ void ProgressBar::onUpdate(float deltaTime) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 绘制组件
|
||||
* @param renderer 渲染后端
|
||||
*/
|
||||
void ProgressBar::onDrawWidget(RenderBackend &renderer) {
|
||||
Vec2 pos = getPosition();
|
||||
Size size = getSize();
|
||||
|
||||
// 计算实际绘制区域
|
||||
float bgX = pos.x + padding_;
|
||||
float bgY = pos.y + padding_;
|
||||
float bgW = size.width - padding_ * 2;
|
||||
float bgH = size.height - padding_ * 2;
|
||||
Rect bgRect(bgX, bgY, bgW, bgH);
|
||||
|
||||
// 绘制背景
|
||||
if (roundedCornersEnabled_) {
|
||||
fillRoundedRect(renderer, bgRect, bgColor_, cornerRadius_);
|
||||
} else {
|
||||
renderer.fillRect(bgRect, bgColor_);
|
||||
}
|
||||
|
||||
// 计算填充区域
|
||||
float percent = getPercent();
|
||||
float fillX = bgX, fillY = bgY, fillW = bgW, fillH = bgH;
|
||||
|
||||
|
|
@ -325,7 +414,6 @@ void ProgressBar::onDrawWidget(RenderBackend &renderer) {
|
|||
}
|
||||
Rect fillRect(fillX, fillY, fillW, fillH);
|
||||
|
||||
// 绘制延迟显示效果
|
||||
if (delayedDisplayEnabled_ && delayedValue_ > displayValue_) {
|
||||
float delayedPercent = (delayedValue_ - min_) / (max_ - min_);
|
||||
float delayedX = bgX, delayedY = bgY, delayedW = bgW, delayedH = bgH;
|
||||
|
|
@ -355,7 +443,6 @@ void ProgressBar::onDrawWidget(RenderBackend &renderer) {
|
|||
}
|
||||
}
|
||||
|
||||
// 绘制填充
|
||||
if (fillW > 0 && fillH > 0) {
|
||||
Color fillColor = getCurrentFillColor();
|
||||
|
||||
|
|
@ -370,7 +457,6 @@ void ProgressBar::onDrawWidget(RenderBackend &renderer) {
|
|||
}
|
||||
}
|
||||
|
||||
// 绘制边框
|
||||
if (borderEnabled_) {
|
||||
if (roundedCornersEnabled_) {
|
||||
drawRoundedRect(renderer, bgRect, borderColor_, cornerRadius_);
|
||||
|
|
@ -379,7 +465,6 @@ void ProgressBar::onDrawWidget(RenderBackend &renderer) {
|
|||
}
|
||||
}
|
||||
|
||||
// 绘制文本
|
||||
if (textEnabled_ && font_) {
|
||||
std::string text = formatText();
|
||||
Vec2 textSize = font_->measureText(text);
|
||||
|
|
@ -393,14 +478,33 @@ void ProgressBar::onDrawWidget(RenderBackend &renderer) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 绘制圆角矩形边框
|
||||
* @param renderer 渲染后端
|
||||
* @param rect 矩形区域
|
||||
* @param color 颜色
|
||||
* @param radius 圆角半径
|
||||
*/
|
||||
void ProgressBar::drawRoundedRect(RenderBackend &renderer, const Rect &rect, const Color &color, float radius) {
|
||||
renderer.drawRect(rect, color, borderWidth_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 填充圆角矩形
|
||||
* @param renderer 渲染后端
|
||||
* @param rect 矩形区域
|
||||
* @param color 颜色
|
||||
* @param radius 圆角半径
|
||||
*/
|
||||
void ProgressBar::fillRoundedRect(RenderBackend &renderer, const Rect &rect, const Color &color, float radius) {
|
||||
renderer.fillRect(rect, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 绘制条纹效果
|
||||
* @param renderer 渲染后端
|
||||
* @param rect 矩形区域
|
||||
*/
|
||||
void ProgressBar::drawStripes(RenderBackend &renderer, const Rect &rect) {
|
||||
const float stripeWidth = 10.0f;
|
||||
const float spacing = 20.0f;
|
||||
|
|
|
|||
|
|
@ -4,95 +4,37 @@
|
|||
|
||||
namespace extra2d {
|
||||
|
||||
/**
|
||||
* @brief 默认构造函数
|
||||
*/
|
||||
RadioButton::RadioButton() {
|
||||
setAnchor(0.0f, 0.0f);
|
||||
setSize(circleSize_, circleSize_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 创建单选按钮对象
|
||||
* @return 单选按钮对象指针
|
||||
*/
|
||||
Ptr<RadioButton> RadioButton::create() {
|
||||
return makePtr<RadioButton>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 创建带标签的单选按钮对象
|
||||
* @param label 标签文本
|
||||
* @return 单选按钮对象指针
|
||||
*/
|
||||
Ptr<RadioButton> RadioButton::create(const std::string &label) {
|
||||
auto rb = makePtr<RadioButton>();
|
||||
rb->setLabel(label);
|
||||
return rb;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用构建器方法
|
||||
// ------------------------------------------------------------------------
|
||||
RadioButton *RadioButton::withPosition(float x, float y) {
|
||||
setPosition(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
RadioButton *RadioButton::withPosition(const Vec2 &pos) {
|
||||
setPosition(pos);
|
||||
return this;
|
||||
}
|
||||
|
||||
RadioButton *RadioButton::withAnchor(float x, float y) {
|
||||
setAnchor(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
RadioButton *RadioButton::withAnchor(const Vec2 &anchor) {
|
||||
setAnchor(anchor);
|
||||
return this;
|
||||
}
|
||||
|
||||
RadioButton *RadioButton::withText(const std::string &text) {
|
||||
setLabel(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
RadioButton *RadioButton::withFont(Ptr<FontAtlas> font) {
|
||||
setFont(font);
|
||||
return this;
|
||||
}
|
||||
|
||||
RadioButton *RadioButton::withTextColor(const Color &color) {
|
||||
setTextColor(color);
|
||||
return this;
|
||||
}
|
||||
|
||||
RadioButton *RadioButton::withSize(float width, float height) {
|
||||
setSize(width, height);
|
||||
return this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用 - 坐标空间设置
|
||||
// ------------------------------------------------------------------------
|
||||
RadioButton *RadioButton::withCoordinateSpace(CoordinateSpace space) {
|
||||
setCoordinateSpace(space);
|
||||
return this;
|
||||
}
|
||||
|
||||
RadioButton *RadioButton::withScreenPosition(float x, float y) {
|
||||
setScreenPosition(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
RadioButton *RadioButton::withScreenPosition(const Vec2 &pos) {
|
||||
setScreenPosition(pos);
|
||||
return this;
|
||||
}
|
||||
|
||||
RadioButton *RadioButton::withCameraOffset(float x, float y) {
|
||||
setCameraOffset(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
RadioButton *RadioButton::withCameraOffset(const Vec2 &offset) {
|
||||
setCameraOffset(offset);
|
||||
return this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 普通设置方法
|
||||
// ------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief 设置选中状态
|
||||
* @param selected 是否选中
|
||||
*/
|
||||
void RadioButton::setSelected(bool selected) {
|
||||
if (selected_ != selected) {
|
||||
selected_ = selected;
|
||||
|
|
@ -102,46 +44,90 @@ void RadioButton::setSelected(bool selected) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置标签文本
|
||||
* @param label 标签文本
|
||||
*/
|
||||
void RadioButton::setLabel(const std::string &label) {
|
||||
label_ = label;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置字体
|
||||
* @param font 字体图集指针
|
||||
*/
|
||||
void RadioButton::setFont(Ptr<FontAtlas> font) {
|
||||
font_ = font;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置文本颜色
|
||||
* @param color 文本颜色
|
||||
*/
|
||||
void RadioButton::setTextColor(const Color &color) {
|
||||
textColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置圆形尺寸
|
||||
* @param size 圆形尺寸
|
||||
*/
|
||||
void RadioButton::setCircleSize(float size) {
|
||||
circleSize_ = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置间距
|
||||
* @param spacing 间距值
|
||||
*/
|
||||
void RadioButton::setSpacing(float spacing) {
|
||||
spacing_ = spacing;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置选中颜色
|
||||
* @param color 选中颜色
|
||||
*/
|
||||
void RadioButton::setSelectedColor(const Color &color) {
|
||||
selectedColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置未选中颜色
|
||||
* @param color 未选中颜色
|
||||
*/
|
||||
void RadioButton::setUnselectedColor(const Color &color) {
|
||||
unselectedColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置圆点颜色
|
||||
* @param color 圆点颜色
|
||||
*/
|
||||
void RadioButton::setDotColor(const Color &color) {
|
||||
dotColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置分组ID
|
||||
* @param groupId 分组ID
|
||||
*/
|
||||
void RadioButton::setGroupId(int groupId) {
|
||||
groupId_ = groupId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置状态改变回调
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
void RadioButton::setOnStateChange(Function<void(bool)> callback) {
|
||||
onStateChange_ = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取边界框
|
||||
* @return 边界矩形
|
||||
*/
|
||||
Rect RadioButton::getBoundingBox() const {
|
||||
Vec2 pos = getPosition();
|
||||
float width = circleSize_;
|
||||
|
|
@ -154,30 +140,36 @@ Rect RadioButton::getBoundingBox() const {
|
|||
return Rect(pos.x, pos.y, width, circleSize_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 绘制组件
|
||||
* @param renderer 渲染后端
|
||||
*/
|
||||
void RadioButton::onDrawWidget(RenderBackend &renderer) {
|
||||
Vec2 pos = getPosition();
|
||||
float centerX = pos.x + circleSize_ * 0.5f;
|
||||
float centerY = pos.y + getSize().height * 0.5f;
|
||||
float radius = circleSize_ * 0.5f;
|
||||
|
||||
// 绘制外圆
|
||||
Color circleColor = selected_ ? selectedColor_ : unselectedColor_;
|
||||
renderer.drawCircle(Vec2(centerX, centerY), radius, circleColor, true);
|
||||
renderer.drawCircle(Vec2(centerX, centerY), radius, Colors::White, false, 1.0f);
|
||||
|
||||
// 绘制内圆点
|
||||
if (selected_) {
|
||||
float dotRadius = radius * 0.4f;
|
||||
renderer.drawCircle(Vec2(centerX, centerY), dotRadius, dotColor_, true);
|
||||
}
|
||||
|
||||
// 绘制标签
|
||||
if (!label_.empty() && font_) {
|
||||
Vec2 textPos(pos.x + circleSize_ + spacing_, pos.y);
|
||||
renderer.drawText(*font_, label_, textPos, textColor_);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 鼠标按下事件处理
|
||||
* @param event 鼠标事件
|
||||
* @return 是否处理了事件
|
||||
*/
|
||||
bool RadioButton::onMousePress(const MouseEvent &event) {
|
||||
if (event.button == MouseButton::Left) {
|
||||
pressed_ = true;
|
||||
|
|
@ -186,6 +178,11 @@ bool RadioButton::onMousePress(const MouseEvent &event) {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 鼠标释放事件处理
|
||||
* @param event 鼠标事件
|
||||
* @return 是否处理了事件
|
||||
*/
|
||||
bool RadioButton::onMouseRelease(const MouseEvent &event) {
|
||||
if (event.button == MouseButton::Left && pressed_) {
|
||||
pressed_ = false;
|
||||
|
|
@ -208,6 +205,10 @@ bool RadioButton::onMouseRelease(const MouseEvent &event) {
|
|||
// RadioButtonGroup 实现
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief 添加单选按钮到组
|
||||
* @param button 单选按钮指针
|
||||
*/
|
||||
void RadioButtonGroup::addButton(RadioButton *button) {
|
||||
if (button && std::find(buttons_.begin(), buttons_.end(), button) == buttons_.end()) {
|
||||
buttons_.push_back(button);
|
||||
|
|
@ -223,6 +224,10 @@ void RadioButtonGroup::addButton(RadioButton *button) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 从组中移除单选按钮
|
||||
* @param button 单选按钮指针
|
||||
*/
|
||||
void RadioButtonGroup::removeButton(RadioButton *button) {
|
||||
auto it = std::find(buttons_.begin(), buttons_.end(), button);
|
||||
if (it != buttons_.end()) {
|
||||
|
|
@ -233,15 +238,17 @@ void RadioButtonGroup::removeButton(RadioButton *button) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 选择指定的单选按钮
|
||||
* @param button 单选按钮指针
|
||||
*/
|
||||
void RadioButtonGroup::selectButton(RadioButton *button) {
|
||||
if (selectedButton_ == button) return;
|
||||
|
||||
// 取消之前的选择
|
||||
if (selectedButton_) {
|
||||
selectedButton_->setSelected(false);
|
||||
}
|
||||
|
||||
// 选择新的按钮
|
||||
selectedButton_ = button;
|
||||
if (button) {
|
||||
button->setSelected(true);
|
||||
|
|
@ -252,6 +259,10 @@ void RadioButtonGroup::selectButton(RadioButton *button) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置选择改变回调
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
void RadioButtonGroup::setOnSelectionChange(Function<void(RadioButton*)> callback) {
|
||||
onSelectionChange_ = callback;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,15 +5,29 @@
|
|||
|
||||
namespace extra2d {
|
||||
|
||||
/**
|
||||
* @brief 默认构造函数
|
||||
*/
|
||||
Slider::Slider() {
|
||||
setAnchor(0.0f, 0.0f);
|
||||
setSize(200.0f, 20.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 创建滑动条对象
|
||||
* @return 滑动条对象指针
|
||||
*/
|
||||
Ptr<Slider> Slider::create() {
|
||||
return makePtr<Slider>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 创建带范围的滑动条对象
|
||||
* @param min 最小值
|
||||
* @param max 最大值
|
||||
* @param value 当前值
|
||||
* @return 滑动条对象指针
|
||||
*/
|
||||
Ptr<Slider> Slider::create(float min, float max, float value) {
|
||||
auto slider = makePtr<Slider>();
|
||||
slider->setRange(min, max);
|
||||
|
|
@ -21,153 +35,21 @@ Ptr<Slider> Slider::create(float min, float max, float value) {
|
|||
return slider;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// 链式调用构建器方法实现
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief 设置位置(浮点坐标)
|
||||
* @param x X坐标
|
||||
* @param y Y坐标
|
||||
* @return 返回this指针,支持链式调用
|
||||
*/
|
||||
Slider *Slider::withPosition(float x, float y) {
|
||||
setPosition(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置位置(Vec2坐标)
|
||||
* @param pos 位置向量
|
||||
* @return 返回this指针,支持链式调用
|
||||
*/
|
||||
Slider *Slider::withPosition(const Vec2 &pos) {
|
||||
setPosition(pos);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置锚点(浮点坐标)
|
||||
* @param x X锚点(0-1)
|
||||
* @param y Y锚点(0-1)
|
||||
* @return 返回this指针,支持链式调用
|
||||
*/
|
||||
Slider *Slider::withAnchor(float x, float y) {
|
||||
setAnchor(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置锚点(Vec2坐标)
|
||||
* @param anchor 锚点向量
|
||||
* @return 返回this指针,支持链式调用
|
||||
*/
|
||||
Slider *Slider::withAnchor(const Vec2 &anchor) {
|
||||
setAnchor(anchor);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置尺寸
|
||||
* @param width 宽度
|
||||
* @param height 高度
|
||||
* @return 返回this指针,支持链式调用
|
||||
*/
|
||||
Slider *Slider::withSize(float width, float height) {
|
||||
setSize(width, height);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置最小值
|
||||
* @brief 设置数值范围
|
||||
* @param min 最小值
|
||||
* @return 返回this指针,支持链式调用
|
||||
*/
|
||||
Slider *Slider::withMinValue(float min) {
|
||||
min_ = min;
|
||||
setValue(value_);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置最大值
|
||||
* @param max 最大值
|
||||
* @return 返回this指针,支持链式调用
|
||||
*/
|
||||
Slider *Slider::withMaxValue(float max) {
|
||||
max_ = max;
|
||||
setValue(value_);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置当前值
|
||||
* @param value 当前值
|
||||
* @return 返回this指针,支持链式调用
|
||||
*/
|
||||
Slider *Slider::withValue(float value) {
|
||||
setValue(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置坐标空间
|
||||
* @param space 坐标空间类型
|
||||
* @return 返回this指针,支持链式调用
|
||||
*/
|
||||
Slider *Slider::withCoordinateSpace(CoordinateSpace space) {
|
||||
setCoordinateSpace(space);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置屏幕位置(浮点坐标)
|
||||
* @param x X屏幕坐标
|
||||
* @param y Y屏幕坐标
|
||||
* @return 返回this指针,支持链式调用
|
||||
*/
|
||||
Slider *Slider::withScreenPosition(float x, float y) {
|
||||
setScreenPosition(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置屏幕位置(Vec2坐标)
|
||||
* @param pos 屏幕位置向量
|
||||
* @return 返回this指针,支持链式调用
|
||||
*/
|
||||
Slider *Slider::withScreenPosition(const Vec2 &pos) {
|
||||
setScreenPosition(pos);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置相机偏移(浮点坐标)
|
||||
* @param x X偏移量
|
||||
* @param y Y偏移量
|
||||
* @return 返回this指针,支持链式调用
|
||||
*/
|
||||
Slider *Slider::withCameraOffset(float x, float y) {
|
||||
setCameraOffset(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置相机偏移(Vec2坐标)
|
||||
* @param offset 偏移向量
|
||||
* @return 返回this指针,支持链式调用
|
||||
*/
|
||||
Slider *Slider::withCameraOffset(const Vec2 &offset) {
|
||||
setCameraOffset(offset);
|
||||
return this;
|
||||
}
|
||||
|
||||
void Slider::setRange(float min, float max) {
|
||||
min_ = min;
|
||||
max_ = max;
|
||||
setValue(value_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置当前值
|
||||
* @param value 新值
|
||||
*/
|
||||
void Slider::setValue(float value) {
|
||||
float newValue = std::clamp(value, min_, max_);
|
||||
if (step_ > 0.0f) {
|
||||
|
|
@ -182,6 +64,10 @@ void Slider::setValue(float value) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置步进值
|
||||
* @param step 步进值
|
||||
*/
|
||||
void Slider::setStep(float step) {
|
||||
step_ = step;
|
||||
if (step_ > 0.0f) {
|
||||
|
|
@ -189,78 +75,155 @@ void Slider::setStep(float step) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置是否为垂直方向
|
||||
* @param vertical 是否垂直
|
||||
*/
|
||||
void Slider::setVertical(bool vertical) {
|
||||
vertical_ = vertical;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置轨道尺寸
|
||||
* @param size 轨道尺寸
|
||||
*/
|
||||
void Slider::setTrackSize(float size) {
|
||||
trackSize_ = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置滑块尺寸
|
||||
* @param size 滑块尺寸
|
||||
*/
|
||||
void Slider::setThumbSize(float size) {
|
||||
thumbSize_ = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置轨道颜色
|
||||
* @param color 轨道颜色
|
||||
*/
|
||||
void Slider::setTrackColor(const Color &color) {
|
||||
trackColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置填充颜色
|
||||
* @param color 填充颜色
|
||||
*/
|
||||
void Slider::setFillColor(const Color &color) {
|
||||
fillColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置滑块颜色
|
||||
* @param color 滑块颜色
|
||||
*/
|
||||
void Slider::setThumbColor(const Color &color) {
|
||||
thumbColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置滑块悬停颜色
|
||||
* @param color 悬停颜色
|
||||
*/
|
||||
void Slider::setThumbHoverColor(const Color &color) {
|
||||
thumbHoverColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置滑块按下颜色
|
||||
* @param color 按下颜色
|
||||
*/
|
||||
void Slider::setThumbPressedColor(const Color &color) {
|
||||
thumbPressedColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置是否显示滑块
|
||||
* @param show 是否显示
|
||||
*/
|
||||
void Slider::setShowThumb(bool show) {
|
||||
showThumb_ = show;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置是否显示填充
|
||||
* @param show 是否显示
|
||||
*/
|
||||
void Slider::setShowFill(bool show) {
|
||||
showFill_ = show;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置是否启用文本显示
|
||||
* @param enabled 是否启用
|
||||
*/
|
||||
void Slider::setTextEnabled(bool enabled) {
|
||||
textEnabled_ = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置字体
|
||||
* @param font 字体图集指针
|
||||
*/
|
||||
void Slider::setFont(Ptr<FontAtlas> font) {
|
||||
font_ = font;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置文本颜色
|
||||
* @param color 文本颜色
|
||||
*/
|
||||
void Slider::setTextColor(const Color &color) {
|
||||
textColor_ = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置文本格式
|
||||
* @param format 格式字符串
|
||||
*/
|
||||
void Slider::setTextFormat(const std::string &format) {
|
||||
textFormat_ = format;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置值改变回调
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
void Slider::setOnValueChange(Function<void(float)> callback) {
|
||||
onValueChange_ = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置拖拽开始回调
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
void Slider::setOnDragStart(Function<void()> callback) {
|
||||
onDragStart_ = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置拖拽结束回调
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
void Slider::setOnDragEnd(Function<void()> callback) {
|
||||
onDragEnd_ = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取边界框
|
||||
* @return 边界矩形
|
||||
*/
|
||||
Rect Slider::getBoundingBox() const {
|
||||
return Rect(getPosition().x, getPosition().y, getSize().width, getSize().height);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 将值转换为位置
|
||||
* @param value 数值
|
||||
* @return 位置坐标
|
||||
*/
|
||||
float Slider::valueToPosition(float value) const {
|
||||
Vec2 pos = getPosition();
|
||||
Size size = getSize();
|
||||
|
|
@ -274,6 +237,11 @@ float Slider::valueToPosition(float value) const {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 将位置转换为值
|
||||
* @param pos 位置坐标
|
||||
* @return 数值
|
||||
*/
|
||||
float Slider::positionToValue(float pos) const {
|
||||
Vec2 widgetPos = getPosition();
|
||||
Size size = getSize();
|
||||
|
|
@ -289,6 +257,10 @@ float Slider::positionToValue(float pos) const {
|
|||
return min_ + percent * (max_ - min_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取滑块矩形
|
||||
* @return 滑块矩形
|
||||
*/
|
||||
Rect Slider::getThumbRect() const {
|
||||
Vec2 pos = getPosition();
|
||||
Size size = getSize();
|
||||
|
|
@ -312,6 +284,10 @@ Rect Slider::getThumbRect() const {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取轨道矩形
|
||||
* @return 轨道矩形
|
||||
*/
|
||||
Rect Slider::getTrackRect() const {
|
||||
Vec2 pos = getPosition();
|
||||
Size size = getSize();
|
||||
|
|
@ -333,6 +309,10 @@ Rect Slider::getTrackRect() const {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 格式化文本
|
||||
* @return 格式化后的文本
|
||||
*/
|
||||
std::string Slider::formatText() const {
|
||||
std::string result = textFormat_;
|
||||
|
||||
|
|
@ -353,18 +333,25 @@ std::string Slider::formatText() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 将值对齐到步进
|
||||
* @param value 原始值
|
||||
* @return 对齐后的值
|
||||
*/
|
||||
float Slider::snapToStep(float value) const {
|
||||
float steps = std::round((value - min_) / step_);
|
||||
return min_ + steps * step_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 绘制组件
|
||||
* @param renderer 渲染后端
|
||||
*/
|
||||
void Slider::onDrawWidget(RenderBackend &renderer) {
|
||||
Rect trackRect = getTrackRect();
|
||||
|
||||
// 绘制轨道背景
|
||||
renderer.fillRect(trackRect, trackColor_);
|
||||
|
||||
// 绘制填充部分
|
||||
if (showFill_) {
|
||||
float percent = (value_ - min_) / (max_ - min_);
|
||||
float fillX = trackRect.origin.x;
|
||||
|
|
@ -383,7 +370,6 @@ void Slider::onDrawWidget(RenderBackend &renderer) {
|
|||
renderer.fillRect(fillRect, fillColor_);
|
||||
}
|
||||
|
||||
// 绘制滑块
|
||||
if (showThumb_) {
|
||||
Rect thumbRect = getThumbRect();
|
||||
Color thumbColor = thumbColor_;
|
||||
|
|
@ -398,7 +384,6 @@ void Slider::onDrawWidget(RenderBackend &renderer) {
|
|||
renderer.drawRect(thumbRect, Colors::White, 1.0f);
|
||||
}
|
||||
|
||||
// 绘制文本
|
||||
if (textEnabled_ && font_) {
|
||||
std::string text = formatText();
|
||||
Vec2 textSize = font_->measureText(text);
|
||||
|
|
@ -414,6 +399,11 @@ void Slider::onDrawWidget(RenderBackend &renderer) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 鼠标按下事件处理
|
||||
* @param event 鼠标事件
|
||||
* @return 是否处理了事件
|
||||
*/
|
||||
bool Slider::onMousePress(const MouseEvent &event) {
|
||||
if (event.button == MouseButton::Left) {
|
||||
Rect thumbRect = getThumbRect();
|
||||
|
|
@ -426,7 +416,6 @@ bool Slider::onMousePress(const MouseEvent &event) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// 点击轨道直接跳转
|
||||
Rect trackRect = getTrackRect();
|
||||
if (trackRect.containsPoint(Point(event.x, event.y))) {
|
||||
float newValue = positionToValue(vertical_ ? event.y : event.x);
|
||||
|
|
@ -441,6 +430,11 @@ bool Slider::onMousePress(const MouseEvent &event) {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 鼠标释放事件处理
|
||||
* @param event 鼠标事件
|
||||
* @return 是否处理了事件
|
||||
*/
|
||||
bool Slider::onMouseRelease(const MouseEvent &event) {
|
||||
if (event.button == MouseButton::Left && dragging_) {
|
||||
dragging_ = false;
|
||||
|
|
@ -452,6 +446,11 @@ bool Slider::onMouseRelease(const MouseEvent &event) {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 鼠标移动事件处理
|
||||
* @param event 鼠标事件
|
||||
* @return 是否处理了事件
|
||||
*/
|
||||
bool Slider::onMouseMove(const MouseEvent &event) {
|
||||
if (dragging_) {
|
||||
float newValue = positionToValue(vertical_ ? event.y : event.x);
|
||||
|
|
@ -459,7 +458,6 @@ bool Slider::onMouseMove(const MouseEvent &event) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// 检查悬停
|
||||
Rect thumbRect = getThumbRect();
|
||||
bool wasHovered = hovered_;
|
||||
hovered_ = thumbRect.containsPoint(Point(event.x, event.y));
|
||||
|
|
@ -467,10 +465,16 @@ bool Slider::onMouseMove(const MouseEvent &event) {
|
|||
return hovered_ != wasHovered;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 鼠标进入事件处理
|
||||
*/
|
||||
void Slider::onMouseEnter() {
|
||||
hovered_ = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 鼠标离开事件处理
|
||||
*/
|
||||
void Slider::onMouseLeave() {
|
||||
hovered_ = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,136 +1,93 @@
|
|||
#include <extra2d/ui/text.h>
|
||||
#include <extra2d/graphics/render_backend.h>
|
||||
#include <extra2d/core/string.h>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <extra2d/core/string.h>
|
||||
#include <extra2d/graphics/render_backend.h>
|
||||
#include <extra2d/ui/text.h>
|
||||
|
||||
|
||||
namespace extra2d {
|
||||
|
||||
Text::Text() {
|
||||
// 文字默认锚点为左上角,这样setPosition(0, 0)会在左上角显示
|
||||
setAnchor(0.0f, 0.0f);
|
||||
}
|
||||
/**
|
||||
* @brief 默认构造函数
|
||||
*/
|
||||
Text::Text() { setAnchor(0.0f, 0.0f); }
|
||||
|
||||
/**
|
||||
* @brief 带文本的构造函数
|
||||
* @param text 初始文本内容
|
||||
*/
|
||||
Text::Text(const std::string &text) : text_(text) {
|
||||
sizeDirty_ = true;
|
||||
// 文字默认锚点为左上角,这样setPosition(0, 0)会在左上角显示
|
||||
setAnchor(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用构建器方法
|
||||
// ------------------------------------------------------------------------
|
||||
Text *Text::withPosition(float x, float y) {
|
||||
setPosition(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
Text *Text::withPosition(const Vec2 &pos) {
|
||||
setPosition(pos);
|
||||
return this;
|
||||
}
|
||||
|
||||
Text *Text::withAnchor(float x, float y) {
|
||||
setAnchor(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
Text *Text::withAnchor(const Vec2 &anchor) {
|
||||
setAnchor(anchor);
|
||||
return this;
|
||||
}
|
||||
|
||||
Text *Text::withTextColor(const Color &color) {
|
||||
setTextColor(color);
|
||||
return this;
|
||||
}
|
||||
|
||||
Text *Text::withFont(Ptr<FontAtlas> font) {
|
||||
setFont(font);
|
||||
return this;
|
||||
}
|
||||
|
||||
Text *Text::withFontSize(int size) {
|
||||
setFontSize(size);
|
||||
return this;
|
||||
}
|
||||
|
||||
Text *Text::withAlignment(Alignment align) {
|
||||
setAlignment(align);
|
||||
return this;
|
||||
}
|
||||
|
||||
Text *Text::withVerticalAlignment(VerticalAlignment align) {
|
||||
setVerticalAlignment(align);
|
||||
return this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 链式调用 - 坐标空间设置
|
||||
// ------------------------------------------------------------------------
|
||||
Text *Text::withCoordinateSpace(CoordinateSpace space) {
|
||||
setCoordinateSpace(space);
|
||||
return this;
|
||||
}
|
||||
|
||||
Text *Text::withScreenPosition(float x, float y) {
|
||||
setScreenPosition(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
Text *Text::withScreenPosition(const Vec2 &pos) {
|
||||
setScreenPosition(pos);
|
||||
return this;
|
||||
}
|
||||
|
||||
Text *Text::withCameraOffset(float x, float y) {
|
||||
setCameraOffset(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
Text *Text::withCameraOffset(const Vec2 &offset) {
|
||||
setCameraOffset(offset);
|
||||
return this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 普通设置方法
|
||||
// ------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief 设置文本内容
|
||||
* @param text 新的文本内容
|
||||
*/
|
||||
void Text::setText(const std::string &text) {
|
||||
text_ = text;
|
||||
sizeDirty_ = true;
|
||||
updateSpatialIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置字体
|
||||
* @param font 字体图集指针
|
||||
*/
|
||||
void Text::setFont(Ptr<FontAtlas> font) {
|
||||
font_ = font;
|
||||
sizeDirty_ = true;
|
||||
updateSpatialIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置文本颜色
|
||||
* @param color 文本颜色
|
||||
*/
|
||||
void Text::setTextColor(const Color &color) { color_ = color; }
|
||||
|
||||
/**
|
||||
* @brief 设置字体大小
|
||||
* @param size 字体大小
|
||||
*/
|
||||
void Text::setFontSize(int size) {
|
||||
fontSize_ = size;
|
||||
sizeDirty_ = true;
|
||||
updateSpatialIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置水平对齐方式
|
||||
* @param align 对齐方式
|
||||
*/
|
||||
void Text::setAlignment(Alignment align) {
|
||||
alignment_ = align;
|
||||
updateSpatialIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置垂直对齐方式
|
||||
* @param align 垂直对齐方式
|
||||
*/
|
||||
void Text::setVerticalAlignment(VerticalAlignment align) {
|
||||
verticalAlignment_ = align;
|
||||
updateSpatialIndex();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取文本尺寸
|
||||
* @return 文本的宽度和高度
|
||||
*/
|
||||
Vec2 Text::getTextSize() const {
|
||||
updateCache();
|
||||
return cachedSize_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取行高
|
||||
* @return 行高值
|
||||
*/
|
||||
float Text::getLineHeight() const {
|
||||
if (font_) {
|
||||
return font_->getLineHeight();
|
||||
|
|
@ -138,6 +95,9 @@ float Text::getLineHeight() const {
|
|||
return static_cast<float>(fontSize_);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 更新缓存
|
||||
*/
|
||||
void Text::updateCache() const {
|
||||
if (!sizeDirty_ || !font_) {
|
||||
return;
|
||||
|
|
@ -147,67 +107,84 @@ void Text::updateCache() const {
|
|||
sizeDirty_ = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 计算绘制位置
|
||||
* @return 绘制位置坐标
|
||||
*/
|
||||
Vec2 Text::calculateDrawPosition() const {
|
||||
Vec2 pos = getPosition();
|
||||
Vec2 textSize = getTextSize();
|
||||
Size widgetSize = getSize();
|
||||
Vec2 anchor = getAnchor();
|
||||
|
||||
// 如果设置了控件大小,使用控件大小作为对齐参考
|
||||
float refWidth = widgetSize.empty() ? textSize.x : widgetSize.width;
|
||||
float refHeight = widgetSize.empty() ? textSize.y : widgetSize.height;
|
||||
|
||||
// 锚点调整:锚点(0.5, 0.5)表示文本中心在pos位置
|
||||
// 需要将文本向左上方偏移锚点比例 * 文本大小
|
||||
pos.x -= textSize.x * anchor.x;
|
||||
pos.y -= textSize.y * anchor.y;
|
||||
|
||||
// 水平对齐(仅在设置了控件大小时生效)
|
||||
if (!widgetSize.empty()) {
|
||||
switch (alignment_) {
|
||||
case Alignment::Center:
|
||||
pos.x += (refWidth - textSize.x) * 0.5f;
|
||||
break;
|
||||
case Alignment::Right:
|
||||
pos.x += refWidth - textSize.x;
|
||||
break;
|
||||
case Alignment::Left:
|
||||
default:
|
||||
break;
|
||||
case Alignment::Center:
|
||||
pos.x += (refWidth - textSize.x) * 0.5f;
|
||||
break;
|
||||
case Alignment::Right:
|
||||
pos.x += refWidth - textSize.x;
|
||||
break;
|
||||
case Alignment::Left:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 垂直对齐(仅在设置了控件大小时生效)
|
||||
if (!widgetSize.empty()) {
|
||||
switch (verticalAlignment_) {
|
||||
case VerticalAlignment::Middle:
|
||||
pos.y += (refHeight - textSize.y) * 0.5f;
|
||||
break;
|
||||
case VerticalAlignment::Bottom:
|
||||
pos.y += refHeight - textSize.y;
|
||||
break;
|
||||
case VerticalAlignment::Top:
|
||||
default:
|
||||
break;
|
||||
case VerticalAlignment::Middle:
|
||||
pos.y += (refHeight - textSize.y) * 0.5f;
|
||||
break;
|
||||
case VerticalAlignment::Bottom:
|
||||
pos.y += refHeight - textSize.y;
|
||||
break;
|
||||
case VerticalAlignment::Top:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 创建空文本对象
|
||||
* @return 文本对象指针
|
||||
*/
|
||||
Ptr<Text> Text::create() { return makePtr<Text>(); }
|
||||
|
||||
/**
|
||||
* @brief 创建带文本的对象
|
||||
* @param text 文本内容
|
||||
* @return 文本对象指针
|
||||
*/
|
||||
Ptr<Text> Text::create(const std::string &text) { return makePtr<Text>(text); }
|
||||
|
||||
/**
|
||||
* @brief 创建带文本和字体的对象
|
||||
* @param text 文本内容
|
||||
* @param font 字体图集
|
||||
* @return 文本对象指针
|
||||
*/
|
||||
Ptr<Text> Text::create(const std::string &text, Ptr<FontAtlas> font) {
|
||||
auto t = makePtr<Text>(text);
|
||||
t->setFont(font);
|
||||
return t;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// 格式化创建方法
|
||||
// ------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief 格式化创建文本
|
||||
* @param fmt 格式字符串
|
||||
* @param ... 可变参数
|
||||
* @return 文本对象指针
|
||||
*/
|
||||
Ptr<Text> Text::createFormat(const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
|
@ -217,6 +194,13 @@ Ptr<Text> Text::createFormat(const char *fmt, ...) {
|
|||
return makePtr<Text>(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 格式化创建文本(带字体)
|
||||
* @param font 字体图集
|
||||
* @param fmt 格式字符串
|
||||
* @param ... 可变参数
|
||||
* @return 文本对象指针
|
||||
*/
|
||||
Ptr<Text> Text::createFormat(Ptr<FontAtlas> font, const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
|
@ -228,6 +212,10 @@ Ptr<Text> Text::createFormat(Ptr<FontAtlas> font, const char *fmt, ...) {
|
|||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取边界框
|
||||
* @return 边界矩形
|
||||
*/
|
||||
Rect Text::getBoundingBox() const {
|
||||
if (!font_ || text_.empty()) {
|
||||
return Rect();
|
||||
|
|
@ -243,6 +231,10 @@ Rect Text::getBoundingBox() const {
|
|||
return Rect(pos.x, pos.y, size.x, size.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 绘制组件
|
||||
* @param renderer 渲染后端
|
||||
*/
|
||||
void Text::onDrawWidget(RenderBackend &renderer) {
|
||||
if (!font_ || text_.empty()) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
using namespace extra2d;
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// Hello World 场景
|
||||
// ============================================================================
|
||||
|
|
@ -33,34 +32,34 @@ public:
|
|||
|
||||
// 创建 "你好世界" 文本组件 - 使用屏幕空间(固定位置,不随相机移动)
|
||||
auto text1 = Text::create("你好世界", font_);
|
||||
text1->withCoordinateSpace(CoordinateSpace::Screen)
|
||||
->withScreenPosition(640.0f, 360.0f) // 屏幕中心
|
||||
->withAnchor(0.5f, 0.5f) // 中心锚点,让文字中心对准位置
|
||||
->withTextColor(Color(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
text1->setCoordinateSpace(CoordinateSpace::Screen);
|
||||
text1->setScreenPosition(640.0f, 360.0f); // 屏幕中心
|
||||
text1->setAnchor(0.5f, 0.5f); // 中心锚点,让文字中心对准位置
|
||||
text1->setTextColor(Color(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
addChild(text1);
|
||||
|
||||
// 创建提示文本组件 - 使用屏幕空间,固定在屏幕底部
|
||||
auto text2 = Text::create("退出按键(START 按钮)", font_);
|
||||
text2->withCoordinateSpace(CoordinateSpace::Screen)
|
||||
->withScreenPosition(640.0f, 650.0f) // 屏幕底部
|
||||
->withAnchor(0.5f, 0.5f)
|
||||
->withTextColor(Color(1.0f, 1.0f, 0.0f, 1.0f));
|
||||
text2->setCoordinateSpace(CoordinateSpace::Screen);
|
||||
text2->setScreenPosition(640.0f, 650.0f); // 屏幕底部
|
||||
text2->setAnchor(0.5f, 0.5f);
|
||||
text2->setTextColor(Color(1.0f, 1.0f, 0.0f, 1.0f));
|
||||
addChild(text2);
|
||||
|
||||
// 创建相机空间文本 - 跟随相机但保持相对偏移
|
||||
auto text3 = Text::create("相机空间文本", font_);
|
||||
text3->withCoordinateSpace(CoordinateSpace::Camera)
|
||||
->withCameraOffset(50.0f, 50.0f) // 相机左上角偏移(屏幕坐标系Y向下)
|
||||
->withAnchor(0.0f, 0.0f) // 左上角锚点,文字从指定位置开始显示
|
||||
->withTextColor(Color(0.0f, 1.0f, 1.0f, 1.0f));
|
||||
text3->setCoordinateSpace(CoordinateSpace::Camera);
|
||||
text3->setCameraOffset(50.0f, 50.0f); // 相机左上角偏移(屏幕坐标系Y向下)
|
||||
text3->setAnchor(0.0f, 0.0f); // 左上角锚点,文字从指定位置开始显示
|
||||
text3->setTextColor(Color(0.0f, 1.0f, 1.0f, 1.0f));
|
||||
addChild(text3);
|
||||
|
||||
// 创建世界空间文本 - 随相机移动(默认行为)
|
||||
auto text4 = Text::create("世界空间文本", font_);
|
||||
text4->withCoordinateSpace(CoordinateSpace::World)
|
||||
->withPosition(100.0f, 100.0f) // 世界坐标
|
||||
->withAnchor(0.0f, 0.0f) // 左上角锚点,文字从指定位置开始显示
|
||||
->withTextColor(Color(1.0f, 0.5f, 0.5f, 1.0f));
|
||||
text4->setCoordinateSpace(CoordinateSpace::World);
|
||||
text4->setPosition(100.0f, 100.0f); // 世界坐标
|
||||
text4->setAnchor(0.0f, 0.0f); // 左上角锚点,文字从指定位置开始显示
|
||||
text4->setTextColor(Color(1.0f, 0.5f, 0.5f, 1.0f));
|
||||
addChild(text4);
|
||||
}
|
||||
|
||||
|
|
@ -89,8 +88,7 @@ private:
|
|||
// 程序入口
|
||||
// ============================================================================
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int main(int argc, char **argv) {
|
||||
// 初始化日志系统
|
||||
Logger::init();
|
||||
Logger::setLevel(LogLevel::Debug);
|
||||
|
|
|
|||
Loading…
Reference in New Issue