Merge pull request #252 from uowuo/theming

Use GTK themes
This commit is contained in:
ouwou 2023-12-26 07:14:43 +00:00 committed by GitHub
commit ffc29b8214
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 297 additions and 735 deletions

View File

@ -29,6 +29,7 @@ jobs:
if_true: >-
git
make
unzip
mingw-w64-x86_64-toolchain
mingw-w64-x86_64-cmake
mingw-w64-x86_64-ninja
@ -41,6 +42,7 @@ jobs:
if_false: >-
git
make
unzip
mingw-w64-x86_64-toolchain
mingw-w64-x86_64-cmake
mingw-w64-x86_64-ninja
@ -95,6 +97,11 @@ jobs:
mkdir -p 16x16/devices 24x24/devices 32x32/devices 48x48/devices 64x64/devices 96x96/devices scalable/devices
mkdir -p 16x16/status 24x24/status 32x32/status 48x48/status 64x64/status 96x96/status scalable/status
cd ${GITHUB_WORKSPACE}
wget https://github.com/rtlewis1/GTK/archive/refs/heads/Material-Black-Colors-Desktop.zip
unzip Material-Black-Colors-Desktop.zip 'GTK-Material-Black-Colors-Desktop/Material-Black-Cherry/**/*'
mkdir -p ${artifact_dir}/share/themes
mv ./GTK-Material-Black-Colors-Desktop/Material-Black-Cherry ${artifact_dir}/share/themes/Material-Black-Cherry
cp -r ci/tree/. ${artifact_dir}
cp ci/gtk-for-windows/gtk-nsis-pack/share/icons/Adwaita/index.theme ${artifact_dir}/share/icons/Adwaita/index.theme
cat "ci/used-icons.txt" | sed 's/\r$//' | xargs -I % cp ci/gtk-for-windows/gtk-nsis-pack/share/icons/Adwaita/16x16/%.symbolic.png ${artifact_dir}/share/icons/Adwaita/16x16/%.symbolic.png || :
cat "ci/used-icons.txt" | sed 's/\r$//' | xargs -I % cp ci/gtk-for-windows/gtk-nsis-pack/share/icons/Adwaita/24x24/%.symbolic.png ${artifact_dir}/share/icons/Adwaita/24x24/%.symbolic.png || :

BIN
.readme/s5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 273 KiB

BIN
.readme/s6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

BIN
.readme/s7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 KiB

BIN
.readme/s8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 346 KiB

View File

