Commit 15628f06 authored by fallenstardust's avatar fallenstardust

update gframe

添加注释
parent eb028f4b
......@@ -19,7 +19,15 @@ namespace irr
namespace gui
{
//! constructor
//! \brief 构造函数,用于初始化一个组合框(ComboBox)控件。
//!
//! 该构造函数会创建一个带有下拉按钮和文本显示区域的组合框控件,并设置其初始状态与样式。
//! 它还会根据皮肤信息调整按钮大小、图标及颜色等视觉属性。
//!
//! \param environment GUI环境指针,提供GUI系统相关功能支持。
//! \param parent 组合框的父级元素,可以为 NULL。
//! \param id 控件ID,用于标识此控件。
//! \param rectangle 控件的位置和尺寸矩形,定义了控件在屏幕上的位置和大小。
CGUIComboBox::CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent,
s32 id, core::rect<s32> rectangle)
: IGUIComboBox(environment, parent, id, rectangle),
......@@ -30,12 +38,15 @@ CGUIComboBox::CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent,
setDebugName("CGUIComboBox");
#endif
// 获取当前使用的皮肤资源
IGUISkin* skin = Environment->getSkin();
// 根据皮肤设定计算下拉按钮宽度,默认为15像素
s32 width = 15;
if (skin)
width = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH);
// 设置下拉按钮的位置和大小
core::rect<s32> r;
r.UpperLeftCorner.X = rectangle.getWidth() - width - 2;
r.LowerRightCorner.X = rectangle.getWidth() - 2;
......@@ -43,22 +54,27 @@ CGUIComboBox::CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent,
r.UpperLeftCorner.Y = 2;
r.LowerRightCorner.Y = rectangle.getHeight() - 2;
// 创建下拉按钮并设置其基本属性
ListButton = Environment->addButton(r, this, -1, L"");
if (skin && skin->getSpriteBank())
{
// 设置按钮使用的精灵图库以及上下状态时显示的图标和颜色
ListButton->setSpriteBank(skin->getSpriteBank());
ListButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_CURSOR_DOWN), skin->getColor(EGDC_WINDOW_SYMBOL));
ListButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_CURSOR_DOWN), skin->getColor(EGDC_WINDOW_SYMBOL));
}
// 设置按钮对齐方式和其他属性
ListButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
ListButton->setSubElement(true);
ListButton->setTabStop(false);
// 设置选中文本区域的位置和大小
r.UpperLeftCorner.X = 2;
r.UpperLeftCorner.Y = 2;
r.LowerRightCorner.X = RelativeRect.getWidth() - (ListButton->getAbsolutePosition().getWidth() + 2);
r.LowerRightCorner.Y = RelativeRect.getHeight() - 2;
// 创建静态文本控件以显示当前选择项
SelectedText = Environment->addStaticText(L"", r, false, false, this, -1, false);
SelectedText->setSubElement(true);
SelectedText->setAlignment(EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
......@@ -67,12 +83,13 @@ CGUIComboBox::CGUIComboBox(IGUIEnvironment* environment, IGUIElement* parent,
SelectedText->setOverrideColor(skin->getColor(EGDC_BUTTON_TEXT));
SelectedText->enableOverrideColor(true);
// this element can be tabbed to
// 允许该控件接收 Tab 键焦点
setTabStop(true);
setTabOrder(-1);
}
void CGUIComboBox::setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical)
{
HAlign = horizontal;
......
......@@ -10,22 +10,45 @@
namespace irr {
namespace gui {
/**
* @brief 在2D空间中绘制一个带有旋转、缩放功能的图像。
*
* 此函数使用 Irrlicht 引擎提供的接口,在屏幕上以指定的位置、旋转中心点、角度和缩放比例来渲染一张纹理图片。
* 支持透明通道以及自定义颜色混合,并能适配不同平台(如 Android)下的材质类型设置。
*
* @param driver 视频驱动指针,用于执行实际绘图操作。
* @param image 要绘制的纹理资源。
* @param sourceRect 源图像中的矩形区域,表示要从纹理中裁剪出的部分。
* @param position 图像在屏幕上的起始绘制位置(左上角坐标)。
* @param rotationPoint 图像绕其旋转的中心点(相对于 position 的偏移量)。
* @param rotation 顺时针旋转的角度(单位:度)。
* @param scale 缩放因子,分别控制 X 和 Y 方向的拉伸程度。
* @param useAlphaChannel 是否启用 Alpha 透明通道进行混合。
* @param color 应用于整个图像的颜色调制(包括透明度)。
*/
void Draw2DImageRotation(video::IVideoDriver* driver, video::ITexture* image, core::rect<s32> sourceRect,
core::vector2d<s32> position, core::vector2d<s32> rotationPoint, f32 rotation, core::vector2df scale, bool useAlphaChannel, video::SColor color) {
// 保存并重置投影矩阵与视图矩阵,以便直接使用屏幕坐标进行绘制
irr::video::SMaterial material;
irr::core::matrix4 oldProjMat = driver->getTransform(irr::video::ETS_PROJECTION);
driver->setTransform(irr::video::ETS_PROJECTION, irr::core::matrix4());
irr::core::matrix4 oldViewMat = driver->getTransform(irr::video::ETS_VIEW);
driver->setTransform(irr::video::ETS_VIEW, irr::core::matrix4());
// 计算图像四个顶点的初始位置(未旋转前)
irr::core::vector2df corner[4];
corner[0] = irr::core::vector2df(position.X, position.Y);
corner[1] = irr::core::vector2df(position.X + sourceRect.getWidth() * scale.X, position.Y);
corner[2] = irr::core::vector2df(position.X, position.Y + sourceRect.getHeight() * scale.Y);
corner[3] = irr::core::vector2df(position.X + sourceRect.getWidth() * scale.X, position.Y + sourceRect.getHeight() * scale.Y);
// 若有旋转,则根据给定的旋转中心点对所有顶点应用旋转变换
if (rotation != 0.0f) {
for (int x = 0; x < 4; x++)
corner[x].rotateBy(rotation, irr::core::vector2df(rotationPoint.X, rotationPoint.Y));
}
// 提取源纹理坐标的 UV 值,并将其归一化到 [0,1] 区间内
irr::core::vector2df uvCorner[4];
uvCorner[0] = irr::core::vector2df(sourceRect.UpperLeftCorner.X, sourceRect.UpperLeftCorner.Y);
uvCorner[1] = irr::core::vector2df(sourceRect.LowerRightCorner.X, sourceRect.UpperLeftCorner.Y);
......@@ -36,6 +59,8 @@ void Draw2DImageRotation(video::IVideoDriver* driver, video::ITexture* image, co
float uvY = uvCorner[x].Y / (float)image->getOriginalSize().Height;
uvCorner[x] = irr::core::vector2df(uvX, uvY);
}
// 构造最终传入 GPU 绘制的顶点数据结构(包含位置、UV 和颜色信息)
irr::video::S3DVertex vertices[4];
irr::u16 indices[6] = { 0, 1, 2, 3, 2, 1 };
float screenWidth = driver->getScreenSize().Width;
......@@ -47,6 +72,8 @@ void Draw2DImageRotation(video::IVideoDriver* driver, video::ITexture* image, co
vertices[x].TCoords = uvCorner[x];
vertices[x].Color = color;
}
// 设置材质属性,关闭光照和深度写入,绑定纹理及选择合适的材质类型(支持跨平台)
material.Lighting = false;
material.ZWriteEnable = false;
material.TextureLayer[0].Texture = image;
......@@ -64,32 +91,55 @@ void Draw2DImageRotation(video::IVideoDriver* driver, video::ITexture* image, co
else material.MaterialType = irr::video::EMT_SOLID;
#endif
// 执行绘制命令并将变换矩阵恢复原状
driver->setMaterial(material);
driver->drawIndexedTriangleList(&vertices[0], 4, &indices[0], 2);
driver->setTransform(irr::video::ETS_PROJECTION, oldProjMat);
driver->setTransform(irr::video::ETS_VIEW, oldViewMat);
}
/**
* @brief 在2D空间中绘制一个图像四边形(quad),支持指定纹理区域、顶点坐标、透明度及颜色。
*
* 此函数使用 Irrlicht 引擎提供的接口,在屏幕空间直接绘制一张纹理图片的一部分,
* 形成由四个角定义的任意四边形。适用于 UI 元素或特殊效果渲染。
*
* @param driver 视频驱动指针,用于执行绘图操作。
* @param image 要绘制的纹理资源。
* @param sourceRect 指定从纹理中裁剪出的矩形区域(像素单位)。
* @param corner 四个二维向量组成的数组,表示在屏幕上的四个角的位置(像素单位)。
* @param useAlphaChannel 是否启用 Alpha 通道进行透明混合。
* @param color 应用于整个 quad 的顶点颜色(包括 alpha 值)。
*/
void Draw2DImageQuad(video::IVideoDriver* driver, video::ITexture* image, core::rect<s32> sourceRect,
core::vector2d<s32> corner[4], bool useAlphaChannel, video::SColor color) {
// 初始化材质并保存当前投影和视图矩阵
irr::video::SMaterial material;
irr::core::matrix4 oldProjMat = driver->getTransform(irr::video::ETS_PROJECTION);
driver->setTransform(irr::video::ETS_PROJECTION, irr::core::matrix4());
irr::core::matrix4 oldViewMat = driver->getTransform(irr::video::ETS_VIEW);
driver->setTransform(irr::video::ETS_VIEW, irr::core::matrix4());
// 计算 UV 坐标:将像素级纹理坐标转换为 [0,1] 范围内的归一化坐标
irr::core::vector2df uvCorner[4];
uvCorner[0] = irr::core::vector2df(sourceRect.UpperLeftCorner.X, sourceRect.UpperLeftCorner.Y);
uvCorner[1] = irr::core::vector2df(sourceRect.LowerRightCorner.X, sourceRect.UpperLeftCorner.Y);
uvCorner[2] = irr::core::vector2df(sourceRect.UpperLeftCorner.X, sourceRect.LowerRightCorner.Y);
uvCorner[3] = irr::core::vector2df(sourceRect.LowerRightCorner.X, sourceRect.LowerRightCorner.Y);
for (int x = 0; x < 4; x++) {
float uvX = uvCorner[x].X / (float)image->getOriginalSize().Width;
float uvY = uvCorner[x].Y / (float)image->getOriginalSize().Height;
uvCorner[x] = irr::core::vector2df(uvX, uvY);
}
// 构造顶点数据:位置映射到 [-1, 1] 屏幕坐标系,并设置 UV 和颜色
irr::video::S3DVertex vertices[4];
irr::u16 indices[6] = { 0, 1, 2, 3, 2, 1 };
float screenWidth = driver->getScreenSize().Width;
float screenHeight = driver->getScreenSize().Height;
for (int x = 0; x < 4; x++) {
float screenPosX = ((corner[x].X / screenWidth) - 0.5f) * 2.0f;
float screenPosY = ((corner[x].Y / screenHeight) - 0.5f) * -2.0f;
......@@ -97,81 +147,153 @@ void Draw2DImageQuad(video::IVideoDriver* driver, video::ITexture* image, core::
vertices[x].TCoords = uvCorner[x];
vertices[x].Color = color;
}
// 设置材质属性:禁用光照与深度写入,绑定纹理
material.Lighting = false;
material.ZWriteEnable = false;
material.TextureLayer[0].Texture = image;
#if defined(_IRR_ANDROID_PLATFORM_)
// Android 平台下根据 NPOT 支持情况调整纹理环绕方式
if (!ygo::mainGame->isNPOTSupported) {
material.TextureLayer[0].TextureWrapU = irr::video::ETC_CLAMP_TO_EDGE;
material.TextureLayer[0].TextureWrapV = irr::video::ETC_CLAMP_TO_EDGE;
}
// 根据是否使用透明通道选择对应的材质类型(Android GLES 特有)
if (useAlphaChannel)
material.MaterialType = (video::E_MATERIAL_TYPE)ygo::mainGame->ogles2TrasparentAlpha;
else material.MaterialType = (video::E_MATERIAL_TYPE)ygo::mainGame->ogles2Solid;
else
material.MaterialType = (video::E_MATERIAL_TYPE)ygo::mainGame->ogles2Solid;
#else
// 非 Android 平台使用标准材质类型
if (useAlphaChannel)
material.MaterialType = irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL;
else material.MaterialType = irr::video::EMT_SOLID;
else
material.MaterialType = irr::video::EMT_SOLID;
#endif
// 应用材质并绘制三角形列表(两个三角形组成一个 quad)
driver->setMaterial(material);
driver->drawIndexedTriangleList(&vertices[0], 4, &indices[0], 2);
// 恢复原始的投影和视图变换矩阵
driver->setTransform(irr::video::ETS_PROJECTION, oldProjMat);
driver->setTransform(irr::video::ETS_VIEW, oldViewMat);
}
/**
* @brief CGUIImageButton类的构造函数
* @param environment GUI环境指针,用于创建和管理GUI元素
* @param parent 父级GUI元素指针,新创建的按钮将作为其子元素
* @param id 控件ID,用于标识和区分不同的GUI元素
* @param rectangle 按钮的矩形区域,定义了按钮在屏幕上的位置和大小
*/
CGUIImageButton::CGUIImageButton(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle)
: CGUIButton(environment, parent, id, rectangle) {
// 初始化图像按钮的默认属性
isDrawImage = true;
isFixedSize = false;
imageRotation = 0.0f;
imageScale = core::vector2df(1.0f, 1.0f);
imageSize = core::dimension2di(rectangle.getWidth(), rectangle.getHeight());
}
/**
* 创建并添加一个图像按钮到GUI环境
* @param env GUI环境指针,用于创建和管理GUI元素
* @param rectangle 按钮的位置和大小矩形区域
* @param parent 父级GUI元素,如果为NULL则使用环境的根元素
* @param id 按钮的唯一标识符
* @return 返回新创建的图像按钮指针
*/
CGUIImageButton* CGUIImageButton::addImageButton(IGUIEnvironment *env, const core::rect<s32>& rectangle, IGUIElement* parent, s32 id) {
// 创建新的图像按钮实例
CGUIImageButton* button = new CGUIImageButton(env, parent ? parent : 0, id, rectangle);
// 释放引用计数,避免内存泄漏
button->drop();
return button;
}
/**
* @brief 绘制图像按钮
*
* 此函数负责绘制CGUIImageButton控件,包括按钮的边框、图像以及按下状态的视觉效果。
* 根据按钮是否被按下,会调整图像位置并绘制相应的3D按钮面板。
*
* @note 该函数重写了基类的draw方法,实现了自定义的图像按钮绘制逻辑
*/
void CGUIImageButton::draw() {
// 检查控件是否可见,不可见则直接返回
if (!IsVisible)
return;
// 获取GUI皮肤和视频驱动器实例
IGUISkin* skin = Environment->getSkin();
video::IVideoDriver* driver = Environment->getVideoDriver();
// 计算按钮绝对矩形区域的中心点
irr::core::vector2di center = AbsoluteRect.getCenter();
// 计算图像绘制的起始位置,使其居中显示
irr::core::vector2di pos = center;
pos.X -= (s32)(ImageRect.getWidth() * imageScale.X * 0.5f);
pos.Y -= (s32)(ImageRect.getHeight() * imageScale.Y * 0.5f);
// 处理按钮按下状态的视觉效果
if(Pressed) {
// 按下时将图像位置和中心点向下右偏移1个像素
pos.X += 1;
pos.Y += 1;
center.X += 1;
center.Y += 1;
// 如果需要绘制边框,则绘制按下状态的3D按钮面板
if (DrawBorder)
skin->draw3DButtonPanePressed(this, AbsoluteRect, &AbsoluteClippingRect);
} else {
// 如果需要绘制边框,则绘制标准状态的3D按钮面板
if (DrawBorder)
skin->draw3DButtonPaneStandard(this, AbsoluteRect, &AbsoluteClippingRect);
}
// 如果存在图像且允许绘制图像,则执行图像绘制操作
if(Image && isDrawImage)
irr::gui::Draw2DImageRotation(driver, Image, ImageRect, pos, center, imageRotation, imageScale);
// 调用基类的绘制方法完成剩余的绘制工作
IGUIElement::draw();
}
/*!
\brief 设置按钮的图像
\param image 指向要设置的纹理图像的指针
\return 无返回值
*/
void CGUIImageButton::setImage(video::ITexture* image)
{
// 增加新图像的引用计数
if(image)
image->grab();
// 减少旧图像的引用计数并释放资源
if(Image)
Image->drop();
// 更新图像指针
Image = image;
// 如果新图像存在,更新图像矩形区域和缩放比例
if(image) {
ImageRect = core::rect<s32>(core::vector2d<s32>(0, 0), image->getOriginalSize());
if(isFixedSize)
imageScale = core::vector2df((irr::f32)imageSize.Width / image->getSize().Width, (irr::f32)imageSize.Height / image->getSize().Height);
}
// 如果没有设置按下状态的图像,则使用当前图像作为按下状态图像
if(!PressedImage)
setPressedImage(Image);
}
void CGUIImageButton::setDrawImage(bool b) {
isDrawImage = b;
}
......
......@@ -7,21 +7,58 @@ namespace ygo {
unsigned char DataManager::scriptBuffer[0x100000] = {};
DataManager dataManager;
/**
* @brief SQL查询语句,用于从数据库中获取卡片数据和文本信息
*
* 该查询语句通过INNER JOIN连接datas表和texts表,获取完整的卡片信息:
* - datas表包含:卡片ID、OCG/TCG限制、别名、字段码、类型、攻击力、守备力、等级、种族、属性、分类
* - texts表包含:卡片名称、描述、16个额外描述字段(str1-str16)
*
* 查询结果按照卡片ID进行匹配,确保每张卡片的数据和文本信息能够正确关联
*/
static const char SELECT_STMT[] = "SELECT datas.id, datas.ot, datas.alias, datas.setcode, datas.type, datas.atk, datas.def, datas.level, datas.race, datas.attribute, datas.category,"
" texts.name, texts.desc, texts.str1, texts.str2, texts.str3, texts.str4, texts.str5, texts.str6, texts.str7, texts.str8,"
" texts.str9, texts.str10, texts.str11, texts.str12, texts.str13, texts.str14, texts.str15, texts.str16 FROM datas INNER JOIN texts ON datas.id = texts.id";
/**
* @brief DataManager构造函数
* @details 初始化DataManager对象,预分配数据容器和字符串容器的容量,
* 并初始化额外的设置码映射表:拟声希望皇和拟声蜥蜴
*/
DataManager::DataManager() : _datas(32768), _strings(32768) {
// 初始化额外设置码映射表,包含拟声希望皇和拟声蜥蜴的5字段setcode集合(因cdb最多4个字段,在此重新设置)
extra_setcode = {
{8512558u, {0x8f, 0x54, 0x59, 0x82, 0x13a}},
{55088578u, {0x8f, 0x54, 0x59, 0x82, 0x13a}},
};
}
/**
* @brief 从指定的 SQLite 数据库中读取卡牌数据并填充到内部数据结构中。
*
* 此函数执行一个预定义的 SQL 查询语句(SELECT_STMT),遍历查询结果,
* 并将每条记录解析为卡牌数据和字符串信息,分别存储在 [_datas](file://D:\YGOPro_New_Master_Rule\YGOMobile-cn-ko-en\Classes\gframe\data_manager.h#L123-L123) 和 [_strings](file://D:\YGOPro_New_Master_Rule\YGOMobile-cn-ko-en\Classes\gframe\data_manager.h#L124-L124) 中。
* 同时处理额外的 setcode 数据。
*
* @param pDB 指向已打开的 SQLite 数据库对象的指针。
* @return 成功读取并处理所有数据时返回 true;若发生错误则调用 Error 函数并返回其结果。
*/
bool DataManager::ReadDB(sqlite3* pDB) {
sqlite3_stmt* pStmt = nullptr;
const char* sql = "select * from datas,texts where datas.id=texts.id";
if (sqlite3_prepare_v2(pDB, sql, -1, &pStmt, nullptr) != SQLITE_OK)
// 准备 SQL 查询语句
if (sqlite3_prepare_v2(pDB, SELECT_STMT, -1, &pStmt, nullptr) != SQLITE_OK)
return Error(pDB, pStmt);
wchar_t strBuffer[4096];
// 遍历查询结果中的每一行
for (int step = sqlite3_step(pStmt); step != SQLITE_DONE; step = sqlite3_step(pStmt)) {
if (step != SQLITE_ROW)
return Error(pDB, pStmt);
// 提取基本字段数据
uint32_t code = static_cast<uint32_t>(sqlite3_column_int64(pStmt, 0));
auto& cd = _datas[code];
cd.code = code;
......@@ -32,47 +69,66 @@ bool DataManager::ReadDB(sqlite3* pDB) {
cd.type = static_cast<decltype(cd.type)>(sqlite3_column_int64(pStmt, 4));
cd.attack = sqlite3_column_int(pStmt, 5);
cd.defense = sqlite3_column_int(pStmt, 6);
// 处理连接怪兽特殊逻辑:link_marker 存储在 defense 字段中
if (cd.type & TYPE_LINK) {
cd.link_marker = cd.defense;
cd.defense = 0;
}
else
cd.link_marker = 0;
// 解析等级、左右刻度等复合字段
uint32_t level = static_cast<uint32_t>(sqlite3_column_int64(pStmt, 7));
cd.level = level & 0xff;
cd.lscale = (level >> 24) & 0xff;
cd.rscale = (level >> 16) & 0xff;
// 其他基础属性
cd.race = static_cast<decltype(cd.race)>(sqlite3_column_int64(pStmt, 8));
cd.attribute = static_cast<decltype(cd.attribute)>(sqlite3_column_int64(pStmt, 9));
cd.category = static_cast<decltype(cd.category)>(sqlite3_column_int64(pStmt, 10));
// 获取并解码名称与描述文本
auto& cs = _strings[code];
if (const char* text = (const char*)sqlite3_column_text(pStmt, 12)) {
if (const char* text = (const char*)sqlite3_column_text(pStmt, 11)) {
BufferIO::DecodeUTF8(text, strBuffer);
cs.name = strBuffer;
}
if (const char* text = (const char*)sqlite3_column_text(pStmt, 13)) {
if (const char* text = (const char*)sqlite3_column_text(pStmt, 12)) {
BufferIO::DecodeUTF8(text, strBuffer);
cs.text = strBuffer;
}
constexpr int desc_count = sizeof cs.desc / sizeof cs.desc[0];
for (int i = 0; i < desc_count; ++i) {
if (const char* text = (const char*)sqlite3_column_text(pStmt, i + 14)) {
// 解码多个描述字段
for (int i = 0; i < DESC_COUNT; ++i) {
if (const char* text = (const char*)sqlite3_column_text(pStmt, 13 + i)) {
BufferIO::DecodeUTF8(text, strBuffer);
cs.desc[i] = strBuffer;
}
}
}
// 清理 SQL 语句资源
sqlite3_finalize(pStmt);
// 应用额外的 setcode 数据(来自 extra_setcode)
for (const auto& entry : extra_setcode) {
const auto& code = entry.first;
const auto& list = entry.second;
// 忽略无效或超出大小限制的数据
if (list.size() > SIZE_SETCODE || list.empty())
continue;
auto it = _datas.find(code);
if (it == _datas.end())
continue;
// 将额外的 setcode 写入对应卡牌数据
std::memcpy(it->second.setcode, list.data(), list.size() * sizeof(uint16_t));
}
return true;
}
bool DataManager::LoadDB(const wchar_t* wfile) {
......
......@@ -49,10 +49,11 @@ struct CardDataC {
return false;
}
};
constexpr int DESC_COUNT = 16;
struct CardString {
std::wstring name;
std::wstring text;
std::wstring desc[16];
std::wstring desc[DESC_COUNT];
};
using code_pointer = std::unordered_map<uint32_t, CardDataC>::const_iterator;
using string_pointer = std::unordered_map<uint32_t, CardString>::const_iterator;
......
......@@ -377,7 +377,7 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
btnLanMode->setImageSize(irr::core::dimension2di(400 * yScale, 76 * yScale));
btnLanMode->setDrawBorder(false);
btnLanMode->setImage(imageManager.tTitleBar);
textLanMode = env->addStaticText(dataManager.GetSysString(1200), Resize(15, 25, 350, 60), false, false, btnLanMode);
textLanMode = env->addStaticText(dataManager.GetSysString(1200)/*本地联机*/, Resize(15, 25, 350, 60), false, false, btnLanMode);
textLanMode->setOverrideFont(titleFont);
textLanMode->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
//version code
......@@ -389,7 +389,7 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
btnSingleMode->setImageSize(irr::core::dimension2di(400 * yScale, 76 * yScale));
btnSingleMode->setDrawBorder(false);
btnSingleMode->setImage(imageManager.tTitleBar);
textSingleMode = env->addStaticText(dataManager.GetSysString(1201), Resize(15, 25, 350, 60), false, false, btnSingleMode);
textSingleMode = env->addStaticText(dataManager.GetSysString(1201)/*单人游戏*/, Resize(15, 25, 350, 60), false, false, btnSingleMode);
textSingleMode->setOverrideFont(titleFont);
textSingleMode->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
//button Replay Mode
......@@ -397,7 +397,7 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
btnReplayMode->setImageSize(irr::core::dimension2di(400 * yScale, 76 * yScale));
btnReplayMode->setDrawBorder(false);
btnReplayMode->setImage(imageManager.tTitleBar);
textReplayMode = env->addStaticText(dataManager.GetSysString(1202), Resize(15, 25, 350, 60), false, false, btnReplayMode);
textReplayMode = env->addStaticText(dataManager.GetSysString(1202)/*观看录像*/, Resize(15, 25, 350, 60), false, false, btnReplayMode);
textReplayMode->setOverrideFont(titleFont);
textReplayMode->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
//button Deck Edit
......@@ -405,7 +405,7 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
btnDeckEdit->setImageSize(irr::core::dimension2di(400 * yScale, 76 * yScale));
btnDeckEdit->setDrawBorder(false);
btnDeckEdit->setImage(imageManager.tTitleBar);
textDeckEdit = env->addStaticText(dataManager.GetSysString(1204), Resize(15, 25, 350, 60), false, false, btnDeckEdit);
textDeckEdit = env->addStaticText(dataManager.GetSysString(1204)/*编辑卡组*/, Resize(15, 25, 350, 60), false, false, btnDeckEdit);
textDeckEdit->setOverrideFont(titleFont);
textDeckEdit->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
//button Settings
......@@ -413,7 +413,7 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
btnSettings->setImageSize(irr::core::dimension2di(400 * yScale, 76 * yScale));
btnSettings->setDrawBorder(false);
btnSettings->setImage(imageManager.tTitleBar);
textSettings = env->addStaticText(dataManager.GetSysString(1273), Resize(15, 25, 350, 60), false, false, btnSettings);
textSettings = env->addStaticText(dataManager.GetSysString(1273)/*系统设定*/, Resize(15, 25, 350, 60), false, false, btnSettings);
textSettings->setOverrideFont(titleFont);
textSettings->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
//button Exit
......@@ -421,57 +421,57 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
btnModeExit->setImageSize(irr::core::dimension2di(400 * yScale, 76 * yScale));
btnModeExit->setDrawBorder(false);
btnModeExit->setImage(imageManager.tTitleBar);
textModeExit = env->addStaticText(dataManager.GetSysString(1210), Resize(15, 25, 350, 65), false, false, btnModeExit);
textModeExit = env->addStaticText(dataManager.GetSysString(1210)/*退出*/, Resize(15, 25, 350, 65), false, false, btnModeExit);
textModeExit->setOverrideFont(titleFont);
textModeExit->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
//---------------------game windows---------------------
//lan mode
wLanWindow = env->addWindow(Resize(220, 100, 800, 520), false, dataManager.GetSysString(1200));
wLanWindow = env->addWindow(Resize(220, 100, 800, 520), false, dataManager.GetSysString(1200)/*本地联机*/);
wLanWindow->getCloseButton()->setVisible(false);
wLanWindow->setVisible(false);
ChangeToIGUIImageWindow(wLanWindow, &bgLanWindow, imageManager.tWindow);
env->addStaticText(dataManager.GetSysString(1220), Resize(30, 30, 70, 70), false, false, wLanWindow);
env->addStaticText(dataManager.GetSysString(1220)/*昵称:*/, Resize(30, 30, 70, 70), false, false, wLanWindow);
ebNickName = irr::gui::CAndroidGUIEditBox::addAndroidEditBox(gameConf.nickname, true, env, Resize(110, 25, 420, 65), wLanWindow);
ebNickName->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
lstHostList = env->addListBox(Resize(30, 75, 540, 240), wLanWindow, LISTBOX_LAN_HOST, true);
lstHostList->setItemHeight(30 * yScale);
btnLanRefresh = env->addButton(Resize(205, 250, 315, 290), wLanWindow, BUTTON_LAN_REFRESH, dataManager.GetSysString(1217));
ChangeToIGUIImageButton(btnLanRefresh, imageManager.tButton_S, imageManager.tButton_S_pressed);
env->addStaticText(dataManager.GetSysString(1221), Resize(30, 305, 100, 340), false, false, wLanWindow);
env->addStaticText(dataManager.GetSysString(1221)/*主机信息:*/, Resize(30, 305, 100, 340), false, false, wLanWindow);
ebJoinHost = irr::gui::CAndroidGUIEditBox::addAndroidEditBox(gameConf.lasthost, true, env, Resize(110, 300, 270, 340), wLanWindow);
ebJoinHost->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
ebJoinPort = irr::gui::CAndroidGUIEditBox::addAndroidEditBox(gameConf.lastport, true, env, Resize(280, 300, 340, 340), wLanWindow);
ebJoinPort->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
env->addStaticText(dataManager.GetSysString(1222), Resize(30, 355, 100, 390), false, false, wLanWindow);
env->addStaticText(dataManager.GetSysString(1222)/*房间密码:*/, Resize(30, 355, 100, 390), false, false, wLanWindow);
ebJoinPass = irr::gui::CAndroidGUIEditBox::addAndroidEditBox(gameConf.roompass, true, env, Resize(110, 350, 340, 390), wLanWindow);
ebJoinPass->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
btnJoinHost = env->addButton(Resize(430, 300, 540, 340), wLanWindow, BUTTON_JOIN_HOST, dataManager.GetSysString(1223));
btnJoinHost = env->addButton(Resize(430, 300, 540, 340), wLanWindow, BUTTON_JOIN_HOST, dataManager.GetSysString(1223)/*加入游戏*/);
ChangeToIGUIImageButton(btnJoinHost, imageManager.tButton_S, imageManager.tButton_S_pressed);
btnJoinCancel = env->addButton(Resize(430, 350, 540, 390), wLanWindow, BUTTON_JOIN_CANCEL, dataManager.GetSysString(1212));
btnJoinCancel = env->addButton(Resize(430, 350, 540, 390), wLanWindow, BUTTON_JOIN_CANCEL, dataManager.GetSysString(1212)/*取消*/);
ChangeToIGUIImageButton(btnJoinCancel, imageManager.tButton_S, imageManager.tButton_S_pressed);
btnCreateHost = env->addButton(Resize(430, 25, 540, 65), wLanWindow, BUTTON_CREATE_HOST, dataManager.GetSysString(1224));
btnCreateHost = env->addButton(Resize(430, 25, 540, 65), wLanWindow, BUTTON_CREATE_HOST, dataManager.GetSysString(1224)/*局域网建主*/);
ChangeToIGUIImageButton(btnCreateHost, imageManager.tButton_S, imageManager.tButton_S_pressed);
//create host
wCreateHost = env->addWindow(Resize(220, 100, 800, 520), false, dataManager.GetSysString(1224));
wCreateHost = env->addWindow(Resize(220, 100, 800, 520), false, dataManager.GetSysString(1224)/*局域网建主*/);
wCreateHost->getCloseButton()->setVisible(false);
wCreateHost->setVisible(false);
ChangeToIGUIImageWindow(wCreateHost, &bgCreateHost, imageManager.tWindow);
env->addStaticText(dataManager.GetSysString(1226), Resize(20, 30, 90, 65), false, false, wCreateHost);
env->addStaticText(dataManager.GetSysString(1226)/*禁限卡表:*/, Resize(20, 30, 90, 65), false, false, wCreateHost);
cbHostLFlist = irr::gui::CAndroidGUIComboBox::addAndroidComboBox(env, Resize(110, 25, 260, 65), wCreateHost);
for(unsigned int i = 0; i < deckManager._lfList.size(); ++i)
cbHostLFlist->addItem(deckManager._lfList[i].listName.c_str(), deckManager._lfList[i].hash);
cbHostLFlist->setSelected(gameConf.use_lflist ? gameConf.default_lflist : cbHostLFlist->getItemCount() - 1);
env->addStaticText(dataManager.GetSysString(1225), Resize(20, 75, 100, 110), false, false, wCreateHost);
env->addStaticText(dataManager.GetSysString(1225)/*卡片允许:*/, Resize(20, 75, 100, 110), false, false, wCreateHost);
cbRule = irr::gui::CAndroidGUIComboBox::addAndroidComboBox(env, Resize(110, 75, 260, 115), wCreateHost);
cbRule->setMaxSelectionRows(10);
cbRule->addItem(dataManager.GetSysString(1481));
cbRule->addItem(dataManager.GetSysString(1482));
cbRule->addItem(dataManager.GetSysString(1483));
cbRule->addItem(dataManager.GetSysString(1484));
cbRule->addItem(dataManager.GetSysString(1485));
cbRule->addItem(dataManager.GetSysString(1486));
cbRule->addItem(dataManager.GetSysString(1481));// OCG
cbRule->addItem(dataManager.GetSysString(1482));// TCG
cbRule->addItem(dataManager.GetSysString(1483));// 简体中文
cbRule->addItem(dataManager.GetSysString(1484));// 自定义卡片
cbRule->addItem(dataManager.GetSysString(1485));// 无独有卡
cbRule->addItem(dataManager.GetSysString(1486));// 所有卡片
switch(gameConf.defaultOT) {
case 1:
cbRule->setSelected(0);
......@@ -489,22 +489,22 @@ bool Game::Initialize(ANDROID_APP app, irr::android::InitOptions *options) {
cbRule->setSelected(5);
break;
}
env->addStaticText(dataManager.GetSysString(1227), Resize(20, 130, 100, 165), false, false, wCreateHost);
env->addStaticText(dataManager.GetSysString(1227)/*决斗模式:*/, Resize(20, 130, 100, 165), false, false, wCreateHost);
cbMatchMode = irr::gui::CAndroidGUIComboBox::addAndroidComboBox(env, Resize(110, 125, 260, 165), wCreateHost);
cbMatchMode->addItem(dataManager.GetSysString(1244));
cbMatchMode->addItem(dataManager.GetSysString(1245));
cbMatchMode->addItem(dataManager.GetSysString(1246));
env->addStaticText(dataManager.GetSysString(1237), Resize(20, 180, 100, 215), false, false, wCreateHost);
cbMatchMode->addItem(dataManager.GetSysString(1244));// 单局模式
cbMatchMode->addItem(dataManager.GetSysString(1245));// 比赛模式
cbMatchMode->addItem(dataManager.GetSysString(1246));// TAG
env->addStaticText(dataManager.GetSysString(1237)/*每回合时间:*/, Resize(20, 180, 100, 215), false, false, wCreateHost);
myswprintf(strbuf, L"%d", 180);
ebTimeLimit = irr::gui::CAndroidGUIEditBox::addAndroidEditBox(strbuf, true, env, Resize(110, 175, 260, 215), wCreateHost);
ebTimeLimit->setTextAlignment(irr::gui::EGUIA_CENTER, irr::gui::EGUIA_CENTER);
env->addStaticText(dataManager.GetSysString(1236), Resize(270, 30, 350, 65), false, false, wCreateHost);
env->addStaticText(dataManager.GetSysString(1236)/*规则:*/, Resize(270, 30, 350, 65), false, false, wCreateHost);
cbDuelRule = irr::gui::CAndroidGUIComboBox::addAndroidComboBox(env, Resize(360, 25, 510, 65), wCreateHost);
cbDuelRule->addItem(dataManager.GetSysString(1260));
cbDuelRule->addItem(dataManager.GetSysString(1261));
cbDuelRule->addItem(dataManager.GetSysString(1262));
cbDuelRule->addItem(dataManager.GetSysString(1263));
cbDuelRule->addItem(dataManager.GetSysString(1264));
cbDuelRule->addItem(dataManager.GetSysString(1260));// 大师规则
cbDuelRule->addItem(dataManager.GetSysString(1261));// 大师规则2
cbDuelRule->addItem(dataManager.GetSysString(1262));// 大师规则3
cbDuelRule->addItem(dataManager.GetSysString(1263));// 新大师规则(2017)
cbDuelRule->addItem(dataManager.GetSysString(1264));// 大师规则(2020)
cbDuelRule->setSelected(gameConf.default_rule - 1);
chkNoCheckDeck = env->addCheckBox(false, Resize(250, 235, 350, 275), wCreateHost, -1, dataManager.GetSysString(1229));
chkNoShuffleDeck = env->addCheckBox(false, Resize(360, 235, 460, 275), wCreateHost, -1, dataManager.GetSysString(1230));
......@@ -1626,11 +1626,11 @@ void Game::MainLoop() {
if(waitFrame >= 0) {
waitFrame++;
if(waitFrame % 90 == 0) {
stHintMsg->setText(dataManager.GetSysString(1390)); // 提示文字1
stHintMsg->setText(dataManager.GetSysString(1390)); // "等待行动中..."
} else if(waitFrame % 90 == 30) {
stHintMsg->setText(dataManager.GetSysString(1391)); // 提示文字2
stHintMsg->setText(dataManager.GetSysString(1391)); // "等待行动中...."
} else if(waitFrame % 90 == 60) {
stHintMsg->setText(dataManager.GetSysString(1392)); // 提示文字3
stHintMsg->setText(dataManager.GetSysString(1392)); // "等待行动中....."
}
}
......@@ -1817,9 +1817,9 @@ void Game::RefreshCategoryDeck(irr::gui::IGUIComboBox* cbCategory, irr::gui::IGU
if (cbCategory == mainGame->cbDBCategory) {
cbCategory->addItem(dataManager.GetSysString(1450));
}
cbCategory->addItem(dataManager.GetSysString(1451));
cbCategory->addItem(dataManager.GetSysString(1452));
cbCategory->addItem(dataManager.GetSysString(1453));
cbCategory->addItem(dataManager.GetSysString(1451));// 人机卡组
cbCategory->addItem(dataManager.GetSysString(1452));// 未分类卡组
cbCategory->addItem(dataManager.GetSysString(1453));// --------(分割线)
FileSystem::TraversalDir(L"./deck", [cbCategory](const wchar_t* name, bool isdir) {
if(isdir) {
cbCategory->addItem(name);
......@@ -1941,7 +1941,7 @@ void Game::RefreshBot() {
lstBotList->addItem(botInfo[i].name);
}
if(botInfo.size() == 0) {
SetStaticText(stBotInfo, 200, guiFont, dataManager.GetSysString(1385));
SetStaticText(stBotInfo, 200, guiFont, dataManager.GetSysString(1385)); // 此模式人机尚未实装
}
else {
RefreshCategoryDeck(cbBotDeckCategory, cbBotDeck);
......@@ -1953,7 +1953,7 @@ void Game::RefreshBot() {
if (cbBotDeck->getItemCount() != 0) {
myswprintf(cate_deck, L"%ls%ls", cate, cbBotDeck->getItem(cbBotDeck->getSelected()));
} else {
myswprintf(cate_deck, L"%ls%ls", cate, dataManager.GetSysString(1301));
myswprintf(cate_deck, L"%ls%ls", cate, dataManager.GetSysString(1301));// 未选择卡组!
}
mainGame->btnBotDeckSelect->setText(cate_deck);
}
......@@ -2114,7 +2114,7 @@ void Game::ShowCardInfo(int code) {
if (target->second.setcode[0]) {
offset = 23; // 固定偏移量用于布局调整
const auto& setname = dataManager.FormatSetName(target->second.setcode);
myswprintf(formatBuffer, L"%ls%ls", dataManager.GetSysString(1329), setname.c_str());
myswprintf(formatBuffer, L"%ls%ls", dataManager.GetSysString(1329), setname.c_str()); // 字段:
stSetName->setText(formatBuffer);
}
else
......
......@@ -8,6 +8,7 @@
#ifndef CANDROIDGUISKIN_H_
#define CANDROIDGUISKIN_H_
// 包含必要的Irrlicht图形用户界面头文件
#include <IGUISkin.h>
#include <irrString.h>
#include <IrrCompileConfig.h>
......@@ -17,224 +18,132 @@
namespace irr {
namespace gui {
// 定义Android GUI皮肤类,继承自IGUISkin接口
class CAndroidGUISkin: public IGUISkin {
public:
// 构造函数,初始化皮肤类型、视频驱动和缩放因子
CAndroidGUISkin(EGUI_SKIN_TYPE type, video::IVideoDriver* driver, float x, float y);
// 静态工厂方法,创建Android皮肤实例
static CAndroidGUISkin* createAndroidSkin(EGUI_SKIN_TYPE type, video::IVideoDriver* driver, IGUIEnvironment* env, float x, float y);
//! destructor
// 析构函数
virtual ~CAndroidGUISkin();
//! returns default color
// 获取默认颜色值
virtual video::SColor getColor(EGUI_DEFAULT_COLOR color) const _IRR_OVERRIDE_;
//! sets a default color
// 设置指定类型的默认颜色
virtual void setColor(EGUI_DEFAULT_COLOR which, video::SColor newColor) _IRR_OVERRIDE_;
//! returns size for the given size type
// 获取指定类型的尺寸大小
virtual s32 getSize(EGUI_DEFAULT_SIZE size) const _IRR_OVERRIDE_;
//! sets a default size
// 设置指定类型的尺寸大小
virtual void setSize(EGUI_DEFAULT_SIZE which, s32 size) _IRR_OVERRIDE_;
//! returns the default font
// 获取默认字体
virtual IGUIFont* getFont(EGUI_DEFAULT_FONT which=EGDF_DEFAULT) const _IRR_OVERRIDE_;
//! sets a default font
// 设置默认字体
virtual void setFont(IGUIFont* font, EGUI_DEFAULT_FONT which=EGDF_DEFAULT) _IRR_OVERRIDE_;
//! sets the sprite bank used for drawing icons
// 设置用于绘制图标的SpriteBank
virtual void setSpriteBank(IGUISpriteBank* bank) _IRR_OVERRIDE_;
//! gets the sprite bank used for drawing icons
// 获取用于绘制图标的SpriteBank
virtual IGUISpriteBank* getSpriteBank() const _IRR_OVERRIDE_;
//! Returns a default icon
/** Returns the sprite index within the sprite bank */
// 返回默认图标索引
virtual u32 getIcon(EGUI_DEFAULT_ICON icon) const _IRR_OVERRIDE_;
//! Sets a default icon
/** Sets the sprite index used for drawing icons like arrows,
close buttons and ticks in checkboxes
\param icon: Enum specifying which icon to change
\param index: The sprite index used to draw this icon */
// 设置默认图标
virtual void setIcon(EGUI_DEFAULT_ICON icon, u32 index) _IRR_OVERRIDE_;
//! Returns a default text.
/** For example for Message box button captions:
"OK", "Cancel", "Yes", "No" and so on. */
// 返回默认文本(如消息框按钮标题:"确定"、"取消"等)
virtual const wchar_t* getDefaultText(EGUI_DEFAULT_TEXT text) const _IRR_OVERRIDE_;
//! Sets a default text.
/** For example for Message box button captions:
"OK", "Cancel", "Yes", "No" and so on. */
// 设置默认文本
virtual void setDefaultText(EGUI_DEFAULT_TEXT which, const wchar_t* newText) _IRR_OVERRIDE_;
//! draws a standard 3d button pane
/** Used for drawing for example buttons in normal state.
It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
\param rect: Defining area where to draw.
\param clip: Clip area.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly. */
// 绘制标准3D按钮面板
virtual void draw3DButtonPaneStandard(IGUIElement* element,
const core::rect<s32>& rect,
const core::rect<s32>* clip=0) _IRR_OVERRIDE_;
//! draws a pressed 3d button pane
/** Used for drawing for example buttons in pressed state.
It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
\param rect: Defining area where to draw.
\param clip: Clip area.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly. */
// 绘制按下状态的3D按钮面板
virtual void draw3DButtonPanePressed(IGUIElement* element,
const core::rect<s32>& rect,
const core::rect<s32>* clip=0) _IRR_OVERRIDE_;
//! draws a sunken 3d pane
/** Used for drawing the background of edit, combo or check boxes.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param bgcolor: Background color.
\param flat: Specifies if the sunken pane should be flat or displayed as sunken
deep into the ground.
\param rect: Defining area where to draw.
\param clip: Clip area. */
// 绘制凹陷的3D面板(用于编辑框、组合框或复选框背景)
virtual void draw3DSunkenPane(IGUIElement* element,
video::SColor bgcolor, bool flat,
bool fillBackGround,
const core::rect<s32>& rect,
const core::rect<s32>* clip=0) _IRR_OVERRIDE_;
//! draws a window background
/** Used for drawing the background of dialogs and windows.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param titleBarColor: Title color.
\param drawTitleBar: True to enable title drawing.
\param rect: Defining area where to draw.
\param clip: Clip area.
\param checkClientArea: When set to non-null the function will not draw anything,
but will instead return the clientArea which can be used for drawing by the calling window.
That is the area without borders and without titlebar.
\return Returns rect where it would be good to draw title bar text. This will
work even when checkClientArea is set to a non-null value.*/
// 绘制窗口背景
virtual core::rect<s32> draw3DWindowBackground(IGUIElement* element,
bool drawTitleBar, video::SColor titleBarColor,
const core::rect<s32>& rect,
const core::rect<s32>* clip,
core::rect<s32>* checkClientArea) _IRR_OVERRIDE_;
//! draws a standard 3d menu pane
/** Used for drawing for menus and context menus.
It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param rect: Defining area where to draw.
\param clip: Clip area. */
// 绘制标准3D菜单面板
virtual void draw3DMenuPane(IGUIElement* element,
const core::rect<s32>& rect,
const core::rect<s32>* clip=0) _IRR_OVERRIDE_;
//! draws a standard 3d tool bar
/** Used for drawing for toolbars and menus.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param rect: Defining area where to draw.
\param clip: Clip area. */
// 绘制标准3D工具栏
virtual void draw3DToolBar(IGUIElement* element,
const core::rect<s32>& rect,
const core::rect<s32>* clip=0) _IRR_OVERRIDE_;
//! draws a tab button
/** Used for drawing for tab buttons on top of tabs.
\param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param active: Specifies if the tab is currently active.
\param rect: Defining area where to draw.
\param clip: Clip area. */
// 绘制标签按钮
virtual void draw3DTabButton(IGUIElement* element, bool active,
const core::rect<s32>& rect, const core::rect<s32>* clip=0,
EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT) _IRR_OVERRIDE_;
//! draws a tab control body
/** \param element: Pointer to the element which wishes to draw this. This parameter
is usually not used by ISkin, but can be used for example by more complex
implementations to find out how to draw the part exactly.
\param border: Specifies if the border should be drawn.
\param background: Specifies if the background should be drawn.
\param rect: Defining area where to draw.
\param clip: Clip area. */
// 绘制标签控制主体
virtual void draw3DTabBody(IGUIElement* element, bool border, bool background,
const core::rect<s32>& rect, const core::rect<s32>* clip=0, s32 tabHeight=-1,
EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT) _IRR_OVERRIDE_;
//! draws an icon, usually from the skin's sprite bank
/** \param element: Pointer to the element which wishes to draw this icon.
This parameter is usually not used by IGUISkin, but can be used for example
by more complex implementations to find out how to draw the part exactly.
\param icon: Specifies the icon to be drawn.
\param position: The position to draw the icon
\param starttime: The time at the start of the animation
\param currenttime: The present time, used to calculate the frame number
\param loop: Whether the animation should loop or not
\param clip: Clip area. */
// 绘制图标(通常来自皮肤的SpriteBank)
virtual void drawIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon,
const core::position2di position,
u32 starttime=0, u32 currenttime=0,
bool loop=false, const core::rect<s32>* clip=0) _IRR_OVERRIDE_;
//! draws a 2d rectangle.
/** \param element: Pointer to the element which wishes to draw this icon.
This parameter is usually not used by IGUISkin, but can be used for example
by more complex implementations to find out how to draw the part exactly.
\param color: Color of the rectangle to draw. The alpha component specifies how
transparent the rectangle will be.
\param pos: Position of the rectangle.
\param clip: Pointer to rectangle against which the rectangle will be clipped.
If the pointer is null, no clipping will be performed. */
// 绘制2D矩形
virtual void draw2DRectangle(IGUIElement* element, const video::SColor &color,
const core::rect<s32>& pos, const core::rect<s32>* clip = 0) _IRR_OVERRIDE_;
//! get the type of this skin
// 获取此皮肤的类型
virtual EGUI_SKIN_TYPE getType() const _IRR_OVERRIDE_;
//! Writes attributes of the skin
// 写入皮肤属性
virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const _IRR_OVERRIDE_;
//! Reads attributes of the skin
// 读取皮肤属性
virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0) _IRR_OVERRIDE_;
private:
video::SColor Colors[EGDC_COUNT];
s32 Sizes[EGDS_COUNT];
u32 Icons[EGDI_COUNT];
IGUIFont* Fonts[EGDF_COUNT];
IGUISpriteBank* SpriteBank;
core::stringw Texts[EGDT_COUNT];
irr::video::IVideoDriver* Driver;
bool UseGradient;
EGUI_SKIN_TYPE Type;
float XScale;
float YScale;
// 私有成员变量:存储各种GUI元素的颜色、尺寸、图标、字体等属性
video::SColor Colors[EGDC_COUNT]; // 颜色数组
s32 Sizes[EGDS_COUNT]; // 尺寸数组
u32 Icons[EGDI_COUNT]; // 图标索引数组
IGUIFont* Fonts[EGDF_COUNT]; // 字体指针数组
IGUISpriteBank* SpriteBank; // SpriteBank指针
core::stringw Texts[EGDT_COUNT]; // 文本字符串数组
irr::video::IVideoDriver* Driver; // 视频驱动指针
bool UseGradient; // 是否使用渐变效果标志
EGUI_SKIN_TYPE Type; // 皮肤类型
float XScale; // X轴缩放因子
float YScale; // Y轴缩放因子
};
} /* namespace gui */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment