nodeeditor 源码阅读 - ConnectionStyle连接风格类

目录

1. ConnectionStyle类实现 

2. 定制连接风格

3. 默认配置 


1. ConnectionStyle类实现 

这段代码的主要目的是定义了一个连接样式的类,用于加载、存储和管理连接的外观配置信息。它包含了构造函数、加载和保存配置信息的方法,以及一些用于获取特定属性值的函数。此外,还包含了一些用于检查和处理JSON数据的宏和条件编译的调试功能。 

ConnectionStyle.hpp

#pragma once

#include <QtGui/QColor>

#include "Export.hpp"   // 用于导出类,以便其他模块或库可以访问 ConnectionStyle 类。
#include "Style.hpp"    // 用于继承 Style 类

namespace QtNodes {

class NODE_EDITOR_PUBLIC ConnectionStyle : public Style
{
public:
    ConnectionStyle();  // 默认构造函数的声明

    ConnectionStyle(QString jsonText);  // 带有参数的构造函数的声明, JSON文本字符串作为参数

    ~ConnectionStyle() = default;

public:
    // 静态成员函数的声明,用于设置连接样式,JSON 文本字符串作为参数。
    // 可直接类名调用
    static void setConnectionStyle(QString jsonText);

public:
    // 虚函数的声明,实现父类中纯虚函数,用于加载《连接》样式的配置信息
    void loadJson(QJsonObject const &json) override;
    // 虚函数的声明,用于将连接样式的配置信息转换为 JSON 对象。
    QJsonObject toJson() const override;

public:
    // 一系列的成员函数的声明,用于获取不同连接样式属性的值,
    
    // 如构造连接颜色、正常连接颜色、选定连接颜色等。
    QColor constructionColor() const;
    QColor normalColor() const;
    QColor normalColor(QString typeId) const;
    QColor selectedColor() const;
    QColor selectedHaloColor() const;
    QColor hoveredColor() const;
    
    // 线宽
    float lineWidth() const;
    float constructionLineWidth() const;
    float pointDiameter() const;

    bool useDataDefinedColors() const;

private:
    // 一系列的私有成员变量的声明,用于存储连接样式的不同属性值,如颜色、线宽等。
    // 各种颜色
    QColor ConstructionColor;
    QColor NormalColor;
    QColor SelectedColor;
    QColor SelectedHaloColor;
    QColor HoveredColor;
    
    // 线宽
    float LineWidth;
    float ConstructionLineWidth;
    float PointDiameter;

    bool UseDataDefinedColors;
};
} // namespace QtNodes

ConnectionStyle.cpp

#include "ConnectionStyle.hpp"

#include "StyleCollection.hpp"  // 用于设置风格StyleCollection::setConnectionStyle(style);

#include <QtCore/QJsonArray>
#include <QtCore/QJsonObject>
#include <QtCore/QJsonValueRef>

#include <QDebug>

#include <random>

using QtNodes::ConnectionStyle;

// 确保静态资源(图片文件,json文件等)的正确加载
// 如果你有一个名为 myapp.qrc 的资源文件,那么你可以在代码中使用 Q_INIT_RESOURCE(myapp);
// 这句代码,写在类的构造函数中,可确保在静态链接的情况下将资源链接到
// 最终的应用程序二进制文件中;写在main函数中,则全局可以使用。
// 同理,在将资源卸载的时候,需要调用Q_CLEANUP_RESOURCE()。
inline void initResources()  // 在ConnectionStyle构造函数中被调用
{
    Q_INIT_RESOURCE(resources);  // 用于初始化Qt资源系统的语句
}

// 默认构造函数的定义。在这个构造函数中,会调用initResources()来初始化资源,
// 然后通过调用loadJsonFile(":DefaultStyle.json")加载默认的样式配置。
ConnectionStyle::ConnectionStyle()
{
    // Explicit resources inialization for preventing the static initialization
    // order fiasco: https://isocpp.org/wiki/faq/ctors#static-init-order
    initResources();

    // This configuration is stored inside the compiled unit and is loaded statically
    loadJsonFile(":DefaultStyle.json");
}

