Skip to content

Commit b66fd7e

Browse files
Merge pull request #51 from Reim-developer/dev
Implement `AbstractTableModel` & `ThemeManager` class
2 parents 960de83 + 706b14f commit b66fd7e

17 files changed

Lines changed: 464 additions & 102 deletions

.github/workflows/linux.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ jobs:
2525
chmod +x ${{ github.workspace }}/${{ env.CI_SCRIPT }}
2626
./${{ env.CI_SCRIPT }} install-dependency
2727
28+
- name: Install Qt
29+
uses: jurplel/install-qt-action@v4
30+
2831
- name: Install Rust
2932
shell: bash
3033
run: |

.github/workflows/linux_dev.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,16 @@ jobs:
2626
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
2727
echo "$HOME/.cargo/bin:$PATH" >> $GITHUB_PATH
2828
29-
- name: Install C++ libraries
29+
- name: Install requirements
3030
shell: bash
3131
run: |
3232
sudo apt-get update
3333
sudo apt-get install -y \
3434
git cmake make ccache \
35-
qt6-base-dev clang
35+
clang
3636
37+
- name: Install Qt
38+
uses: jurplel/install-qt-action@v4
3739

3840
- name: Add Rust components
3941
shell: bash

scripts/linux_deploy.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ nproc=$(nproc)
88
install_dependency() {
99
sudo apt-get update
1010
sudo apt-get install -y git cmake \
11-
qt6-base-dev clang
11+
clang
1212
}
1313

