Use libhandy for main window

This commit is contained in:
Marvin W 2020-03-14 00:53:50 +01:00 committed by fiaxh
parent 6ca47bf795
commit 5e04cdde39
5 changed files with 103 additions and 21 deletions

11
cmake/FindHandy.cmake Normal file
View file

@ -0,0 +1,11 @@
include(PkgConfigWithFallback)
find_pkg_config_with_fallback(Handy
PKG_CONFIG_NAME libhandy-0.0
LIB_NAMES libhandy-0.0
INCLUDE_NAMES handy.h
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Handy
REQUIRED_VARS Handy_LIBRARY
VERSION_VAR Handy_VERSION)

View file

@ -13,6 +13,7 @@ find_packages(MAIN_PACKAGES REQUIRED
GTK3 GTK3
ICU ICU
Gspell Gspell
Handy
) )
set(RESOURCE_LIST set(RESOURCE_LIST
@ -211,7 +212,7 @@ OPTIONS
${MAIN_EXTRA_OPTIONS} ${MAIN_EXTRA_OPTIONS}
) )
add_definitions(${VALA_CFLAGS} -DGETTEXT_PACKAGE=\"${GETTEXT_PACKAGE}\" -DLOCALE_INSTALL_DIR=\"${LOCALE_INSTALL_DIR}\" -DDINO_VERSION=\"${PROJECT_VERSION}\") add_definitions(${VALA_CFLAGS} -DGETTEXT_PACKAGE=\"${GETTEXT_PACKAGE}\" -DLOCALE_INSTALL_DIR=\"${LOCALE_INSTALL_DIR}\" -DDINO_VERSION=\"${PROJECT_VERSION}\" -DHANDY_USE_UNSTABLE_API=yes)
add_executable(dino ${MAIN_VALA_C} ${MAIN_GRESOURCES_TARGET} src/emojichooser.c) add_executable(dino ${MAIN_VALA_C} ${MAIN_GRESOURCES_TARGET} src/emojichooser.c)
add_dependencies(dino ${GETTEXT_PACKAGE}-translations) add_dependencies(dino ${GETTEXT_PACKAGE}-translations)
target_include_directories(dino PRIVATE src) target_include_directories(dino PRIVATE src)

View file

@ -1,12 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<object class="GtkPaned" id="paned"> <object class="HdyLeaflet" id="paned">
<property name="position">300</property>
<property name="orientation">horizontal</property> <property name="orientation">horizontal</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property>
<property name="mode-transition-type">slide</property>
<property name="child-transition-type">slide</property>
<child> <child>
<object class="GtkStack" id="left_stack"> <object class="GtkStack" id="left_stack">
<property name="visible">True</property> <property name="visible">True</property>
<property name="hexpand">False</property>
<child> <child>
<object class="GtkScrolledWindow" id="scrolled"> <object class="GtkScrolledWindow" id="scrolled">
<property name="expand">True</property> <property name="expand">True</property>
@ -29,6 +32,7 @@
<property name="valign">start</property> <property name="valign">start</property>
<property name="halign">start</property> <property name="halign">start</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="width_request">260</property>
<child> <child>
<object class="GtkImage" id="conversation_list_placeholder_image"> <object class="GtkImage" id="conversation_list_placeholder_image">
<property name="visible">True</property> <property name="visible">True</property>
@ -44,7 +48,9 @@
<property name="margin-top">70</property> <property name="margin-top">70</property>
<property name="margin-right">50</property> <property name="margin-right">50</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="xalign">0</property>
<property name="valign">end</property> <property name="valign">end</property>
<property name="max-width-chars">0</property>
<property name="label" translatable="yes">Click here to start a conversation or join a channel.</property> <property name="label" translatable="yes">Click here to start a conversation or join a channel.</property>
<style> <style>
<class name="dim-label"/> <class name="dim-label"/>
@ -58,8 +64,7 @@
</child> </child>
</object> </object>
<packing> <packing>
<property name="resize">False</property> <property name="name">list-pane</property>
<property name="shrink">False</property>
</packing> </packing>
</child> </child>
<child> <child>
@ -139,8 +144,7 @@
</child> </child>
</object> </object>
<packing> <packing>
<property name="resize">True</property> <property name="name">view-pane</property>
<property name="shrink">False</property>
</packing> </packing>
</child> </child>
</object> </object>

View file

@ -65,11 +65,23 @@ public class ConversationTitlebarCsd : ConversationTitlebar, Gtk.HeaderBar {
public new string? title { get { return this.get_title(); } set { base.set_title(value); } } public new string? title { get { return this.get_title(); } set { base.set_title(value); } }
public new string? subtitle { get { return this.get_subtitle(); } set { base.set_subtitle(value); } } public new string? subtitle { get { return this.get_subtitle(); } set { base.set_subtitle(value); } }
private Revealer back_revealer;
public bool back_button {
get { return back_revealer.reveal_child; }
set { back_revealer.reveal_child = value; }
}
public signal void back_pressed();
public ConversationTitlebarCsd() { public ConversationTitlebarCsd() {
this.get_style_context().add_class("dino-right"); this.get_style_context().add_class("dino-right");
show_close_button = true; show_close_button = true;
hexpand = true; hexpand = true;
back_revealer = new Revealer() { visible = true, transition_type = RevealerTransitionType.SLIDE_RIGHT, transition_duration = 200, can_focus = false, reveal_child = false };
Button back_button = new Button.from_icon_name("go-previous-symbolic") { visible = true, valign = Align.CENTER, use_underline = true };
back_button.get_style_context().add_class("image-button");
back_button.clicked.connect(() => back_pressed());
back_revealer.add(back_button);
this.pack_start(back_revealer);
} }
public void insert_entry(Plugins.ConversationTitlebarEntry entry) { public void insert_entry(Plugins.ConversationTitlebarEntry entry) {
@ -77,6 +89,16 @@ public class ConversationTitlebarCsd : ConversationTitlebar, Gtk.HeaderBar {
Button gtk_widget = (Gtk.Button)widget; Button gtk_widget = (Gtk.Button)widget;
this.pack_end(gtk_widget); this.pack_end(gtk_widget);
} }
/*
* HdyLeaflet collapses based on natural_width, but labels set natural_width to the width required to have the full
* text in a single line, thus if the label gets longer, HdyLeaflet would collapse. Work around is to just use the
* minimum_width as natural_width.
*/
public override void get_preferred_width(out int minimum_width, out int natural_width) {
base.get_preferred_width(out minimum_width, out natural_width);
natural_width = minimum_width;
}
} }
} }