@ -2,7 +2,16 @@
---
Alternative Discord client made in C++ with GTK
<img src="/.readme/s3.png">
<table>
<tr>
<td><img src="/.readme/s5.png"></td>
<td><img src="/.readme/s6.png"></td>
</tr>
<tr>
<td><img src="/.readme/s7.png"></td>
<td><img src="/.readme/s8.png"></td>
</tr>
</table>
<a href="https://discord.gg/wkCU3vuzG5"><img src="https://discord.com/api/guilds/858156817711890443/widget.png?style=shield"></a>
@ -11,7 +20,7 @@ Current features:
* Not Electron
* Voice support
* Handles most types of chat messages including embeds, images, and replies
* Completely styleable/customizable with CSS (if you have a system GTK theme it won't really use it though)
* Completely styleable/customizable
* Identifies to Discord as the web client unlike other clients so less likely to be falsely flagged as spam<sup>1</sup>
* Set status
* Unread and mention indicators
@ -301,10 +310,8 @@ For example, memory_db would be set by adding `memory_db = true` under the line
| Setting | Type | Description |
|-------------------------|--------|-----------------------------------------------------|
| `linkcolor` | string | color to use for links in messages |
| `expandercolor` | string | color to use for the expander in the channel list |
| `nsfwchannelcolor` | string | color to use for NSFW channels in the channel list |
| `channelcolor` | string | color to use for SFW channels in the channel list |
| `mentionbadgecolor` | string | background color for mention badges |
| `mentionbadgetextcolor` | string | color to use for number displayed on mention badges |
| `unreadcolor` | string | color to use for the unread indicator |

View File

@ -38,6 +38,7 @@
/bin/libidn2-0.dll
/bin/libintl-8.dll
/bin/libjpeg-8.dll
/bin/liblzma-5.dll
/bin/libnghttp2-14.dll
/bin/libopus-0.dll
/bin/libpango-1.0-0.dll
@ -49,6 +50,7 @@
/bin/libpixman-1-0.dll
/bin/libpng16-16.dll
/bin/libpsl-5.dll
/bin/librsvg-2-2.dll
/bin/libsigc-2.0-0.dll
/bin/libsodium-26.dll
/bin/libspdlog.dll
@ -59,6 +61,7 @@
/bin/libthai-0.dll
/bin/libunistring-5.dll
/bin/libwinpthread-1.dll
/bin/libxml2-2.dll
/bin/libzstd.dll
/bin/zlib1.dll
/../usr/bin/msys-2.0.dll

View File

@ -0,0 +1,2 @@
[Settings]
gtk-theme-name=Material-Black-Cherry

View File

@ -1,97 +0,0 @@
/*
application wide stuff
has to be separate to allow main.css to override certain things
*/
.app-window label:not(:disabled) {
color: @text_color;
}
.app-window entry {
background: @secondary_color;
color: @text_color;
border: 1px solid #1c2e40;
}
.app-window button {
background: @secondary_color;
color: @text_color;
text-shadow: none;
box-shadow: none;
}
.app-window button:checked {
border-top: 0px;
border-left: 0px;
border-right: 0px;
border-bottom: 3px solid #39a2ed;
color: #ffffff;
}
.app-window button:not(:checked) {
border: 3px #0000ff;
}
.app-window.background {
background: @background_color;
}
.app-window treeview {
color: @text_color;
}
.app-window treeview:not(:selected) {
background: @secondary_color;
}
.app-window list, .app-popup list {
background: @secondary_color;
}
.app-window paned separator {
background: @background_color;
}
.app-window scrollbar {
background: @background_color;
border-left: 1px solid transparent;
}
.app-window menubar, menu {
background: @background_color;
color: #cccccc;
}
.app-window textview text {
caret-color: #ababab;
}
.app-window check,
.app-window radio {
background-clip: padding-box;
background: @secondary_color;
border-color: #070707;
box-shadow: 0 1px rgba(0, 0, 0, 0);
color: #dddddd;
}
.app-window check:checked,
.app-window radio:checked {
background-clip: border-box;
background: #0b4285;
border-color: #092444;
box-shadow: 0 1px rgba(0, 0, 0, 0);
color: #dddddd;
}
.app-window colorswatch {
box-shadow: 0 1px rgba(0, 0, 0, 0);
}
.app-window scale {
padding-top: 0px;
padding-bottom: 0px;
margin-top: 0px;
margin-bottom: 0px;
color: @text_color;
}

View File

@ -1,35 +0,0 @@
.embed {
border-radius: 5px;
padding: 10px;
}
.embed-footer {
margin-top: 5px;
font-size: 11px;
}
.embed-author {
margin-bottom: 10px;
font-size: 12px;
}
.message-attachment-box {
border: 1px solid #aaaaaa;
padding: 2px 5px 2px 5px;
}
.status-indicator.dnd {
color: #982929;
}
.status-indicator.online {
color: #43B581;
}
.status-indicator.offline {
color: #808080;
}
.status-indicator.idle {
color: #FAA61A;
}

View File

@ -1,12 +1,7 @@
@define-color background_color #141414;
@define-color secondary_color #111111;
@define-color text_color #fbfbfb;
.embed {
background-color: rgba(0, 0, 0, 0.2);
color: #cbcbcb;
border-radius: 5px;
padding: 10px;
background-color: rgba(0.0, 0.0, 0.0, 0.1);
}
.embed-footer {
@ -19,140 +14,7 @@
font-size: 12px;
}
.channel-list {
background-color: @secondary_color;
}
.channel-row-label {
padding: 5px;
}
.channel-row-label, .channel-row-label text {
color: @text_color;
background: rgba(0, 0, 0, 0);
}
.channel-row-label.nsfw text {
color: #ed6666;
}
.channel-row:focus {
background-color: #34495e;
}
.channel-row-category {
padding-left: 15px;
color: #ff5370;
}
.channel-row-channel {
padding-left: 30px;
}
.messages, .message-container {
background-color: @background_color;
}
.messages {
padding: 15px;
}
.message-container-extra {
color: #78909c;
}
.message-container-timestamp {
color: #78909c;
}
.message-text {
/* this isnt stricly necessary but it fixes emoji clipping */
padding-bottom: 5px;
}
.message-text:not(.failed) text, .message-reply {
color: @text_color;
}
.message-text.pending text {
color: shade(@text_color, 0.5);
}
.message-text.failed text {
color: #b72d4f;
}
.message-reply {
border-left: 2px solid gray;
padding-left: 20px;
padding-top: 6px;
padding-bottom: 6px;
opacity: 0.7;
}
.message-text + .message-text {
padding-top: 5px;
}
.message-text text {
background-color: @background_color;
}
.message-input, .message-input textview, .message-input textview text {
background-color: #242424;
color: #adadad;
border-radius: 3px;
border: 1px solid transparent;
}
.message-input {
border: 1px solid #444444;
margin-right: 15px;
}
.message-input.replying {
border: 1px solid #026FB9;
}
.message-input.editing {
border: 1px solid #b9026f;
}
.message-input.bad-input {
border: 1px solid #dd3300;
}
.message-input-browse-icon {
color: #b9bbbe;
margin-left: 5px;
margin-top: 11px;
}
/* i dont think theres a way to circumvent having to do this to adjust around the browse icon */
.message-input:not(.with-browser-icon) {
padding: 0px 0px 0px 5px;
}
.message-input.with-browse-icon {
padding: 0px 0px 0px 30px;
}
.members {
background-color: @background_color;
}
.members-row-label {
color: @text_color;
padding: 5px;
}
.members-row-member {
padding: 0;
padding-left: 15px;
}
.message-attachment-box {
color: #aaaaaa;
border: 1px solid #aaaaaa;
padding: 2px 5px 2px 5px;
}
@ -161,61 +23,6 @@
margin: 5px;
}
.message-component {
margin: 5px;
}
.message-component.primary {
background: #5865F2;
}
.message-component.secondary, .message-component.link {
background: #4F545C;
}
.message-component.success {
background: #43B581;
}
.message-component.danger {
background: #F04747;
}
.reaction-box {
padding: 2px 5px 2px 5px;
margin: 0px 0px 0px 0px;
background-color: rgba(0.4, 0.4, 0.4, 0.4);
border-radius: 5px;
border: 1px solid transparent;
}
.reaction-box.reacted {
border: 1px solid white;
}
.reaction-count {
color: @text_color;
}
.completer {
background-color: @secondary_color;
padding: 5px;
}
.completer-entry {
color: @text_color;
}
.completer-entry-image {
margin-right: 6px;
}
.typing-indicator {
margin-top: 10px;
margin-bottom: -7px;
color: @text_color;
}
.status-indicator.dnd {
color: #982929;
}
@ -232,6 +39,26 @@
color: #FAA61A;
}
.message-input textview, .message-input textview text {
background-color: inherit;
}
.message-text, .message-text text {
background: inherit;
}
.message-input textview {
padding: 10px 5px;
}
.message-reply {
border-left: 2px solid gray;
padding-left: 10px;
padding-top: 6px;
padding-bottom: 6px;
opacity: 0.8;
}
.profile-main-container {
padding: 20px;
}
@ -242,31 +69,13 @@
}
.profile-username-nondisplay {
margin-left: 10px;
}
.profile-badge {
margin-right: 10px;
margin-left: 10px;
}
.profile-switcher {
padding-top: 5px;
}
.profile-connections {
margin-top: 10px;
}
.profile-connection {
background: @secondary_color;
border-radius: 15px;
margin-right: 20px;
}
.profile-connection box {
padding: 5px;
}
.profile-stack {
padding-top: 5px;
}
@ -276,126 +85,63 @@
padding-bottom: 5px;
}
.profile-notes-text, .profile-notes-text text {
background: @secondary_color;
}
.profile-notes-text text {
border-radius: 5px;
border: 1px solid #36515e;
color: @text_color;
padding-bottom: 5px;
}
.profile-badges {
padding-left: 5px;
}
.guild-members-pane-info {
padding: 10px;
.profile-badge {
margin-right: 5px;
}
.drag-hover-top {
background: linear-gradient(to bottom, rgba(255, 66, 66, 0.65) 0%, rgba(0, 0, 0, 0) 35%);
}
.drag-hover-bottom {
background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 65%, rgba(255, 66, 66, 0.65) 100%);
}
.friends-list list {
background: @background_color;
padding-left: 10px;
}
.friends-list-row-bot {
color: #ff0000;
}
.channel-tab-switcher .box {
margin: -7px -1px -7px -1px;
background: #2a2a2a;
border: 1px solid black;
}
.channel-tab-switcher tab:hover {
box-shadow: inset 0 -6px #17633e;
}
.channel-tab-switcher tab:checked {
box-shadow: inset 0 -6px #2feb90;
}
.channel-tab-switcher tab {
background: #1A1A1A;
border: 1px solid #808080;
min-height: 35px;
}
.channel-tab-switcher tab.needs-attention:not(:checked) {
font-weight: bold;
animation: 150ms ease-in;
/* background-image: radial-gradient(ellipse at bottom, #FF5370, #1A1A1A 30%); */
box-shadow: inset 0 -6px red;
}
.channel-tab-switcher tab > button {
border: none;
padding: 0;
margin: 5px;
min-width: 16px;
min-height: 16px;
color: #FF5370;
background-color: rgba(0.21, 0.21, 0.21, 0.5);
}
.channel-tab-switcher tab > button:hover {
background-color: alpha(#ff0000, 0.5);
}
.message-progress {
border: none;
margin-bottom: -8px;
}
.message-progress trough {
border: none;
background-color: transparent;
}
.message-progress progress {
border: none;
background-color: #dd3300;
margin-left: 1px;
}
.voice-info {
background-color: #0B0B0B;
padding: 5px;
border: 1px solid #202020;
}
.voice-info-disconnect-image {
color: #DDDDDD;
}
.voice-info-status {
font-weight: bold;
}
.voice-info-location {
}
.voice-state-server {
color: red;
}
spinbutton {
color: @text_color;
.profile-connections {
margin-top: 10px;
}
.emoji-picker, .emoji-picker stack box {
background-color: @background_color;
.profile-connection {
padding: 5px;
border-radius: 10px;
border: 1px solid @theme_fg_color;
}
.profile-connection-image {
padding-right: 5px;
}
.reaction-box {
padding: 2px 5px 2px 5px;
border-radius: 5px;
border: 1px solid @theme_fg_color;
}
.reaction-box.reacted {
border: 1px solid #5865f2;
background-color: alpha(@theme_selected_bg_color, 0.5);
}
.set-status-dialog .dialog-vbox {
padding: 5px;
}
.set-status-dialog .dialog-action-area {
margin: 10px 5px 5px 5px;
}
.voice-settings-window > box {
padding: 5px;
}
.voice-settings-window scale {
margin-right: 8px;
}
.message-input scrollbar.vertical slider {
min-height: 0px;
}
.message-text.pending {
color: alpha(currentColor, 0.5);
}
.message-text.failed {
color: red;
}

View File

@ -192,13 +192,6 @@ int Abaddon::StartGTK() {
dlg.run();
});
m_css_low_provider = Gtk::CssProvider::create();
m_css_low_provider->signal_parsing_error().connect([](const Glib::RefPtr<const Gtk::CssSection> &section, const Glib::Error &error) {
Gtk::MessageDialog dlg("low-priority css failed parsing (" + error.what() + ")", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
dlg.set_position(Gtk::WIN_POS_CENTER);
dlg.run();
});
#ifdef _WIN32
bool png_found = false;
bool gif_found = false;
@ -1086,10 +1079,6 @@ void Abaddon::ActionReloadCSS() {
Gtk::StyleContext::remove_provider_for_screen(Gdk::Screen::get_default(), m_css_provider);
m_css_provider->load_from_path(GetCSSPath("/" + GetSettings().MainCSS));
Gtk::StyleContext::add_provider_for_screen(Gdk::Screen::get_default(), m_css_provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
Gtk::StyleContext::remove_provider_for_screen(Gdk::Screen::get_default(), m_css_low_provider);
m_css_low_provider->load_from_path(GetCSSPath("/application-low-priority.css"));
Gtk::StyleContext::add_provider_for_screen(Gdk::Screen::get_default(), m_css_low_provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION - 1);
} catch (Glib::Error &e) {
Gtk::MessageDialog dlg(*m_main_window, "css failed to load (" + e.what() + ")", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
dlg.set_position(Gtk::WIN_POS_CENTER);

View File

@ -182,7 +182,6 @@ private:
mutable std::mutex m_mutex;
Glib::RefPtr<Gtk::Application> m_gtk_app;
Glib::RefPtr<Gtk::CssProvider> m_css_provider;
Glib::RefPtr<Gtk::CssProvider> m_css_low_provider; // registered with a lower priority to allow better customization
Glib::RefPtr<Gtk::StatusIcon> m_tray;
std::unique_ptr<MainWindow> m_main_window; // wah wah cant create a gtkstylecontext fuck you

View File

@ -7,6 +7,49 @@ constexpr static double M_PI = 3.14159265358979;
constexpr static double M_PI_H = M_PI / 2.0;
constexpr static double M_PI_3_2 = M_PI * 3.0 / 2.0;
void AddUnreadIndicator(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area) {
static const auto color_setting = Gdk::RGBA(Abaddon::Get().GetSettings().UnreadIndicatorColor);
const auto color = color_setting.get_alpha_u() > 0 ? color_setting : widget.get_style_context()->get_background_color(Gtk::STATE_FLAG_SELECTED);
cr->set_source_rgb(color.get_red(), color.get_green(), color.get_blue());
const auto x = background_area.get_x();
const auto y = background_area.get_y();
const auto w = background_area.get_width();
const auto h = background_area.get_height();
cr->rectangle(x, y, 3, h);
cr->fill();
}
void RenderExpander(int x_offset, const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, bool is_expanded) {
constexpr static int len = 5;
int x1, y1, x2, y2, x3, y3;
if (is_expanded) {
x1 = background_area.get_x() + x_offset;
y1 = background_area.get_y() + background_area.get_height() / 2 - len;
x2 = background_area.get_x() + x_offset + len;
y2 = background_area.get_y() + background_area.get_height() / 2 + len;
x3 = background_area.get_x() + x_offset + len * 2;
y3 = background_area.get_y() + background_area.get_height() / 2 - len;
} else {
x1 = background_area.get_x() + x_offset;
y1 = background_area.get_y() + background_area.get_height() / 2 - len;
x2 = background_area.get_x() + x_offset + len * 2;
y2 = background_area.get_y() + background_area.get_height() / 2;
x3 = background_area.get_x() + x_offset;
y3 = background_area.get_y() + background_area.get_height() / 2 + len;
}
cr->move_to(x1, y1);
cr->line_to(x2, y2);
cr->line_to(x3, y3);
auto expander_color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelsExpanderColor);
if (expander_color.get_alpha_u() == 0) {
expander_color = widget.get_style_context()->get_background_color(Gtk::STATE_FLAG_SELECTED);
}
cr->set_source_rgb(expander_color.get_red(), expander_color.get_green(), expander_color.get_blue());
cr->stroke();
}
CellRendererChannels::CellRendererChannels()
: Glib::ObjectBase(typeid(CellRendererChannels))
, Gtk::CellRenderer()
@ -207,30 +250,7 @@ void CellRendererChannels::get_preferred_height_for_width_vfunc_folder(Gtk::Widg
}
void CellRendererChannels::render_vfunc_folder(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags) {
constexpr static int len = 5;
int x1, y1, x2, y2, x3, y3;
if (property_expanded()) {
x1 = background_area.get_x() + 7;
y1 = background_area.get_y() + background_area.get_height() / 2 - len;
x2 = background_area.get_x() + 7 + len;
y2 = background_area.get_y() + background_area.get_height() / 2 + len;
x3 = background_area.get_x() + 7 + len * 2;
y3 = background_area.get_y() + background_area.get_height() / 2 - len;
} else {
x1 = background_area.get_x() + 7;
y1 = background_area.get_y() + background_area.get_height() / 2 - len;
x2 = background_area.get_x() + 7 + len * 2;
y2 = background_area.get_y() + background_area.get_height() / 2;
x3 = background_area.get_x() + 7;
y3 = background_area.get_y() + background_area.get_height() / 2 + len;
}
cr->move_to(x1, y1);
cr->line_to(x2, y2);
cr->line_to(x3, y3);
const auto expander_color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelsExpanderColor);
cr->set_source_rgb(expander_color.get_red(), expander_color.get_green(), expander_color.get_blue());
cr->stroke();
RenderExpander(7, cr, widget, background_area, property_expanded());
Gtk::Requisition text_minimum, text_natural;
m_renderer_text.get_preferred_size(widget, text_minimum, text_natural);
@ -241,11 +261,8 @@ void CellRendererChannels::render_vfunc_folder(const Cairo::RefPtr<Cairo::Contex
Gdk::Rectangle text_cell_area(text_x, text_y, text_w, text_h);
static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelColor);
if (m_property_color.get_value().has_value()) {
m_renderer_text.property_foreground_rgba() = *m_property_color.get_value();
} else {
m_renderer_text.property_foreground_rgba() = color;
}
m_renderer_text.render(cr, widget, background_area, text_cell_area, flags);
m_renderer_text.property_foreground_set() = false;
@ -325,8 +342,6 @@ void CellRendererChannels::render_vfunc_guild(const Cairo::RefPtr<Cairo::Context
static_cast<int>(text_w),
static_cast<int>(text_h));
static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelColor);
m_renderer_text.property_foreground_rgba() = color;
m_renderer_text.render(cr, widget, background_area, text_cell_area, flags);
const bool hover_only = Abaddon::Get().GetSettings().AnimatedGuildHoverOnly;
@ -373,14 +388,9 @@ void CellRendererChannels::render_vfunc_guild(const Cairo::RefPtr<Cairo::Context
const auto has_unread = discord.GetUnreadStateForGuild(id, total_mentions);
if (has_unread && !discord.IsGuildMuted(id)) {
static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().UnreadIndicatorColor);
cr->set_source_rgb(color.get_red(), color.get_green(), color.get_blue());
const auto x = background_area.get_x();
const auto y = background_area.get_y();
const auto w = background_area.get_width();
const auto h = background_area.get_height();
cr->rectangle(x, y + h / 2.0 - 24.0 / 2.0, 3.0, 24.0);
cr->fill();
auto area = background_area;
area.set_y(area.get_y() + area.get_height() / 2.0 - 24.0 / 2.0);
AddUnreadIndicator(cr, widget, area);
}
if (total_mentions < 1) return;
@ -410,42 +420,8 @@ void CellRendererChannels::get_preferred_height_for_width_vfunc_category(Gtk::Wi
m_renderer_text.get_preferred_height_for_width(widget, width, minimum_height, natural_height);
}
void AddUnreadIndicator(const Cairo::RefPtr<Cairo::Context> &cr, const Gdk::Rectangle &background_area) {
static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().UnreadIndicatorColor);
cr->set_source_rgb(color.get_red(), color.get_green(), color.get_blue());
const auto x = background_area.get_x();
const auto y = background_area.get_y();
const auto w = background_area.get_width();
const auto h = background_area.get_height();
cr->rectangle(x, y, 3, h);
cr->fill();
}
void CellRendererChannels::render_vfunc_category(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags) {
// todo: figure out how Gtk::Arrow is rendered because i like it better :^)
constexpr static int len = 5;
int x1, y1, x2, y2, x3, y3;
if (property_expanded()) {
x1 = background_area.get_x() + 7;
y1 = background_area.get_y() + background_area.get_height() / 2 - len;
x2 = background_area.get_x() + 7 + len;
y2 = background_area.get_y() + background_area.get_height() / 2 + len;
x3 = background_area.get_x() + 7 + len * 2;
y3 = background_area.get_y() + background_area.get_height() / 2 - len;
} else {
x1 = background_area.get_x() + 7;
y1 = background_area.get_y() + background_area.get_height() / 2 - len;
x2 = background_area.get_x() + 7 + len * 2;
y2 = background_area.get_y() + background_area.get_height() / 2;
x3 = background_area.get_x() + 7;
y3 = background_area.get_y() + background_area.get_height() / 2 + len;
}
cr->move_to(x1, y1);
cr->line_to(x2, y2);
cr->line_to(x3, y3);
const auto expander_color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelsExpanderColor);
cr->set_source_rgb(expander_color.get_red(), expander_color.get_green(), expander_color.get_blue());
cr->stroke();
RenderExpander(7, cr, widget, background_area, property_expanded());
Gtk::Requisition text_minimum, text_natural;
m_renderer_text.get_preferred_size(widget, text_minimum, text_natural);
@ -457,23 +433,14 @@ void CellRendererChannels::render_vfunc_category(const Cairo::RefPtr<Cairo::Cont
Gdk::Rectangle text_cell_area(text_x, text_y, text_w, text_h);
static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelColor);
auto &discord = Abaddon::Get().GetDiscordClient();
const auto id = m_property_id.get_value();
if (discord.IsChannelMuted(m_property_id.get_value())) {
auto muted = color;
muted.set_red(muted.get_red() * 0.5);
muted.set_green(muted.get_green() * 0.5);
muted.set_blue(muted.get_blue() * 0.5);
m_renderer_text.property_foreground_rgba() = muted;
} else {
if (!discord.IsChannelMuted(m_property_id.get_value())) {
if (discord.GetUnreadChannelsCountForCategory(id) > 0) {
AddUnreadIndicator(cr, background_area);
AddUnreadIndicator(cr, widget, background_area);
}
m_renderer_text.property_foreground_rgba() = color;
}
m_renderer_text.render(cr, widget, background_area, text_cell_area, flags);
m_renderer_text.property_foreground_set() = false;
}
// text channel
@ -509,23 +476,14 @@ void CellRendererChannels::render_vfunc_channel(const Cairo::RefPtr<Cairo::Conte
const auto id = m_property_id.get_value();
const bool is_muted = discord.IsChannelMuted(id);
static const auto sfw_unmuted = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelColor);
m_renderer_text.property_sensitive() = false;
static const auto nsfw_color = Gdk::RGBA(Abaddon::Get().GetSettings().NSFWChannelColor);
if (m_property_nsfw.get_value())
m_renderer_text.property_foreground_rgba() = nsfw_color;
else
m_renderer_text.property_foreground_rgba() = sfw_unmuted;
if (is_muted) {
auto col = m_renderer_text.property_foreground_rgba().get_value();
col.set_red(col.get_red() * 0.5);
col.set_green(col.get_green() * 0.5);
col.set_blue(col.get_blue() * 0.5);
m_renderer_text.property_foreground_rgba() = col;
}
auto color = widget.get_style_context()->get_color(Gtk::STATE_FLAG_NORMAL);
if (property_nsfw()) color = nsfw_color;
if (is_muted) color.set_alpha(0.6);
m_renderer_text.property_foreground_rgba() = color;
m_renderer_text.render(cr, widget, background_area, text_cell_area, flags);
// unset foreground to default so properties dont bleed
m_renderer_text.property_foreground_set() = false;
// unread
@ -535,7 +493,7 @@ void CellRendererChannels::render_vfunc_channel(const Cairo::RefPtr<Cairo::Conte
if (unread_state < 0) return;
if (!is_muted) {
AddUnreadIndicator(cr, background_area);
AddUnreadIndicator(cr, widget, background_area);
}
if (unread_state < 1) return;
@ -580,18 +538,7 @@ void CellRendererChannels::render_vfunc_thread(const Cairo::RefPtr<Cairo::Contex
const auto id = m_property_id.get_value();
const bool is_muted = discord.IsChannelMuted(id);
static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelColor);
if (Abaddon::Get().GetDiscordClient().IsChannelMuted(m_property_id.get_value())) {
auto muted = color;
muted.set_red(muted.get_red() * 0.5);
muted.set_green(muted.get_green() * 0.5);
muted.set_blue(muted.get_blue() * 0.5);
m_renderer_text.property_foreground_rgba() = muted;
} else {
m_renderer_text.property_foreground_rgba() = color;
}
m_renderer_text.render(cr, widget, background_area, text_cell_area, flags);
m_renderer_text.property_foreground_set() = false;
// unread
if (!Abaddon::Get().GetSettings().Unreads) return;
@ -600,14 +547,7 @@ void CellRendererChannels::render_vfunc_thread(const Cairo::RefPtr<Cairo::Contex
if (unread_state < 0) return;
if (!is_muted) {
static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().UnreadIndicatorColor);
cr->set_source_rgb(color.get_red(), color.get_green(), color.get_blue());
const auto x = background_area.get_x();
const auto y = background_area.get_y();
const auto w = background_area.get_width();
const auto h = background_area.get_height();
cr->rectangle(x, y, 3, h);
cr->fill();
AddUnreadIndicator(cr, widget, background_area);
}
if (unread_state < 1) return;
@ -667,31 +607,7 @@ void CellRendererChannels::render_vfunc_voice_channel(const Cairo::RefPtr<Cairo:
cell_area.get_y() + cell_area.get_height() / 2.0 - height / 2.0);
layout->show_in_cairo_context(cr);
// expander
constexpr static int len = 5;
constexpr static int offset = 24;
int x1, y1, x2, y2, x3, y3;
if (property_expanded()) {
x1 = background_area.get_x() + offset;
y1 = background_area.get_y() + background_area.get_height() / 2 - len;
x2 = background_area.get_x() + offset + len;
y2 = background_area.get_y() + background_area.get_height() / 2 + len;
x3 = background_area.get_x() + offset + len * 2;
y3 = background_area.get_y() + background_area.get_height() / 2 - len;
} else {
x1 = background_area.get_x() + offset;
y1 = background_area.get_y() + background_area.get_height() / 2 - len;
x2 = background_area.get_x() + offset + len * 2;
y2 = background_area.get_y() + background_area.get_height() / 2;
x3 = background_area.get_x() + offset;
y3 = background_area.get_y() + background_area.get_height() / 2 + len;
}
cr->move_to(x1, y1);
cr->line_to(x2, y2);
cr->line_to(x3, y3);
const auto expander_color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelsExpanderColor);
cr->set_source_rgb(expander_color.get_red(), expander_color.get_green(), expander_color.get_blue());
cr->stroke();
RenderExpander(24, cr, widget, background_area, property_expanded());
}
// voice participant
@ -897,18 +813,7 @@ void CellRendererChannels::render_vfunc_dm(const Cairo::RefPtr<Cairo::Context> &
const auto id = m_property_id.get_value();
const bool is_muted = discord.IsChannelMuted(id);
static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelColor);
if (Abaddon::Get().GetDiscordClient().IsChannelMuted(m_property_id.get_value())) {
auto muted = color;
muted.set_red(muted.get_red() * 0.5);
muted.set_green(muted.get_green() * 0.5);
muted.set_blue(muted.get_blue() * 0.5);
m_renderer_text.property_foreground_rgba() = muted;
} else {
m_renderer_text.property_foreground_rgba() = color;
}
m_renderer_text.render(cr, widget, background_area, text_cell_area, flags);
m_renderer_text.property_foreground_set() = false;
Gdk::Cairo::set_source_pixbuf(cr, m_property_pixbuf.get_value(), icon_x, icon_y);
cr->rectangle(icon_x, icon_y, icon_w, icon_h);
@ -921,14 +826,7 @@ void CellRendererChannels::render_vfunc_dm(const Cairo::RefPtr<Cairo::Context> &
if (unread_state < 0) return;
if (!is_muted) {
static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().UnreadIndicatorColor);
cr->set_source_rgb(color.get_red(), color.get_green(), color.get_blue());
const auto x = background_area.get_x();
const auto y = background_area.get_y();
const auto w = background_area.get_width();
const auto h = background_area.get_height();
cr->rectangle(x, y, 3, h);
cr->fill();
AddUnreadIndicator(cr, widget, background_area);
}
}
@ -955,8 +853,11 @@ void CellRendererChannels::unread_render_mentions(const Cairo::RefPtr<Cairo::Con
int width, height;
layout->get_pixel_size(width, height);
{
static const auto bg = Gdk::RGBA(Abaddon::Get().GetSettings().MentionBadgeColor);
static const auto text = Gdk::RGBA(Abaddon::Get().GetSettings().MentionBadgeTextColor);
static const auto badge_setting = Gdk::RGBA(Abaddon::Get().GetSettings().MentionBadgeColor);
static const auto text_setting = Gdk::RGBA(Abaddon::Get().GetSettings().MentionBadgeTextColor);
auto bg = badge_setting.get_alpha_u() > 0 ? badge_setting : widget.get_style_context()->get_background_color(Gtk::STATE_FLAG_SELECTED);
auto text = text_setting.get_alpha_u() > 0 ? text_setting : widget.get_style_context()->get_color(Gtk::STATE_FLAG_SELECTED);
const auto x = cell_area.get_x() + edge - width - MentionsRightPad;
const auto y = cell_area.get_y() + cell_area.get_height() / 2.0 - height / 2.0 - 1;

View File

@ -20,7 +20,7 @@ ChatInputText::ChatInputText() {
m_textview.signal_key_press_event().connect(cb, false);
m_textview.set_hexpand(false);
m_textview.set_halign(Gtk::ALIGN_FILL);
m_textview.set_valign(Gtk::ALIGN_CENTER);
m_textview.set_valign(Gtk::ALIGN_FILL);
m_textview.set_wrap_mode(Gtk::WRAP_WORD_CHAR);
m_textview.show();
add(m_textview);
@ -113,30 +113,25 @@ ChatInputTextContainer::ChatInputTextContainer() {
};
m_input.signal_key_press_proxy().connect(cb);
m_upload_button.set_image(m_upload_img);
m_upload_button.set_halign(Gtk::ALIGN_CENTER);
m_upload_button.set_valign(Gtk::ALIGN_CENTER);
m_upload_button.get_style_context()->add_class(GTK_STYLE_CLASS_FLAT);
m_upload_img.property_icon_name() = "document-send-symbolic";
m_upload_img.property_icon_size() = Gtk::ICON_SIZE_LARGE_TOOLBAR;
m_upload_img.get_style_context()->add_class("message-input-browse-icon");
AddPointerCursor(m_upload_ev);
m_upload_ev.signal_button_press_event().connect([this](GdkEventButton *ev) -> bool {
if (ev->button == GDK_BUTTON_PRIMARY) {
ShowFileChooser();
// return focus
m_input.grab_focus();
return true;
}
return false;
m_upload_button.signal_clicked().connect([this]() {
ShowFileChooser();
m_input.grab_focus();
});
m_upload_ev.add(m_upload_img);
add_overlay(m_upload_ev);
add(m_input);
m_upload_box.pack_start(m_upload_button);
pack_start(m_upload_box, false, false);
pack_start(m_input);
show_all_children();
// stop the overlay from using (start) padding
signal_get_child_position().connect(sigc::mem_fun(*this, &ChatInputTextContainer::GetChildPosition), false);
}
void ChatInputTextContainer::ShowFileChooser() {
@ -160,39 +155,11 @@ ChatInputText &ChatInputTextContainer::Get() {
}
void ChatInputTextContainer::ShowChooserIcon() {
m_upload_ev.show();
m_upload_button.show();
}
void ChatInputTextContainer::HideChooserIcon() {
m_upload_ev.hide();
}
bool ChatInputTextContainer::GetChildPosition(Gtk::Widget *child, Gdk::Rectangle &pos) {
Gtk::Allocation main_alloc;
{
auto *grandchild = m_input.get_child();
int x, y;
if (grandchild->translate_coordinates(m_input, 0, 0, x, y)) {
main_alloc.set_x(x);
main_alloc.set_y(y);
} else {
main_alloc.set_x(0);
main_alloc.set_y(0);
}
main_alloc.set_width(grandchild->get_allocated_width());
main_alloc.set_height(grandchild->get_allocated_height());
}
Gtk::Requisition min, req;
child->get_preferred_size(min, req);
// let css move it around
pos.set_x(0);
pos.set_y(0);
pos.set_width(std::max(min.width, std::min(main_alloc.get_width(), req.width)));
pos.set_height(std::max(min.height, std::min(main_alloc.get_height(), req.height)));
return true;
m_upload_button.hide();
}
ChatInputTextContainer::type_signal_add_attachment ChatInputTextContainer::signal_add_attachment() {

View File

@ -104,7 +104,7 @@ private:
};
// file upload, text
class ChatInputTextContainer : public Gtk::Overlay {
class ChatInputTextContainer : public Gtk::Box {
public:
ChatInputTextContainer();
@ -116,9 +116,9 @@ public:
private:
void ShowFileChooser();
bool GetChildPosition(Gtk::Widget *child, Gdk::Rectangle &pos);
Gtk::EventBox m_upload_ev;
Gtk::Box m_upload_box;
Gtk::Button m_upload_button;
Gtk::Image m_upload_img;
ChatInputText m_input;

View File

@ -364,7 +364,7 @@ Gtk::Widget *ChatMessageItemContainer::CreateEmbedComponent(const EmbedData &emb
}
return false;
});
static auto color = Abaddon::Get().GetSettings().LinkColor;
const auto color = title_label->get_style_context()->get_color(Gtk::STATE_FLAG_LINK);
title_label->override_color(Gdk::RGBA(color));
title_label->set_markup("<b>" + Glib::Markup::escape_text(*embed.Title) + "</b>");
}
@ -856,7 +856,8 @@ void ChatMessageItemContainer::HandleLinks(Gtk::TextView &tv) {
std::string link = match.fetch(0);
auto tag = buf->create_tag();
m_link_tagmap[tag] = link;
tag->property_foreground_rgba() = Gdk::RGBA(Abaddon::Get().GetSettings().LinkColor);
const auto color = tv.get_style_context()->get_color(Gtk::STATE_FLAG_LINK);
tag->property_foreground_rgba() = color;
tag->set_property("underline", 1); // stupid workaround for vcpkg bug (i think)
const auto chars_start = g_utf8_pointer_to_offset(text.c_str(), text.c_str() + mstart);

View File

@ -5,7 +5,7 @@
#include "chatlist.hpp"
#include "constants.hpp"
#ifdef WITH_LIBHANDY
#include "channeltabswitcherhandy.hpp"
#include "channeltabswitcherhandy.hpp"
#endif
ChatWindow::ChatWindow() {
@ -109,7 +109,13 @@ ChatWindow::ChatWindow() {
m_main->add(*m_meta);
m_main->add(m_progress);
m_progress.show();
m_progress.signal_start().connect([this]() {
m_progress.show();
});
m_progress.signal_stop().connect([this]() {
m_progress.hide();
});
m_main->show();
}

View File

@ -5,12 +5,19 @@ MessageUploadProgressBar::MessageUploadProgressBar() {
auto &discord = Abaddon::Get().GetDiscordClient();
discord.signal_message_progress().connect([this](const std::string &nonce, float percent) {
if (nonce == m_last_nonce) {
if (!m_active) {
m_active = true;
m_signal_start.emit();
}
set_fraction(percent);
}
});
discord.signal_message_send_fail().connect([this](const std::string &nonce, float) {
if (nonce == m_last_nonce)
if (nonce == m_last_nonce) {
set_fraction(0.0);
m_active = false;
m_signal_stop.emit();
}
});
discord.signal_message_create().connect([this](const Message &msg) {
if (msg.IsPending) {
@ -18,6 +25,16 @@ MessageUploadProgressBar::MessageUploadProgressBar() {
} else if (msg.Nonce.has_value() && (*msg.Nonce == m_last_nonce)) {
m_last_nonce = "";
set_fraction(0.0);
m_active = false;
m_signal_stop.emit();
}
});
}
MessageUploadProgressBar::type_signal_start MessageUploadProgressBar::signal_start() {
return m_signal_start;
}
MessageUploadProgressBar::type_signal_stop MessageUploadProgressBar::signal_stop() {
return m_signal_stop;
}

View File

@ -6,5 +6,16 @@ public:
MessageUploadProgressBar();
private:
bool m_active = false;
std::string m_last_nonce;
using type_signal_start = sigc::signal<void()>;
using type_signal_stop = sigc::signal<void()>;
type_signal_start m_signal_start;
type_signal_stop m_signal_stop;
public:
type_signal_start signal_start();
type_signal_stop signal_stop();
};

View File

@ -1,17 +1,31 @@
#include "setstatus.hpp"
static const std::array feelings = {
"wonderful",
"splendiferous",
"delicious",
"outstanding",
"amazing",
"great",
"marvelous",
"superb",
"out of this world",
"stupendous",
"tip-top",
"horrible",
};
SetStatusDialog::SetStatusDialog(Gtk::Window &parent)
: Gtk::Dialog("Set Status", parent, true)
, m_layout(Gtk::ORIENTATION_VERTICAL)
, m_bottom(Gtk::ORIENTATION_HORIZONTAL)
, m_ok("OK")
, m_cancel("Cancel")
, m_bbox(Gtk::ORIENTATION_HORIZONTAL) {
set_default_size(300, 50);
, m_cancel("Cancel") {
set_default_size(350, 200);
get_style_context()->add_class("app-window");
get_style_context()->add_class("app-popup");
get_style_context()->add_class("set-status-dialog");
m_text.set_placeholder_text("Status text");
m_text.set_placeholder_text("I feel " + Glib::ustring(feelings[rand() % feelings.size()]) + "!");
m_status_combo.append("online", "Online");
m_status_combo.append("dnd", "Do Not Disturb");
@ -35,16 +49,17 @@ SetStatusDialog::SetStatusDialog(Gtk::Window &parent)
response(Gtk::RESPONSE_CANCEL);
});
m_bbox.pack_start(m_ok, Gtk::PACK_SHRINK);
m_bbox.pack_start(m_cancel, Gtk::PACK_SHRINK);
m_bbox.set_layout(Gtk::BUTTONBOX_END);
m_layout.pack_start(*Gtk::make_managed<Gtk::Label>("How are you, " + Abaddon::Get().GetDiscordClient().GetUserData().GetDisplayName() + "?", Gtk::ALIGN_START));
m_layout.pack_start(m_text);
m_layout.pack_start(*Gtk::make_managed<Gtk::Label>("Status", Gtk::ALIGN_START));
m_layout.pack_start(m_status_combo);
m_layout.pack_start(*Gtk::make_managed<Gtk::Label>("Activity", Gtk::ALIGN_START));
m_layout.pack_start(m_type_combo);
m_bottom.add(m_status_combo);
m_bottom.add(m_type_combo);
m_bottom.add(m_bbox);
m_layout.add(m_text);
m_layout.add(m_bottom);
get_content_area()->add(m_layout);
get_action_area()->pack_start(m_ok, Gtk::PACK_SHRINK);
get_action_area()->pack_start(m_cancel, Gtk::PACK_SHRINK);
get_action_area()->set_layout(Gtk::BUTTONBOX_START);
show_all_children();
}

View File

@ -8,14 +8,12 @@ public:
PresenceStatus GetStatusType() const;
std::string GetActivityName() const;
protected:
private:
Gtk::Box m_layout;
Gtk::Box m_bottom;
Gtk::Entry m_text;
Gtk::ComboBoxText m_status_combo;
Gtk::ComboBoxText m_type_combo;
Gtk::Button m_ok;
Gtk::Button m_cancel;
Gtk::ButtonBox m_bbox;
};

View File

@ -68,9 +68,7 @@ void SettingsManager::ReadSettings() {
SMINT("http", "concurrent", CacheHTTPConcurrency);
SMSTR("http", "user_agent", UserAgent);
SMSTR("style", "expandercolor", ChannelsExpanderColor);
SMSTR("style", "linkcolor", LinkColor);
SMSTR("style", "nsfwchannelcolor", NSFWChannelColor);
SMSTR("style", "channelcolor", ChannelColor);
SMSTR("style", "mentionbadgecolor", MentionBadgeColor);
SMSTR("style", "mentionbadgetextcolor", MentionBadgeTextColor);
SMSTR("style", "unreadcolor", UnreadIndicatorColor);
@ -159,9 +157,7 @@ void SettingsManager::Close() {
SMINT("http", "concurrent", CacheHTTPConcurrency);
SMSTR("http", "user_agent", UserAgent);
SMSTR("style", "expandercolor", ChannelsExpanderColor);
SMSTR("style", "linkcolor", LinkColor);
SMSTR("style", "nsfwchannelcolor", NSFWChannelColor);
SMSTR("style", "channelcolor", ChannelColor);
SMSTR("style", "mentionbadgecolor", MentionBadgeColor);
SMSTR("style", "mentionbadgetextcolor", MentionBadgeTextColor);
SMSTR("style", "unreadcolor", UnreadIndicatorColor);

View File

@ -38,14 +38,11 @@ public:
std::string UserAgent { "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36" };
// [style]
// TODO: convert to StyleProperty... or maybe not? i still cant figure out what the "correct" method is for this
std::string LinkColor { "rgba(40, 200, 180, 255)" };
std::string ChannelsExpanderColor { "rgba(255, 83, 112, 255)" };
std::string NSFWChannelColor { "#ed6666" };
std::string ChannelColor { "#fbfbfb" };
std::string MentionBadgeColor { "#b82525" };
std::string MentionBadgeTextColor { "#fbfbfb" };
std::string UnreadIndicatorColor { "#ffffff" };
std::string ChannelsExpanderColor { "rgba(255, 83, 112, 0)" };
std::string NSFWChannelColor { "#970d0d" };
std::string MentionBadgeColor { "rgba(184, 37, 37, 0)" };
std::string MentionBadgeTextColor { "rgba(251, 251, 251, 0)" };
std::string UnreadIndicatorColor { "rgba(255, 255, 255, 0)" };
// [notifications]
#ifdef _WIN32

View File

@ -12,6 +12,7 @@
VoiceSettingsWindow::VoiceSettingsWindow()
: m_main(Gtk::ORIENTATION_VERTICAL) {
get_style_context()->add_class("app-window");
get_style_context()->add_class("voice-settings-window");
set_default_size(300, 300);
m_encoding_mode.append("Voice");
@ -115,10 +116,21 @@ VoiceSettingsWindow::VoiceSettingsWindow()
m_signal_gain.emit(m_gain.get_value() / 100.0);
});
m_main.add(m_encoding_mode);
m_main.add(m_signal);
m_main.add(m_bitrate);
m_main.add(m_gain);
auto *layout = Gtk::make_managed<Gtk::HBox>();
auto *labels = Gtk::make_managed<Gtk::VBox>();
auto *widgets = Gtk::make_managed<Gtk::VBox>();
layout->pack_start(*labels, false, true, 5);
layout->pack_start(*widgets);
labels->pack_start(*Gtk::make_managed<Gtk::Label>("Coding Mode", Gtk::ALIGN_END));
labels->pack_start(*Gtk::make_managed<Gtk::Label>("Signal Hint", Gtk::ALIGN_END));
labels->pack_start(*Gtk::make_managed<Gtk::Label>("Bitrate", Gtk::ALIGN_END));
labels->pack_start(*Gtk::make_managed<Gtk::Label>("Gain", Gtk::ALIGN_END));
widgets->pack_start(m_encoding_mode);
widgets->pack_start(m_signal);
widgets->pack_start(m_bitrate);
widgets->pack_start(m_gain);
m_main.add(*layout);
add(m_main);
show_all_children();

View File

@ -181,7 +181,7 @@ VoiceWindow::VoiceWindow(Snowflake channel_id)
m_mix_mono.set_active(audio.GetMixMono());
m_mix_mono.signal_toggled().connect([this]() {
Abaddon::Get().GetAudio().SetMixMono(m_mix_mono.get_active());
Abaddon::Get().GetAudio().SetMixMono(m_mix_mono.get_active());
});
auto *playback_renderer = Gtk::make_managed<Gtk::CellRendererText>();
@ -225,20 +225,40 @@ VoiceWindow::VoiceWindow(Snowflake channel_id)
window->show();
});
auto *sliders_container = Gtk::make_managed<Gtk::HBox>();
auto *sliders_labels = Gtk::make_managed<Gtk::VBox>();
auto *sliders_sliders = Gtk::make_managed<Gtk::VBox>();
sliders_container->pack_start(*sliders_labels, false, true, 2);
sliders_container->pack_start(*sliders_sliders);
sliders_labels->pack_start(*Gtk::make_managed<Gtk::Label>("Threshold", Gtk::ALIGN_END));
sliders_labels->pack_start(*Gtk::make_managed<Gtk::Label>("Gain", Gtk::ALIGN_END));
sliders_sliders->pack_start(m_vad_param);
sliders_sliders->pack_start(m_capture_gain);
auto *combos_container = Gtk::make_managed<Gtk::HBox>();
auto *combos_labels = Gtk::make_managed<Gtk::VBox>();
auto *combos_combos = Gtk::make_managed<Gtk::VBox>();
combos_container->pack_start(*combos_labels, false, true, 6);
combos_container->pack_start(*combos_combos, Gtk::PACK_EXPAND_WIDGET, 6);
combos_labels->pack_start(*Gtk::make_managed<Gtk::Label>("VAD Method", Gtk::ALIGN_END));
combos_labels->pack_start(*Gtk::make_managed<Gtk::Label>("Output Device", Gtk::ALIGN_END));
combos_labels->pack_start(*Gtk::make_managed<Gtk::Label>("Input Device", Gtk::ALIGN_END));
combos_combos->pack_start(m_vad_combo);
combos_combos->pack_start(m_playback_combo);
combos_combos->pack_start(m_capture_combo);
m_scroll.add(m_user_list);
m_controls.add(m_mute);
m_controls.add(m_deafen);
m_controls.add(m_noise_suppression);
m_controls.add(m_mix_mono);
m_main.add(m_menu_bar);
m_main.add(m_controls);
m_main.add(m_vad_value);
m_main.add(m_vad_param);
m_main.add(m_capture_gain);
m_main.add(m_scroll);
m_main.add(m_vad_combo);
m_main.add(m_playback_combo);
m_main.add(m_capture_combo);
m_main.pack_start(m_menu_bar);
m_main.pack_start(m_controls);
m_main.pack_start(m_vad_value);
m_main.pack_start(*Gtk::make_managed<Gtk::Label>("Input Settings"));
m_main.pack_start(*sliders_container);
m_main.pack_start(m_scroll);
m_main.pack_start(*combos_container, Gtk::PACK_EXPAND_WIDGET, 2);
add(m_main);
show_all_children();