1414
function check() {

src/back_end/src/internal/app_config.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ pub struct AppGuiSettings {
1212
pub foreground_color: String,
1313
pub background_button_color: String,
1414
pub foreground_button_color: String,
15+
pub background_table_header_color: String,
16+
pub foreground_table_header_color: String,
1517
}
1618

1719
#[derive(Deserialize, Serialize)]
@@ -32,6 +34,8 @@ impl AppConfig {
3234
foreground_color: "#ffffff".to_string(),
3335
background_button_color: "#2f3136".to_string(),
3436
foreground_button_color: "#ffffff".to_string(),
37+
background_table_header_color: "#2f3136".to_string(),
38+
foreground_table_header_color: "#ffffff".to_string(),
3539
};
3640

3741
Self {

src/back_end/src/raw_config/constant.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@ pub const BACKGROUND_COLOR: &str = "background_color";
1313
pub const FOREGROUND_COLOR: &str = "foreground_color";
1414
pub const BACKGROUND_COLOR_BUTTON: &str = "background_button_color";
1515
pub const FOREGROUND_COLOR_BUTTON: &str = "fore_background_color";
16+
pub const BACKGROUND_COLOR_TABLE_HEADER: &str = "background_table_header_color";
17+
pub const FOREGROUND_COLOR_TABLE_HEADER: &str = "foreground_table_header_color";
1618

1719
/* Default application color fallback */
1820
pub const FALLBACK_BG_COLOR: &str = "#2f3136";
1921
pub const FALLBACK_FG_COLOR: &str = "#ffffff";
2022
pub const FALLBACK_BG_BUTTON_COLOR: &str = "#2f3136";
2123
pub const FALLBACK_FG_BUTTON_COLOR: &str = "#ffffff";
24+
pub const FALLBACK_BG_TABLE_HEADER_COLOR: &str = "#2f3136";
25+
pub const FALLBACK_FG_TABLE_HEADER_COLOR: &str = "#ffffff";

src/back_end/src/raw_config/raw_toml.rs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use crate::raw_config::constant::{
22
APP_GUI_SETTINGS, APP_SETTINGS, BACKGROUND_COLOR, BACKGROUND_COLOR_BUTTON,
3-
FALLBACK_BG_BUTTON_COLOR, FALLBACK_BG_COLOR, FALLBACK_FG_BUTTON_COLOR,
4-
FALLBACK_FG_COLOR, FOREGROUND_COLOR, FOREGROUND_COLOR_BUTTON,
5-
HIDE_WHEN_CLOSED, HIDE_WHEN_CLOSED_FALLBACK, NOTIFICATION,
6-
NOTIFICATION_FALLBACK,
3+
BACKGROUND_COLOR_TABLE_HEADER, FALLBACK_BG_BUTTON_COLOR, FALLBACK_BG_COLOR,
4+
FALLBACK_BG_TABLE_HEADER_COLOR, FALLBACK_FG_BUTTON_COLOR,
5+
FALLBACK_FG_COLOR, FALLBACK_FG_TABLE_HEADER_COLOR, FOREGROUND_COLOR,
6+
FOREGROUND_COLOR_BUTTON, FOREGROUND_COLOR_TABLE_HEADER, HIDE_WHEN_CLOSED,
7+
HIDE_WHEN_CLOSED_FALLBACK, NOTIFICATION, NOTIFICATION_FALLBACK,
78
};
89
use std::{
910
ffi::{CStr, CString, c_char},
@@ -23,6 +24,8 @@ pub struct RawAppGuiSettings {
2324
pub foreground_color: *mut c_char,
2425
pub background_button_color: *mut c_char,
2526
pub foreground_button_color: *mut c_char,
27+
pub background_header_table_color: *mut c_char,
28+
pub foreground_header_table_color: *mut c_char,
2629
}
2730

2831
#[repr(C)]
@@ -109,6 +112,16 @@ pub unsafe extern "C" fn raw_exists_config(
109112
FOREGROUND_COLOR_BUTTON,
110113
FALLBACK_FG_BUTTON_COLOR,
111114
);
115+
let bg_table_header_color = color_by_settings(
116+
&toml_value,
117+
BACKGROUND_COLOR_TABLE_HEADER,
118+
FALLBACK_BG_TABLE_HEADER_COLOR,
119+
);
120+
let fg_table_header_color = color_by_settings(
121+
&toml_value,
122+
FOREGROUND_COLOR_TABLE_HEADER,
123+
FALLBACK_FG_TABLE_HEADER_COLOR,
124+
);
112125

113126
let Ok(bg_cstr) = CString::new(bg_color) else {
114127
return Status::ConvertToCStringFailed;
@@ -126,6 +139,14 @@ pub unsafe extern "C" fn raw_exists_config(
126139
return Status::ConvertToCStringFailed;
127140
};
128141

142+
let Ok(bg_table_header_cstr) = CString::new(bg_table_header_color) else {
143+
return Status::ConvertToCStringFailed;
144+
};
145+
146+
let Ok(fg_table_header_cstr) = CString::new(fg_table_header_color) else {
147+
return Status::ConvertToCStringFailed;
148+
};
149+
129150
if let Some(config) = unsafe { raw_cfg_out.as_mut() } {
130151
config.app_settings.hide_when_closed = app_settings.hide_when_closed;
131152
config.app_settings.notification = app_settings.notification;
@@ -135,6 +156,10 @@ pub unsafe extern "C" fn raw_exists_config(
135156
bg_btn_cstr.into_raw();
136157
config.app_gui_settings.foreground_button_color =
137158
fg_btn_cstr.into_raw();
159+
config.app_gui_settings.background_header_table_color =
160+
bg_table_header_cstr.into_raw();
161+
config.app_gui_settings.foreground_header_table_color =
162+
fg_table_header_cstr.into_raw();
138163

139164
return RawReadAppConfigStatus::Ok;
140165
}
@@ -154,6 +179,12 @@ pub unsafe extern "C" fn raw_free_cstr_app_config(config: *mut RawAppConfig) {
154179
CString::from_raw(cfg.app_gui_settings.background_button_color);
155180
let _ =
156181
CString::from_raw(cfg.app_gui_settings.foreground_button_color);
182+
let _ = CString::from_raw(
183+
cfg.app_gui_settings.background_header_table_color,
184+
);
185+
let _ = CString::from_raw(
186+
cfg.app_gui_settings.foreground_header_table_color,
187+
);
157188
}
158189
}
159190
}

src/ffi/raw/config.hxx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ typedef struct {
4141
char *foreground_color;
4242
char *background_button_color;
4343
char *foreground_button_color;
44+
char *background_table_header_color;
45+
char *foreground_table_header_color;
4446
} RawAppGuiSettings;
4547

4648
typedef struct {
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
#ifndef ABSTRACT_TABLE_MODEL_HXX
2+
#define ABSTRACT_TABLE_MODEL_HXX
3+
4+
#include <qabstractitemmodel.h>
5+
#include <qcontainerfwd.h>
6+
#include <qlist.h>
7+
#include <qnamespace.h>
8+
#include <qtmetamacros.h>
9+
#include <qtypes.h>
10+
#include <qvariant.h>
11+
12+
#include <algorithm>
13+
#include <climits>
14+
#include <cstdint>
15+
16+
using std::min;
17+
using std::uint8_t;
18+
namespace Lazyboard::front_end {
19+
20+
typedef struct TableItem {
21+
QString time;
22+
QString content;
23+
QString content_type;
24+
bool is_pinned = false;
25+
} TableItem;
26+
27+
template <typename T>
28+
constexpr void unused(T &t) {
29+
(void)t;
30+
}
31+
32+
class AbstractTableModel : public QAbstractTableModel {
33+
Q_OBJECT
34+
35+
public:
36+
// clang-format off
37+
enum Colum : uint8_t {
38+
TIME = 0,
39+
CONTENT = 1,
40+
TYPE = 2,
41+
PINNED,
42+
COLUMN_COUNT,
43+
}; // clang-format on
44+
45+
int rowCount(const QModelIndex &parent = QModelIndex()) const override {
46+
unused(parent);
47+
return static_cast<int>(min(table_item.size(), qsizetype(INT_MAX)));
48+
}
49+
50+
int columnCount(const QModelIndex &parent = QModelIndex()) const override {
51+
unused(parent);
52+
return COLUMN_COUNT;
53+
}
54+
55+
QVariant data(const QModelIndex &index,
56+
int role = Qt::DisplayRole) const override {
57+
if (!index.isValid() || index.row() >= table_item.size() ||
58+
index.row() < 0) {
59+
return QVariant();
60+
}
61+
62+
const TableItem &item = table_item[index.row()];
63+
64+
if (role == Qt::DisplayRole || role == Qt::EditRole) {
65+
switch (index.column()) {
66+
case TIME:
67+
return item.time;
68+
69+
case CONTENT: {
70+
const auto max_length = 20;
71+
if (item.content.length() > max_length) {
72+
auto content_length = item.content.length();
73+
74+
qsizetype remaining_length =
75+
content_length - max_length;
76+
77+
QString truncated =
78+
item.content.left(max_length) +
79+
QString(" and %1 more...").arg(remaining_length);
80+
81+
return truncated;
82+
}
83+
84+
return item.content;
85+
}
86+
87+
case TYPE | PINNED:
88+
return item.content_type;
89+
90+
default:
91+
return {};
92+
}
93+
}
94+
95+
if (role == Qt::CheckStateRole && index.column() == PINNED) {
96+
return item.is_pinned ? Qt::Checked : Qt::Unchecked;
97+
}
98+
99+
return QVariant();
100+
}
101+
102+
QVariant headerData(int section, Qt::Orientation orientation,
103+
int role = Qt::DisplayRole) const override {
104+
if (role != Qt::DisplayRole || orientation != Qt::Horizontal) {
105+
return QVariant();
106+
}
107+
108+
switch (section) {
109+
case TIME:
110+
return "Time";
111+
112+
case CONTENT:
113+
return "Content";
114+
115+
case TYPE:
116+
return "Type";
117+
118+
case PINNED:
119+
return "Pinned";
120+
121+
default:
122+
return QVariant();
123+
}
124+
}
125+
126+
Qt::ItemFlags flags(const QModelIndex &index) const override {
127+
if (!index.isValid()) {
128+
return Qt::NoItemFlags;
129+
}
130+
131+
Qt::ItemFlags flag = QAbstractTableModel::flags(index);
132+
133+
if (index.column() == PINNED) {
134+
flag |= Qt::ItemFlag::ItemIsUserCheckable |
135+
Qt::ItemFlag::ItemIsEditable;
136+
} else {
137+
flag |= Qt::ItemIsEditable;
138+
}
139+
140+
return flag;
141+
}
142+
143+
bool setData(const QModelIndex &index, const QVariant &value,
144+
int role) override {
145+
if (!index.isValid() || index.row() >= table_item.size()) {
146+
return false;
147+
}
148+
149+
TableItem &item = table_item[index.row()];
150+
151+
if (index.column() == PINNED && role == Qt::CheckStateRole) {
152+
bool checked = (value.toInt() == Qt::Checked);
153+
154+
if (item.is_pinned != checked) {
155+
item.is_pinned = checked;
156+
157+
emit dataChanged(index, index,
158+
{Qt::CheckStateRole, Qt::DisplayRole});
159+
160+
return true;
161+
}
162+
}
163+
164+
if (role == Qt::EditRole) {
165+
switch (index.column()) {
166+
case TIME:
167+
item.time = value.toString();
168+
break;
169+
170+
case CONTENT:
171+
item.content = value.toString();
172+
break;
173+
174+
case TYPE:
175+
item.content_type = value.toString();
176+
break;
177+
178+
default:
179+
return false;
180+
}
181+
182+
emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole});
183+
return true;
184+
}
185+
186+
return false;
187+
}
188+
189+
private:
190+
QList<TableItem> table_item;
191+
};
192+
} // namespace Lazyboard::front_end
193+
194+
#endif // ABSTRACT_TABLE_MODEL_HXX
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#ifndef ERROR_DEBUG_HXX
2+
#define ERROR_DEBUG_HXX
3+
4+
#if !defined(LAZY_DEBUG)
5+
#error "Could not include 'error_debug' if 'LAZY_DEBUG' is disabled.
6+
#endif
7+
#include <cstdint>
8+
#include <map>
9+
#include <string_view>
10+
11+
namespace Lazyboard::front_end {
12+
using std::map;
13+
using std::string_view;
14+
using std::uint8_t;
15+
16+
// clang-format off
17+
enum class ErrorDebugType : uint8_t{
18+
INVALID_HEX_COLOR = 1,
19+
}; // clang-format on
20+
21+
inline const map<ErrorDebugType, string_view> &error_type() {
22+
static const map<ErrorDebugType, string_view> error_type = {
23+
{ErrorDebugType::INVALID_HEX_COLOR, "INVALID_HEX_COLOR"},
24+
};
25+
26+
return error_type;
27+
}
28+
29+
} // namespace Lazyboard::front_end
30+
#endif // ERROR_DEBUG_HXX

0 commit comments

Comments
 (0)