View file

@ -22,8 +22,9 @@ public class MainWindow : Gtk.Window {
public ConversationListTitlebarCsd conversation_list_titlebar_csd; public ConversationListTitlebarCsd conversation_list_titlebar_csd;
public HeaderBar placeholder_headerbar = new HeaderBar() { title="Dino", show_close_button=true, visible=true }; public HeaderBar placeholder_headerbar = new HeaderBar() { title="Dino", show_close_button=true, visible=true };
public Box box = new Box(Orientation.VERTICAL, 0) { orientation=Orientation.VERTICAL, visible=true }; public Box box = new Box(Orientation.VERTICAL, 0) { orientation=Orientation.VERTICAL, visible=true };
public Paned headerbar_paned = new Paned(Orientation.HORIZONTAL) { visible=true }; public Hdy.Leaflet headerbar_paned = new Hdy.Leaflet() { visible=true };
public Paned paned; public Hdy.TitleBar titlebar = new Hdy.TitleBar() { visible=true };
public Hdy.Leaflet paned;
public Revealer search_revealer; public Revealer search_revealer;
public SearchEntry search_entry; public SearchEntry search_entry;
public GlobalSearch search_box; public GlobalSearch search_box;
@ -44,23 +45,29 @@ public class MainWindow : Gtk.Window {
restore_window_size(); restore_window_size();
this.get_style_context().add_class("dino-main"); this.get_style_context().add_class("dino-main");
setup_headerbar();
Gtk.Settings.get_default().notify["gtk-decoration-layout"].connect(set_window_buttons); Gtk.Settings.get_default().notify["gtk-decoration-layout"].connect(set_window_buttons);
this.realize.connect(set_window_buttons); this.realize.connect(set_window_buttons);
setup_unified(); setup_unified();
setup_headerbar();
setup_stack(); setup_stack();
paned.bind_property("position", headerbar_paned, "position", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL); paned.bind_property("mode-transition-type", headerbar_paned, "mode-transition-type", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
paned.bind_property("mode-transition-duration", headerbar_paned, "mode-transition-duration", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
paned.bind_property("child-transition-type", headerbar_paned, "child-transition-type", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
paned.bind_property("child-transition-duration", headerbar_paned, "child-transition-duration", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
paned.bind_property("visible-child-name", headerbar_paned, "visible-child-name", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
} }
private void setup_unified() { private void setup_unified() {
Builder builder = new Builder.from_resource("/im/dino/Dino/unified_main_content.ui"); Builder builder = new Builder.from_resource("/im/dino/Dino/unified_main_content.ui");
paned = (Paned) builder.get_object("paned"); paned = (Hdy.Leaflet) builder.get_object("paned");
paned.notify["fold"].connect_after(() => update_headerbar());
box.add(paned); box.add(paned);
left_stack = (Stack) builder.get_object("left_stack"); left_stack = (Stack) builder.get_object("left_stack");
right_stack = (Stack) builder.get_object("right_stack"); right_stack = (Stack) builder.get_object("right_stack");
conversation_view = (ConversationView) builder.get_object("conversation_view"); conversation_view = (ConversationView) builder.get_object("conversation_view");
conversation_selector = ((ConversationSelector) builder.get_object("conversation_list")).init(stream_interactor); conversation_selector = ((ConversationSelector) builder.get_object("conversation_list")).init(stream_interactor);
conversation_selector.conversation_selected.connect_after(() => show_view_pane());
search_box = ((GlobalSearch) builder.get_object("search_box")).init(stream_interactor); search_box = ((GlobalSearch) builder.get_object("search_box")).init(stream_interactor);
search_revealer = (Revealer) builder.get_object("search_revealer"); search_revealer = (Revealer) builder.get_object("search_revealer");
search_entry = (SearchEntry) builder.get_object("search_entry"); search_entry = (SearchEntry) builder.get_object("search_entry");
@ -68,20 +75,52 @@ public class MainWindow : Gtk.Window {
conversation_list_placeholder_image.set_from_pixbuf(new Pixbuf.from_resource("/im/dino/Dino/icons/dino-conversation-list-placeholder-arrow.svg")); conversation_list_placeholder_image.set_from_pixbuf(new Pixbuf.from_resource("/im/dino/Dino/icons/dino-conversation-list-placeholder-arrow.svg"));
} }
private void update_headerbar() {
if (!Util.use_csd()) return;
conversation_titlebar_csd.back_button = headerbar_paned.fold == Hdy.Fold.FOLDED;
set_window_buttons();
}
private void show_list_pane() {
paned.visible_child_name = "list-pane";
if (headerbar_paned.fold == Hdy.Fold.FOLDED) {
conversation_selector.unselect_row(conversation_selector.get_selected_row());
}
}
private void show_view_pane() {
paned.visible_child_name = "view-pane";
}
private void setup_headerbar() { private void setup_headerbar() {
SizeGroup conversation_list_group = new SizeGroup(SizeGroupMode.HORIZONTAL);
conversation_list_group.add_widget(left_stack);
SizeGroup conversation_view_group = new SizeGroup(SizeGroupMode.HORIZONTAL);
conversation_view_group.add_widget(right_stack);
if (Util.use_csd()) { if (Util.use_csd()) {
conversation_list_titlebar_csd = new ConversationListTitlebarCsd() { visible=true }; conversation_list_titlebar_csd = new ConversationListTitlebarCsd() { visible=true };
headerbar_paned.pack1(conversation_list_titlebar_csd, false, false); headerbar_paned.add_with_properties(conversation_list_titlebar_csd, "name", "list-pane");
conversation_list_group.add_widget(conversation_list_titlebar_csd);
Separator sep = new Separator(Orientation.HORIZONTAL) { visible = true };
sep.get_style_context().add_class("sidebar");
headerbar_paned.add(sep);
conversation_titlebar_csd = new ConversationTitlebarCsd() { visible=true }; conversation_titlebar_csd = new ConversationTitlebarCsd() { visible=true };
conversation_titlebar_csd.back_pressed.connect(() => show_list_pane());
conversation_titlebar = conversation_titlebar_csd; conversation_titlebar = conversation_titlebar_csd;
headerbar_paned.pack2(conversation_titlebar_csd, true, false); headerbar_paned.add_with_properties(conversation_titlebar_csd, "name", "view-pane");
conversation_view_group.add_widget(conversation_titlebar);
titlebar.add(headerbar_paned);
} else { } else {
ConversationListTitlebar conversation_list_titlebar = new ConversationListTitlebar() { visible=true }; ConversationListTitlebar conversation_list_titlebar = new ConversationListTitlebar() { visible=true };
headerbar_paned.pack1(conversation_list_titlebar, false, false); headerbar_paned.add_with_properties(conversation_list_titlebar, "name", "list-pane");
conversation_list_group.add_widget(conversation_list_titlebar);
conversation_titlebar = new ConversationTitlebarNoCsd() { visible=true }; conversation_titlebar = new ConversationTitlebarNoCsd() { visible=true };
headerbar_paned.pack2(conversation_titlebar, true, false); headerbar_paned.add_with_properties(conversation_titlebar, "name", "view-pane");
conversation_view_group.add_widget(conversation_titlebar);
box.add(headerbar_paned); box.add(headerbar_paned);
} }
@ -92,9 +131,14 @@ public class MainWindow : Gtk.Window {
Gtk.Settings? gtk_settings = Gtk.Settings.get_default(); Gtk.Settings? gtk_settings = Gtk.Settings.get_default();
if (gtk_settings == null) return; if (gtk_settings == null) return;
if (headerbar_paned.fold == Hdy.Fold.FOLDED) {
conversation_list_titlebar_csd.decoration_layout = gtk_settings.gtk_decoration_layout;
conversation_titlebar_csd.decoration_layout = "";
} else {
string[] buttons = gtk_settings.gtk_decoration_layout.split(":"); string[] buttons = gtk_settings.gtk_decoration_layout.split(":");
this.conversation_list_titlebar_csd.decoration_layout = buttons[0] + ":"; conversation_list_titlebar_csd.decoration_layout = buttons[0] + ":";
this.conversation_titlebar_csd.decoration_layout = ((buttons.length == 2) ? ":" + buttons[1] : ""); conversation_titlebar_csd.decoration_layout = ((buttons.length == 2) ? ":" + buttons[1] : "");
}
} }
private void setup_stack() { private void setup_stack() {
@ -118,7 +162,7 @@ public class MainWindow : Gtk.Window {
stack.set_visible_child_name("main"); stack.set_visible_child_name("main");
if (Util.use_csd()) { if (Util.use_csd()) {
set_titlebar(headerbar_paned); set_titlebar(titlebar);
} }
} else if (stack_state == StackState.CLEAN_START || stack_state == StackState.NO_ACTIVE_ACCOUNTS) { } else if (stack_state == StackState.CLEAN_START || stack_state == StackState.NO_ACTIVE_ACCOUNTS) {
if (stack_state == StackState.CLEAN_START) { if (stack_state == StackState.CLEAN_START) {
@ -134,7 +178,7 @@ public class MainWindow : Gtk.Window {
left_stack.set_visible_child_name("placeholder"); left_stack.set_visible_child_name("placeholder");
right_stack.set_visible_child_name("placeholder"); right_stack.set_visible_child_name("placeholder");
if (Util.use_csd()) { if (Util.use_csd()) {
set_titlebar(headerbar_paned); set_titlebar(titlebar);
} }
} }
} }