Commit c9174ca4 authored by captainwong's avatar captainwong

update

parent c024947b
#pragma once #pragma once
#include "qt_global.h" #include "qt_global.h"
#include <system_error> #include <system_error>
#include <QString> #include <QString>
JLIBQT_NAMESPACE_BEGIN JLIBQT_NAMESPACE_BEGIN
//! 获取错误码文字描述 //! 获取错误码文字描述
inline QString ecString(const std::error_code& ec) { inline QString ecString(const std::error_code& ec) {
return QString::fromLocal8Bit(ec.message().data()); return QString::fromLocal8Bit(ec.message().data());
} }
//! 获取错误码文字描述(带有错误目录) //! 获取错误码文字描述(带有错误目录)
inline QString ecStringWithCategory(const std::error_code& ec) { inline QString ecStringWithCategory(const std::error_code& ec) {
return QString::fromLocal8Bit(ec.category().name()) + ": " + QString::fromLocal8Bit(ec.message().data()); return QString::fromLocal8Bit(ec.category().name()) + ": " + QString::fromLocal8Bit(ec.message().data());
} }
#define BREAK_IF_QUERY_FAILED(ec_type) if (!ok) { \ #define BREAK_IF_QUERY_FAILED(ec_type) if (!ok) { \
ec = ec_type; \ ec = ec_type; \
MYQCRITICAL << ecStringWithCategory(ec) << "\n" << query.lastError(); \ MYQCRITICAL << ecStringWithCategory(ec) << "\n" << query.lastError(); \
break; \ break; \
} }
enum class DatabaseErrorCode { enum class DatabaseErrorCode {
OpenDbFailed = 1, OpenDbFailed = 1,
CreateDbTableFailed, CreateDbTableFailed,
QueryDbFailed, QueryDbFailed,
}; };
JLIBQT_NAMESPACE_END JLIBQT_NAMESPACE_END
#define ENABLE_ENUM_AS_ERROR_CODE(type) \ #define ENABLE_ENUM_AS_ERROR_CODE(type) \
namespace std { \ namespace std { \
template <> struct is_error_code_enum<type> : true_type {}; \ template <> struct is_error_code_enum<type> : true_type {}; \
std::error_code make_error_code(type); \ std::error_code make_error_code(type); \
} }
ENABLE_ENUM_AS_ERROR_CODE(JLIBQT_NAMESPACE DatabaseErrorCode) ENABLE_ENUM_AS_ERROR_CODE(JLIBQT_NAMESPACE DatabaseErrorCode)
std::error_code std::make_error_code(JLIBQT_NAMESPACE DatabaseErrorCode ec); std::error_code std::make_error_code(JLIBQT_NAMESPACE DatabaseErrorCode ec);
#pragma once #pragma once
#include <QDebug> #include <QDebug>
#include <QDateTime> #include <QDateTime>
#ifdef _WIN32 #ifdef _WIN32
#include <Windows.h> #include <Windows.h>
#endif //_WIN32 #endif //_WIN32
#define JLIBQT_QDEBUG_FILE_LINE_STREAM "[" << __FUNCTION__ << __LINE__ << "]: " #define JLIBQT_QDEBUG_FILE_LINE_STREAM "[" << __FUNCTION__ << __LINE__ << "]: "
#define JLIBQT_QDEBUG_FILE_LINE_VALUE (QString("[") + __FUNCTION__ + " " + QString::number(__LINE__) + "]: ") #define JLIBQT_QDEBUG_FILE_LINE_VALUE (QString("[") + __FUNCTION__ + " " + QString::number(__LINE__) + "]: ")
#define MYQDEBUG qDebug() << JLIBQT_QDEBUG_FILE_LINE_STREAM #define MYQDEBUG qDebug() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQINFO qInfo() << JLIBQT_QDEBUG_FILE_LINE_STREAM #define MYQINFO qInfo() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQWARN qWarning() << JLIBQT_QDEBUG_FILE_LINE_STREAM #define MYQWARN qWarning() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQCRITICAL qCritical() << JLIBQT_QDEBUG_FILE_LINE_STREAM #define MYQCRITICAL qCritical() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQDEBUG_NOQUOTE qDebug().noquote() << JLIBQT_QDEBUG_FILE_LINE_STREAM #define MYQDEBUG_NOQUOTE qDebug().noquote() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQINFO_NOQUOTE qInfo().noquote() << JLIBQT_QDEBUG_FILE_LINE_STREAM #define MYQINFO_NOQUOTE qInfo().noquote() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQWARN_NOQUOTE qWarning().noquote() << JLIBQT_QDEBUG_FILE_LINE_STREAM #define MYQWARN_NOQUOTE qWarning().noquote() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQCRITICAL_NOQUOTE qCritical().noquote() << JLIBQT_QDEBUG_FILE_LINE_STREAM #define MYQCRITICAL_NOQUOTE qCritical().noquote() << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQDEBUG2 qDebug() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM #define MYQDEBUG2 qDebug() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQINFO2 qInfo() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM #define MYQINFO2 qInfo() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQWARN2 qWarning() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM #define MYQWARN2 qWarning() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQCRITICAL2 qCritical() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM #define MYQCRITICAL2 qCritical() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQDEBUG2_NOQUOTE qDebug().noquote() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM #define MYQDEBUG2_NOQUOTE qDebug().noquote() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQINFO2_NOQUOTE qInfo().noquote() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM #define MYQINFO2_NOQUOTE qInfo().noquote() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQWARN2_NOQUOTE qWarning().noquote() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM #define MYQWARN2_NOQUOTE qWarning().noquote() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
#define MYQCRITICAL2_NOQUOTE qCritical().noquote() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM #define MYQCRITICAL2_NOQUOTE qCritical().noquote() << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") << JLIBQT_QDEBUG_FILE_LINE_STREAM
//! 弹窗报告行号开关 //! 弹窗报告行号开关
// #define JLIBQT_SHOW_LINE 0 // #define JLIBQT_SHOW_LINE 0
//! 当行号大于下方定义的值时,弹窗报告行号,否则忽略。可在多个cpp文件分别定义不同的值。 //! 当行号大于下方定义的值时,弹窗报告行号,否则忽略。可在多个cpp文件分别定义不同的值。
// #define JLIBQT_SHOW_MSGBOX_AFTER_LINE 1 // #define JLIBQT_SHOW_MSGBOX_AFTER_LINE 1
#if JLIBQT_SHOW_LINE #if JLIBQT_SHOW_LINE
#ifdef JLIBQT_SHOW_MSGBOX_AFTER_LINE #ifdef JLIBQT_SHOW_MSGBOX_AFTER_LINE
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER if(__LINE__ >= JLIBQT_SHOW_MSGBOX_AFTER_LINE) { MessageBoxW(nullptr, (std::wstring(__FILEW__) + L":" + std::to_wstring(__LINE__)).data(), L"Test", 0); } #define JLIBQT_SHOW_MSGBOX_LINE_NUMBER if(__LINE__ >= JLIBQT_SHOW_MSGBOX_AFTER_LINE) { MessageBoxW(nullptr, (std::wstring(__FILEW__) + L":" + std::to_wstring(__LINE__)).data(), L"Test", 0); }
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER_WITH_TITLE(title) if(__LINE__ >= JLIBQT_SHOW_MSGBOX_AFTER_LINE) { MessageBoxW(nullptr, (std::wstring(__FILEW__) + L":" + std::to_wstring(__LINE__)).data(), title, 0); } #define JLIBQT_SHOW_MSGBOX_LINE_NUMBER_WITH_TITLE(title) if(__LINE__ >= JLIBQT_SHOW_MSGBOX_AFTER_LINE) { MessageBoxW(nullptr, (std::wstring(__FILEW__) + L":" + std::to_wstring(__LINE__)).data(), title, 0); }
#else #else
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER { MessageBoxW(nullptr, (std::wstring(__FILEW__) + L":" + std::to_wstring(__LINE__)).data(), L"Test", 0); } #define JLIBQT_SHOW_MSGBOX_LINE_NUMBER { MessageBoxW(nullptr, (std::wstring(__FILEW__) + L":" + std::to_wstring(__LINE__)).data(), L"Test", 0); }
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER_WITH_TITLE(title) { MessageBoxW(nullptr, (std::wstring(__FILEW__) + L":" + std::to_wstring(__LINE__)).data(), title, 0); } #define JLIBQT_SHOW_MSGBOX_LINE_NUMBER_WITH_TITLE(title) { MessageBoxW(nullptr, (std::wstring(__FILEW__) + L":" + std::to_wstring(__LINE__)).data(), title, 0); }
#endif #endif
#else #else
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER #define JLIBQT_SHOW_MSGBOX_LINE_NUMBER
#define JLIBQT_SHOW_MSGBOX_LINE_NUMBER_WITH_TITLE(title) #define JLIBQT_SHOW_MSGBOX_LINE_NUMBER_WITH_TITLE(title)
#endif #endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#pragma once #pragma once
#include "../base/config.h" #include "../base/config.h"
#include <ShlObj.h> #include <ShlObj.h>
#include <string> #include <string>
#include <algorithm> #include <algorithm>
namespace jlib { namespace jlib {
namespace win32 { namespace win32 {
inline std::wstring getExePath() { inline std::wstring getExePath() {
wchar_t path[1024] = { 0 }; ::GetModuleFileNameW(nullptr, path, 1024); return path; wchar_t path[1024] = { 0 }; ::GetModuleFileNameW(nullptr, path, 1024); return path;
} }
inline std::string getExePathA() { inline std::string getExePathA() {
char path[1024] = { 0 }; ::GetModuleFileNameA(nullptr, path, 1024); return path; char path[1024] = { 0 }; ::GetModuleFileNameA(nullptr, path, 1024); return path;
} }
inline std::wstring getFolder(const std::wstring& path) { inline std::wstring getFolder(const std::wstring& path) {
auto pos = path.find_last_of(L"\\/"); return pos != path.npos ? path.substr(0, pos) : path; auto pos = path.find_last_of(L"\\/"); return pos != path.npos ? path.substr(0, pos) : path;
} }
inline std::string getFolder(const std::string& path) { inline std::string getFolder(const std::string& path) {
auto pos = path.find_last_of("\\/"); return pos != path.npos ? path.substr(0, pos) : path; auto pos = path.find_last_of("\\/"); return pos != path.npos ? path.substr(0, pos) : path;
} }
inline std::wstring getExeFolderPath() { return getFolder(getExePath()); } inline std::wstring getExeFolderPath() { return getFolder(getExePath()); }
inline std::string getExeFolderPathA() { return getFolder(getExePathA()); } inline std::string getExeFolderPathA() { return getFolder(getExePathA()); }
static constexpr const wchar_t* DEFAULT_PATH_FILTERW = L"\\/:*?\"<>| "; static constexpr const wchar_t* DEFAULT_PATH_FILTERW = L"\\/:*?\"<>| ";
static constexpr const char* DEFAULT_PATH_FILTER = "\\/:*?\"<>| "; static constexpr const char* DEFAULT_PATH_FILTER = "\\/:*?\"<>| ";
inline std::wstring integrateFileName(const std::wstring& name, const std::wstring& filter = DEFAULT_PATH_FILTERW, wchar_t replace_by = L'_') { inline std::wstring integrateFileName(const std::wstring& name, const std::wstring& filter = DEFAULT_PATH_FILTERW, wchar_t replace_by = L'_') {
auto ret = name; for (auto c : filter) { std::replace(ret.begin(), ret.end(), c, replace_by); } return ret; auto ret = name; for (auto c : filter) { std::replace(ret.begin(), ret.end(), c, replace_by); } return ret;
} }
inline std::string integrateFileName(const std::string& name, const std::string& filter = DEFAULT_PATH_FILTER, char replace_by = '_') { inline std::string integrateFileName(const std::string& name, const std::string& filter = DEFAULT_PATH_FILTER, char replace_by = '_') {
auto ret = name; for (auto c : filter) { std::replace(ret.begin(), ret.end(), c, replace_by); } return ret; auto ret = name; for (auto c : filter) { std::replace(ret.begin(), ret.end(), c, replace_by); } return ret;
} }
inline std::wstring getSpecialFolder(int csidl) { inline std::wstring getSpecialFolder(int csidl) {
wchar_t path[MAX_PATH] = { 0 }; wchar_t path[MAX_PATH] = { 0 };
return ::SHGetSpecialFolderPathW(nullptr, path, csidl, false) ? std::wstring(path) : std::wstring(); return ::SHGetSpecialFolderPathW(nullptr, path, csidl, false) ? std::wstring(path) : std::wstring();
} }
inline std::string getSpecialFolderA(int csidl) { inline std::string getSpecialFolderA(int csidl) {
char path[MAX_PATH] = { 0 }; char path[MAX_PATH] = { 0 };
return ::SHGetSpecialFolderPathA(nullptr, path, csidl, false) ? std::string(path) : std::string(); return ::SHGetSpecialFolderPathA(nullptr, path, csidl, false) ? std::string(path) : std::string();
} }
/** /**
* @brief 获取%APPDATA%路径,一般用于存储程序配置文件 * @brief 获取%APPDATA%路径,一般用于存储程序配置文件
* @note 一般xp的结果为: C:\Documents and Setting\[UserName]\Application Data * @note 一般xp的结果为: C:\Documents and Setting\[UserName]\Application Data
* @note 一般vista及以上的结果为:C:\Users\[UserName]\AppData\Roaming * @note 一般vista及以上的结果为:C:\Users\[UserName]\AppData\Roaming
*/ */
inline std::wstring getAppDataPath() { return getSpecialFolder(CSIDL_APPDATA); } inline std::wstring getAppDataPath() { return getSpecialFolder(CSIDL_APPDATA); }
inline std::string getAppDataPathA() { return getSpecialFolderA(CSIDL_APPDATA); } inline std::string getAppDataPathA() { return getSpecialFolderA(CSIDL_APPDATA); }
inline std::wstring getTempPath() { wchar_t path[MAX_PATH] = { 0 }; ::GetTempPathW(MAX_PATH, path); return path; } inline std::wstring getTempPath() { wchar_t path[MAX_PATH] = { 0 }; ::GetTempPathW(MAX_PATH, path); return path; }
inline std::string getTempPathA() { char path[MAX_PATH] = { 0 }; ::GetTempPathA(MAX_PATH, path); return path; } inline std::string getTempPathA() { char path[MAX_PATH] = { 0 }; ::GetTempPathA(MAX_PATH, path); return path; }
inline std::wstring getMyDocumentsPath() { return getSpecialFolder(CSIDL_MYDOCUMENTS); } inline std::wstring getMyDocumentsPath() { return getSpecialFolder(CSIDL_MYDOCUMENTS); }
inline std::string getMyDocumentsPathA() { return getSpecialFolderA(CSIDL_MYDOCUMENTS); } inline std::string getMyDocumentsPathA() { return getSpecialFolderA(CSIDL_MYDOCUMENTS); }
inline std::wstring getTempFileName(const std::wstring& folder, const std::wstring& pre) { inline std::wstring getTempFileName(const std::wstring& folder, const std::wstring& pre) {
wchar_t path[MAX_PATH] = { 0 }; wchar_t path[MAX_PATH] = { 0 };
UINT ret = ::GetTempFileNameW(folder.c_str(), pre.c_str(), 0, path); UINT ret = ::GetTempFileNameW(folder.c_str(), pre.c_str(), 0, path);
if (ret != 0) { return path; } return std::wstring(); if (ret != 0) { return path; } return std::wstring();
} }
inline std::string getTempFileName(const std::string& folder, const std::string& pre) { inline std::string getTempFileName(const std::string& folder, const std::string& pre) {
char path[MAX_PATH] = { 0 }; char path[MAX_PATH] = { 0 };
UINT ret = ::GetTempFileNameA(folder.c_str(), pre.c_str(), 0, path); UINT ret = ::GetTempFileNameA(folder.c_str(), pre.c_str(), 0, path);
if (ret != 0) { return path; } return std::string(); if (ret != 0) { return path; } return std::string();
} }
inline std::wstring getTempFileName(const std::wstring& pre = L"JLIB") { inline std::wstring getTempFileName(const std::wstring& pre = L"JLIB") {
return getTempFileName(getTempPath(), pre); return getTempFileName(getTempPath(), pre);
} }
inline std::string getTempFileNameA(const std::string& pre = "JLIB") { inline std::string getTempFileNameA(const std::string& pre = "JLIB") {
return getTempFileName(getTempPathA(), pre); return getTempFileName(getTempPathA(), pre);
} }
inline bool folderExists(const std::wstring& folderPath) { inline bool folderExists(const std::wstring& folderPath) {
DWORD dwAttrib = ::GetFileAttributesW(folderPath.data()); DWORD dwAttrib = ::GetFileAttributesW(folderPath.data());
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY); return (dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
} }
inline bool folderExists(const std::string& folderPath) { inline bool folderExists(const std::string& folderPath) {
DWORD dwAttrib = ::GetFileAttributesA(folderPath.data()); DWORD dwAttrib = ::GetFileAttributesA(folderPath.data());
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY); return (dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
} }
inline bool fileExists(const std::wstring& filePath) { inline bool fileExists(const std::wstring& filePath) {
DWORD dwAttrib = ::GetFileAttributesW(filePath.data()); DWORD dwAttrib = ::GetFileAttributesW(filePath.data());
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY); return (dwAttrib != INVALID_FILE_ATTRIBUTES) && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
} }
inline bool fileExists(const std::string& filePath) { inline bool fileExists(const std::string& filePath) {
DWORD dwAttrib = ::GetFileAttributesA(filePath.data()); DWORD dwAttrib = ::GetFileAttributesA(filePath.data());
return (dwAttrib != INVALID_FILE_ATTRIBUTES) && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY); return (dwAttrib != INVALID_FILE_ATTRIBUTES) && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
} }
inline bool createDirectory(const std::wstring& path) { inline bool createDirectory(const std::wstring& path) {
return ::CreateDirectoryW(path.data(), nullptr) ? true : false; return ::CreateDirectoryW(path.data(), nullptr) ? true : false;
} }
inline bool createDirectory(const std::string& path) { inline bool createDirectory(const std::string& path) {
return ::CreateDirectoryA(path.data(), nullptr) ? true : false; return ::CreateDirectoryA(path.data(), nullptr) ? true : false;
} }
//! 应用程序典型路径辅助 //! 应用程序典型路径辅助
//struct PathHelper { //struct PathHelper {
// //
// //
//}; //};
} }
} }
This diff is collapsed.
#pragma once #pragma once
#include <Windows.h> #include <Windows.h>
#include <vector> #include <vector>
namespace jlib namespace jlib
{ {
namespace win32 namespace win32
{ {
inline long width(::LPCRECT rc) { inline long width(::LPCRECT rc) {
return rc->right - rc->left; return rc->right - rc->left;
} }
inline long height(::LPCRECT rc) { inline long height(::LPCRECT rc) {
return rc->bottom - rc->top; return rc->bottom - rc->top;
} }
inline void deflateRect(::LPRECT rc, int l, int t, int r, int b) { inline void deflateRect(::LPRECT rc, int l, int t, int r, int b) {
rc->left += l; rc->left += l;
rc->top += t; rc->top += t;
rc->right -= r; rc->right -= r;
rc->bottom -= b; rc->bottom -= b;
} }
inline void inflateRect(::LPRECT rc, int l, int t, int r, int b) { inline void inflateRect(::LPRECT rc, int l, int t, int r, int b) {
rc->left -= l; rc->left -= l;
rc->top -= t; rc->top -= t;
rc->right += r; rc->right += r;
rc->bottom += b; rc->bottom += b;
} }
//! 将矩形平均分割成 n 份,间距 2*gap, n 必须是平方数 x^2, x={1,2,3...} //! 将矩形平均分割成 n 份,间距 2*gap, n 必须是平方数 x^2, x={1,2,3...}
inline std::vector<::RECT> splitRect(::LPCRECT rc, int n, int gap = 50) { inline std::vector<::RECT> splitRect(::LPCRECT rc, int n, int gap = 50) {
std::vector<::RECT> v; std::vector<::RECT> v;
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
v.push_back(*rc); v.push_back(*rc);
} }
double l = sqrt(n); double l = sqrt(n);
int line = int(l); int line = int(l);
int col_step = (int)(width(rc) / line); int col_step = (int)(width(rc) / line);
int row_step = (int)(height(rc) / line); int row_step = (int)(height(rc) / line);
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
v[i].left = rc->left + (i % line) * col_step; v[i].left = rc->left + (i % line) * col_step;
v[i].right = v[i].left + col_step; v[i].right = v[i].left + col_step;
v[i].top = rc->top + (i / line) * row_step; v[i].top = rc->top + (i / line) * row_step;
v[i].bottom = v[i].top + row_step; v[i].bottom = v[i].top + row_step;
deflateRect(&v[i], gap, gap, gap, gap); deflateRect(&v[i], gap, gap, gap, gap);
} }
return v; return v;
}; };
//! 将矩形水平平均分割为 n 份矩形, 当 hgap == -1 时,分割出的矩形与源矩形保持比例 //! 将矩形水平平均分割为 n 份矩形, 当 hgap == -1 时,分割出的矩形与源矩形保持比例
inline std::vector<::RECT> split_rect_horizontal(::LPCRECT rc, int n, int wgap = 50, int hgap = -1) { inline std::vector<::RECT> split_rect_horizontal(::LPCRECT rc, int n, int wgap = 50, int hgap = -1) {
std::vector<::RECT> v; std::vector<::RECT> v;
int w = (width(rc) - (n + 1) * wgap) / n; int w = (width(rc) - (n + 1) * wgap) / n;
if (hgap == -1) { if (hgap == -1) {
double ratio = (rc->right - rc->left) * 1.0 / (rc->bottom - rc->top); double ratio = (rc->right - rc->left) * 1.0 / (rc->bottom - rc->top);
int h = static_cast<int>(w / ratio); int h = static_cast<int>(w / ratio);
hgap = (height(rc) - h) / 2; hgap = (height(rc) - h) / 2;
} }
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
::RECT r = *rc; ::RECT r = *rc;
r.left += i * w + (i + 1) * wgap; r.left += i * w + (i + 1) * wgap;
r.right = r.left + w; r.right = r.left + w;
r.top = rc->top + hgap; r.top = rc->top + hgap;
r.bottom = rc->bottom - hgap; r.bottom = rc->bottom - hgap;
v.push_back(r); v.push_back(r);
} }
return v; return v;
} }
/** /**
* @brief 从矩形内获取六边形顶点 * @brief 从矩形内获取六边形顶点
* @param rc 矩形 * @param rc 矩形
* @param spliter 六边形的边长是矩形边长的 1/spliter * @param spliter 六边形的边长是矩形边长的 1/spliter
* @note rc's width / spliter = (rc's width - hexagon's side length) / 2 * @note rc's width / spliter = (rc's width - hexagon's side length) / 2
* @return 六边形的六个顶点坐标,从上边左侧点顺时针排列 * @return 六边形的六个顶点坐标,从上边左侧点顺时针排列
*/ */
inline std::vector<::POINT> getHexagonVertexesFromRect(::LPCRECT rc, float spliter = 3.0) { inline std::vector<::POINT> getHexagonVertexesFromRect(::LPCRECT rc, float spliter = 3.0) {
if (!rc) { return std::vector<::POINT>(); } if (!rc) { return std::vector<::POINT>(); }
if (spliter == 0.0) { spliter = 3.0; } if (spliter == 0.0) { spliter = 3.0; }
std::vector<::POINT> v; std::vector<::POINT> v;
auto w = rc->right - rc->left; auto w = rc->right - rc->left;
auto h = rc->bottom - rc->top; auto h = rc->bottom - rc->top;
auto ww = static_cast<int>(w / spliter); auto ww = static_cast<int>(w / spliter);
auto hh = static_cast<int>(h / spliter); auto hh = static_cast<int>(h / spliter);
::POINT pt; ::POINT pt;
pt.x = rc->left; pt.x = rc->left;
pt.y = rc->top + hh; pt.y = rc->top + hh;
v.push_back(pt); v.push_back(pt);
pt.x = rc->left + ww; pt.x = rc->left + ww;
pt.y = rc->top; pt.y = rc->top;
v.push_back(pt); v.push_back(pt);
pt.x = rc->right - ww; pt.x = rc->right - ww;
v.push_back(pt); v.push_back(pt);
pt.x = rc->right; pt.x = rc->right;
pt.y = rc->top + hh; pt.y = rc->top + hh;
v.push_back(pt); v.push_back(pt);
pt.y = rc->bottom - hh; pt.y = rc->bottom - hh;
v.push_back(pt); v.push_back(pt);
pt.x = rc->right - ww; pt.x = rc->right - ww;
pt.y = rc->bottom; pt.y = rc->bottom;
v.push_back(pt); v.push_back(pt);
pt.x = rc->left + ww; pt.x = rc->left + ww;
v.push_back(pt); v.push_back(pt);
pt.x = rc->left; pt.x = rc->left;
pt.y = rc->bottom - hh; pt.y = rc->bottom - hh;
v.push_back(pt); v.push_back(pt);
return v; return v;
} }
} }
} }
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