// 带有参数的构造函数的定义。这个构造函数接受一个JSON文本字符串作为参数,
// 它会加载默认的样式配置并从传入的JSON文本中加载额外的配置。
ConnectionStyle::ConnectionStyle(QString jsonText)
{
    loadJsonFile(":DefaultStyle.json");  // 继承自父类Style,父类有个纯虚函数loadJson,被子类ConnectionStyle实现,并对自己的私有成员变量赋值。
    loadJsonText(jsonText);
}

// 定义了一个用于从JSON对象加载连接样式配置的函数。
// 这个函数根据JSON对象的键值对,解析并设置连接样式的各个属性。
void ConnectionStyle::setConnectionStyle(QString jsonText)
{
    ConnectionStyle style(jsonText);

    StyleCollection::setConnectionStyle(style);
}

// 一系列用于读取和写入颜色、浮点数和布尔值的宏。
// 这些宏用于将连接样式的不同属性从JSON对象中读取和写入。
#ifdef STYLE_DEBUG
#define CONNECTION_STYLE_CHECK_UNDEFINED_VALUE(v, variable) \
    { \
        if (v.type() == QJsonValue::Undefined || v.type() == QJsonValue::Null) \
            qWarning() << "Undefined value for parameter:" << #variable; \
    }
#else
#define CONNECTION_STYLE_CHECK_UNDEFINED_VALUE(v, variable)
#endif

#define CONNECTION_VALUE_EXISTS(v) \
    (v.type() != QJsonValue::Undefined && v.type() != QJsonValue::Null)

