ui: search sidebar initial

This commit is contained in:
bobufa 2018-07-04 23:38:28 +02:00
parent babfc3bd36
commit 8b23ddad2d
15 changed files with 161 additions and 79 deletions

View file

@ -44,6 +44,7 @@ set(RESOURCE_LIST
occupant_list.ui
occupant_list_item.ui
settings_dialog.ui
unified_main_content.ui
unified_window_placeholder.ui
theme.css

View file

@ -22,20 +22,5 @@
<property name="pack_type">start</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="search_button">
<property name="visible">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon-name">system-search-symbolic</property>
<property name="icon-size">1</property>
</object>
</child>
</object>
<packing>
<property name="pack_type">end</property>
</packing>
</child>
</template>
</interface>

View file

@ -4,21 +4,6 @@
<property name="can_focus">True</property>
<property name="expand">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkRevealer" id="search_revealer">
<property name="hexpand">True</property>
<property name="visible">True</property>
<child>
<object class="GtkSearchEntry" id="search_entry">
<property name="primary_icon_name">edit-find-symbolic</property>
<property name="placeholder_text" translatable="yes">Search</property>
<property name="margin">10px</property>
<property name="hexpand">True</property>
<property name="visible">True</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow" id="scrolled">
<property name="expand">True</property>

View file

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="menu_add">
<section>

View file

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="menu_app">
<section>

View file

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<menu id="menu_conversation">
<section>

View file

@ -17,6 +17,16 @@ window.dino-main .dino-conversation undershoot {
background: none;
}
window.dino-main .dino-sidebar frame {
background: @insensitive_bg_color;
border-left: 1px solid @borders;
}
window.dino-main .dino-sidebar frame.collapsed {
border-bottom: 1px solid @borders;
}
window.dino-main .dino-chatinput frame box {
background: @theme_base_color;
}

View file

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<object class="GtkPaned" id="paned">
<property name="position">300</property>
<property name="orientation">horizontal</property>
<property name="visible">True</property>
<child>
<object class="DinoUiConversationSelectorView" id="conversation_list">
<property name="visible">True</property>
</object>
<packing>
<property name="resize">False</property>
<property name="shrink">False</property>
</packing>
</child>
<child>
<object class="GtkOverlay">
<property name="visible">True</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="visible">True</property>
<style>
<class name="dino-conversation"/>
</style>
<child>
<object class="DinoUiConversationSummaryConversationView" id="conversation_frame">
<property name="visible">True</property>
</object>
</child>
<child>
<object class="DinoUiChatInputView" id="chat_input">
<property name="visible">True</property>
</object>
</child>
</object>
</child>
<child type="overlay">
<object class="GtkRevealer" id="search_revealer">
<property name="visible">True</property>
<property name="halign">end</property>
<property name="transition-type">slide-left</property>
<style>
<class name="dino-sidebar"/>
</style>
<child>
<object class="GtkFrame">
<property name="visible">True</property>
<property name="width-request">400</property>
<property name="shadow-type">none</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="visible">True</property>
<child>
<object class="GtkSearchEntry" id="search_entry">
<property name="visible">True</property>
<property name="margin">12</property>
</object>
</child>
<child><placeholder/></child>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="resize">True</property>
<property name="shrink">False</property>
</packing>
</child>
</object>
</interface>

View file

@ -32,7 +32,7 @@ public class View : Box {
[GtkChild] private Separator file_separator;
private EncryptionButton encryption_widget = new EncryptionButton() { margin_top=3, valign=Align.START, visible=true };
public View(StreamInteractor stream_interactor) {
public View init(StreamInteractor stream_interactor) {
this.stream_interactor = stream_interactor;
occupants_tab_completor = new OccupantsTabCompletor(stream_interactor, text_input);
@ -70,6 +70,7 @@ public class View : Box {
Util.force_css(frame, "* { border-radius: 3px; }");
stream_interactor.get_module(FileManager.IDENTITY).upload_available.connect(on_upload_available);
return this;
}
public void initialize_for_conversation(Conversation conversation) {

View file

@ -10,7 +10,6 @@ public class ConversationListTitlebar : Gtk.HeaderBar {
public signal void conversation_opened(Conversation conversation);
[GtkChild] private MenuButton add_button;
[GtkChild] public ToggleButton search_button;
private StreamInteractor stream_interactor;

View file

@ -10,43 +10,14 @@ namespace Dino.Ui.ConversationSelector {
public class View : Box {
public List conversation_list;
[GtkChild] public SearchEntry search_entry;
[GtkChild] public Revealer search_revealer;
[GtkChild] private ScrolledWindow scrolled;
public View(StreamInteractor stream_interactor) {
public View init(StreamInteractor stream_interactor) {
conversation_list = new List(stream_interactor) { visible=true };
scrolled.add(conversation_list);
search_entry.key_release_event.connect(search_key_release_event);
search_entry.search_changed.connect(search_changed);
return this;
}
public void conversation_selected(Conversation? conversation) {
search_entry.set_text("");
}
private void refilter() {
string[]? values = null;
string str = search_entry.get_text ();
if (str != "") values = str.split(" ");
conversation_list.set_filter_values(values);
}
private void search_changed(Editable editable) {
refilter();
}
private bool search_key_release_event(EventKey event) {
conversation_list.select_row(conversation_list.get_row_at_y(0));
if (event.keyval == Key.Down) {
ConversationRow? row = (ConversationRow) conversation_list.get_row_at_index(0);
if (row != null) {
conversation_list.select_row(row);
row.grab_focus();
}
}
return false;
}
}
}

View file

@ -35,7 +35,7 @@ public class ConversationView : Box, Plugins.ConversationItemCollection {
private bool firstLoad = true;
private bool at_current_content = true;
public ConversationView(StreamInteractor stream_interactor) {
public ConversationView init(StreamInteractor stream_interactor) {
this.stream_interactor = stream_interactor;
scrolled.vadjustment.notify["upper"].connect_after(on_upper_notify);
scrolled.vadjustment.notify["value"].connect(on_value_notify);
@ -58,6 +58,7 @@ public class ConversationView : Box, Plugins.ConversationItemCollection {
});
Util.force_base_background(this);
return this;
}
// Workaround GTK TextView issues: Delay first load of contents

View file

@ -0,0 +1,32 @@
using Gtk;
using Gee;
using Dino.Entities;
namespace Dino.Ui {
public class SearchMenuEntry : Plugins.ConversationTitlebarEntry, Object {
public string id { get { return "search"; } }
Plugins.ConversationTitlebarWidget search_button;
public SearchMenuEntry(Plugins.ConversationTitlebarWidget search_button) {
this.search_button = search_button;
}
public double order { get { return 1; } }
public Plugins.ConversationTitlebarWidget? get_widget(Plugins.WidgetType type) {
if (type == Plugins.WidgetType.GTK) {
return search_button;
}
return null;
}
}
public class GlobalSearchButton : Plugins.ConversationTitlebarWidget, Gtk.ToggleButton {
public new void set_conversation(Conversation conversation) {
active = false;
}
}
}

View file

@ -11,6 +11,7 @@ public class ConversationTitlebar : Gtk.HeaderBar {
private Window window;
private Conversation? conversation;
private Gee.List<Plugins.ConversationTitlebarWidget> widgets = new ArrayList<Plugins.ConversationTitlebarWidget>();
public GlobalSearchButton search_button = new GlobalSearchButton() { visible = true };
public ConversationTitlebar(StreamInteractor stream_interactor, Window window) {
this.stream_interactor = stream_interactor;
@ -19,9 +20,11 @@ public class ConversationTitlebar : Gtk.HeaderBar {
this.get_style_context().add_class("dino-right");
show_close_button = true;
hexpand = true;
search_button.set_image(new Gtk.Image.from_icon_name("system-search-symbolic", Gtk.IconSize.MENU) { visible = true });
Application app = GLib.Application.get_default() as Application;
app.plugin_registry.register_contact_titlebar_entry(new MenuEntry(stream_interactor));
app.plugin_registry.register_contact_titlebar_entry(new SearchMenuEntry(search_button));
app.plugin_registry.register_contact_titlebar_entry(new OccupantsEntry(stream_interactor, window));
foreach(var e in app.plugin_registry.conversation_titlebar_entries) {

View file

@ -16,7 +16,9 @@ public class UnifiedWindow : Window {
private ConversationTitlebar conversation_titlebar;
private HeaderBar placeholder_headerbar = new HeaderBar() { title="Dino", show_close_button=true, visible=true };
private Paned headerbar_paned = new Paned(Orientation.HORIZONTAL) { visible=true };
private Paned paned = new Paned(Orientation.HORIZONTAL) { visible=true };
private Paned paned;
private Revealer search_revealer;
private SearchEntry search_entry;
private Stack stack = new Stack() { visible=true };
private StreamInteractor stream_interactor;
@ -36,8 +38,15 @@ public class UnifiedWindow : Window {
setup_unified();
setup_stack();
conversation_list_titlebar.search_button.bind_property("active", filterable_conversation_list.search_revealer, "reveal-child",
BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
conversation_titlebar.search_button.bind_property("active", search_revealer, "reveal-child", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
search_revealer.notify["child-revealed"].connect(() => {
if (search_revealer.child_revealed) {
search_entry.grab_focus();
} else {
search_entry.text = "";
}
});
paned.bind_property("position", headerbar_paned, "position", BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
focus_in_event.connect(on_focus_in_event);
@ -56,6 +65,18 @@ public class UnifiedWindow : Window {
check_stack();
}
private void hide_search_results() {
search_revealer.get_style_context().add_class("collapsed");
search_revealer.valign = Align.START;
// TODO: Make search results box inivisble
}
private void show_search_results() {
// TODO: Make search results box visible
search_revealer.get_style_context().remove_class("collapsed");
search_revealer.valign = Align.FILL;
}
public void on_conversation_selected(Conversation conversation) {
if (this.conversation == null || !this.conversation.equals(conversation)) {
this.conversation = conversation;
@ -70,18 +91,13 @@ public class UnifiedWindow : Window {
}
private void setup_unified() {
chat_input = new ChatInput.View(stream_interactor) { visible=true };
conversation_frame = new ConversationSummary.ConversationView(stream_interactor) { visible=true };
filterable_conversation_list = new ConversationSelector.View(stream_interactor) { visible=true };
Grid grid = new Grid() { orientation=Orientation.VERTICAL, visible=true };
grid.get_style_context().add_class("dino-conversation");
grid.add(conversation_frame);
grid.add(chat_input);
paned.set_position(300);
paned.pack1(filterable_conversation_list, false, false);
paned.pack2(grid, true, false);
Builder builder = new Builder.from_resource("/im/dino/Dino/unified_main_content.ui");
paned = (Paned) builder.get_object("paned");
chat_input = ((ChatInput.View) builder.get_object("chat_input")).init(stream_interactor);
conversation_frame = ((ConversationSummary.ConversationView) builder.get_object("conversation_frame")).init(stream_interactor);
filterable_conversation_list = ((ConversationSelector.View) builder.get_object("conversation_list")).init(stream_interactor);
search_revealer = (Revealer) builder.get_object("search_revealer");
search_entry = (SearchEntry) builder.get_object("search_entry");
}
private void setup_headerbar() {