#define CONNECTION_STYLE_READ_COLOR(values, variable) \
    { \
        auto valueRef = values[#variable]; \
        CONNECTION_STYLE_CHECK_UNDEFINED_VALUE(valueRef, variable) \
        if (CONNECTION_VALUE_EXISTS(valueRef)) { \
            if (valueRef.isArray()) { \
                auto colorArray = valueRef.toArray(); \
                std::vector<int> rgb; \
                rgb.reserve(3); \
                for (auto it = colorArray.begin(); it != colorArray.end(); ++it) { \
                    rgb.push_back((*it).toInt()); \
                } \
                variable = QColor(rgb[0], rgb[1], rgb[2]); \
            } else { \
                variable = QColor(valueRef.toString()); \
            } \
        } \
    }

#define CONNECTION_STYLE_WRITE_COLOR(values, variable) \
    { \
        values[#variable] = variable.name(); \
    }

#define CONNECTION_STYLE_READ_FLOAT(values, variable) \
    { \
        auto valueRef = values[#variable]; \
        CONNECTION_STYLE_CHECK_UNDEFINED_VALUE(valueRef, variable) \
        if (CONNECTION_VALUE_EXISTS(valueRef)) \
            variable = valueRef.toDouble(); \
    }

#define CONNECTION_STYLE_WRITE_FLOAT(values, variable) \
    { \
        values[#variable] = variable; \
    }

#define CONNECTION_STYLE_READ_BOOL(values, variable) \
    { \
        auto valueRef = values[#variable]; \
        CONNECTION_STYLE_CHECK_UNDEFINED_VALUE(valueRef, variable) \
        if (CONNECTION_VALUE_EXISTS(valueRef)) \
            variable = valueRef.toBool(); \
    }

#define CONNECTION_STYLE_WRITE_BOOL(values, variable) \
    { \
        values[#variable] = variable; \
    }

// 实现父类中纯虚函数,用于加载《连接》样式的配置信息
void ConnectionStyle::loadJson(QJsonObject const &json)
{
    QJsonValue nodeStyleValues = json["ConnectionStyle"];

    QJsonObject obj = nodeStyleValues.toObject();

    CONNECTION_STYLE_READ_COLOR(obj, ConstructionColor);
    CONNECTION_STYLE_READ_COLOR(obj, NormalColor);
    CONNECTION_STYLE_READ_COLOR(obj, SelectedColor);
    CONNECTION_STYLE_READ_COLOR(obj, SelectedHaloColor);
    CONNECTION_STYLE_READ_COLOR(obj, HoveredColor);

    CONNECTION_STYLE_READ_FLOAT(obj, LineWidth);
    CONNECTION_STYLE_READ_FLOAT(obj, ConstructionLineWidth);
    CONNECTION_STYLE_READ_FLOAT(obj, PointDiameter);

    CONNECTION_STYLE_READ_BOOL(obj, UseDataDefinedColors);
}

// 定义了一个将连接样式配置转换为JSON对象的函数。
// 这个函数创建一个JSON对象,将连接样式的各个属性存储在对象中,并返回该对象。
QJsonObject ConnectionStyle::toJson() const
{
    QJsonObject obj;
    
    // 将连接样式的各个属性存储在JSON对象中
    CONNECTION_STYLE_WRITE_COLOR(obj, ConstructionColor);
    CONNECTION_STYLE_WRITE_COLOR(obj, NormalColor);
    CONNECTION_STYLE_WRITE_COLOR(obj, SelectedColor);
    CONNECTION_STYLE_WRITE_COLOR(obj, SelectedHaloColor);
    CONNECTION_STYLE_WRITE_COLOR(obj, HoveredColor);

    CONNECTION_STYLE_WRITE_FLOAT(obj, LineWidth);
    CONNECTION_STYLE_WRITE_FLOAT(obj, ConstructionLineWidth);
    CONNECTION_STYLE_WRITE_FLOAT(obj, PointDiameter);

    CONNECTION_STYLE_WRITE_BOOL(obj, UseDataDefinedColors);

    QJsonObject root;   // JSON对象
    root["ConnectionStyle"] = obj;  // 将json对象放置在root json对象的其中一个成员
    return root;
}

// 定义了一个返回连接的颜色的函数。
QColor ConnectionStyle::constructionColor() const
{
    return ConstructionColor;
}

// 返回正常连接的颜色的函数。
QColor ConnectionStyle::normalColor() const
{
    return NormalColor;
}

//  定义了一个返回特定类型的正常连接颜色的函数,根据传入的类型ID生成颜色。
QColor ConnectionStyle::normalColor(QString typeId) const
{
    std::size_t hash = qHash(typeId);

    std::size_t const hue_range = 0xFF;

    std::mt19937 gen(static_cast<unsigned int>(hash));
    std::uniform_int_distribution<int> distrib(0, hue_range);

    int hue = distrib(gen);
    int sat = 120 + hash % 129;

    return QColor::fromHsl(hue, sat, 160);
}

// 选定连接颜色的函数
QColor ConnectionStyle::selectedColor() const
{
    return SelectedColor;
}

// 选定连接光晕颜色的函数
QColor ConnectionStyle::selectedHaloColor() const
{
    return SelectedHaloColor;
}

// 悬停连接颜色的函数
QColor ConnectionStyle::hoveredColor() const
{
    return HoveredColor;
}

// 返回线宽的函数。
float ConnectionStyle::lineWidth() const
{
    return LineWidth;
}

// 返回构造线宽的函数。
float ConnectionStyle::constructionLineWidth() const
{
    return ConstructionLineWidth;
}

// 返回点直径的函数。
float ConnectionStyle::pointDiameter() const
{
    return PointDiameter;
}

// 定义了一个返回是否使用数据定义颜色的函数,用于判断是否启用了数据定义的颜色。
bool ConnectionStyle::useDataDefinedColors() const
{
    return UseDataDefinedColors;
}

2. 定制连接风格

调用形式 

// 设置风格
setStyle();
static void setStyle()
{
    // 字符串前面加R,则该字符串是原始字符串,里面的都是普通字符。
    // 连接风格设置内容:
    // "ConstructionColor": "gray",
    // "NormalColor" : "black",
    // "SelectedColor" : "gray",
    // "SelectedHaloColor" : "deepskyblue",
    // "HoveredColor" : "deepskyblue",
    //
    // "LineWidth" : 3.0,
    // "ConstructionLineWidth" : 2.0,
    // "PointDiameter" : 10.0,
    //
    // "UseDataDefinedColors" : true
    ConnectionStyle::setConnectionStyle(  
        R"(
  {
    "ConnectionStyle": {
      "ConstructionColor": "gray",          
      "NormalColor": "black",
      "SelectedColor": "gray",
      "SelectedHaloColor": "deepskyblue",
      "HoveredColor": "deepskyblue",

      "LineWidth": 3.0,
      "ConstructionLineWidth": 2.0,
      "PointDiameter": 10.0,

      "UseDataDefinedColors": true
    }
  }
  )");
}

// 两步:
// (1) 使用QString jsonTexts创建ConnectionStyle对象style
// (2) 然后在风格集合类StyleCollection设置连接风格为style
void ConnectionStyle::setConnectionStyle(QString jsonText)
{
    ConnectionStyle style(jsonText);  // 首先载入默认配置,再增加新增配置

    StyleCollection::setConnectionStyle(style);  // 内部生成一个单例静态对象
}

QString 传入的键值对,以json格式查看

3. 默认配置 

{
  "GraphicsViewStyle": {
    "BackgroundColor": [53, 53, 53],
    "FineGridColor": [60, 60, 60],
    "CoarseGridColor": [25, 25, 25]
  },
  "NodeStyle": {
    "NormalBoundaryColor": [255, 255, 255],
    "SelectedBoundaryColor": [255, 165, 0],
    "GradientColor0": "gray",
    "GradientColor1": [80, 80, 80],
    "GradientColor2": [64, 64, 64],
    "GradientColor3": [58, 58, 58],
    "ShadowColor": [20, 20, 20],
    "FontColor" : "white",
    "FontColorFaded" : "gray",
    "ConnectionPointColor": [169, 169, 169],
    "FilledConnectionPointColor": "cyan",
    "ErrorColor": "red",
    "WarningColor": [128, 128, 0],

    "PenWidth": 1.0,
    "HoveredPenWidth": 1.5,

    "ConnectionPointDiameter": 8.0,

    "Opacity": 0.8
  },
  "ConnectionStyle": {
    "ConstructionColor": "gray",
    "NormalColor": "darkcyan",
    "SelectedColor": [100, 100, 100],
    "SelectedHaloColor": "orange",
    "HoveredColor": "lightcyan",

    "LineWidth": 3.0,
    "ConstructionLineWidth": 2.0,
    "PointDiameter": 10.0,

    "UseDataDefinedColors": false
  }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Hive是一个基于Hadoop的数据仓库基础结构,它提供了SQL查询和数据分析功能。Hive的源代码阅读是指对Hive项目的源代码进行逐行分析和理解,以深入了解Hive的内部工作原理和实现细节。 Hive的源代码阅读可以从导读开始。导读部分是Hive代码仓库中的一些重要文档和指南,它们提供了关于Hive项目的概述和指导。 首先,我们可以阅读Hive项目的README文件。该文件通常包含了对项目的介绍、功能特点和使用说明。README文件一般会介绍Hive的目标、核心组件和HiveQL查询语言等内容,为我们提供了整体了解Hive的入口。 接下来,我们可以查看Hive项目中的文档目录。在这个目录下,我们可以找到各种文档、指南和设计文档,它们详细描述了Hive的不同方面和内部机制。这些文档可以帮助我们了解Hive的体系结构、数据处理流程、优化技巧等内容,为后续阅读源代码提供了必要的背景知识。 此外,还可以关注Hive项目的WIKI页面。Hive的WIKI页面常常有丰富的内容,包括开发指南、常见问题解答等。这些页面中提供了一些较为具体和实用的信息,可以帮助我们更好地理解Hive的源代码。 在阅读Hive源代码时,我们应该注重核心模块和关键的分析。可以从查询解析器、查询优化器和执行引擎等模块开始阅读。这些模块负责将HiveQL查询转化为Hadoop任务并执行查询操作。 最后,我们还可以参考Hive源代码中的注释和代码文档。良好的代码注释可以帮助我们理解代码的意图和实现细节,而代码文档则可以提供更加详细的说明和使用方法。 综上所述,Hive源码阅读的导读包括了阅读README文件、查看文档目录和WIKI页面、重点关注核心模块和关键的分析,以及参考代码注释和文档等内容。通过导读,我们可以为接下来的源码阅读做好准备,更好地理解Hive的工作原理和实现方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Q

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值