Drop Granite.ModeButton
This commit is contained in:
parent
c9836034c0
commit
024a870228
|
@ -1,16 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1 -->
|
||||
<!-- Generated with glade 3.36.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<requires lib="libhandy" version="0.0"/>
|
||||
<template class="TootleDialogsMainWindow" parent="GtkWindow">
|
||||
<property name="width_request">450</property>
|
||||
<property name="height_request">600</property>
|
||||
<property name="can_focus">False</property>
|
||||
<child>
|
||||
<object class="GtkStack" id="view_stack">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="transition_type">slide-left-right</property>
|
||||
<child>
|
||||
<object class="GtkStack" id="timeline_stack">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="transition_type">slide-left-right</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">0</property>
|
||||
<property name="title" translatable="yes">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child type="titlebar">
|
||||
<object class="GtkHeaderBar" id="header">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="show_close_button">True</property>
|
||||
<child type="title">
|
||||
<object class="HdyViewSwitcher" id="timeline_switcher">
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkButton" id="back_button">
|
||||
<property name="can_focus">True</property>
|
||||
|
@ -41,11 +68,6 @@
|
|||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child type="title">
|
||||
<object class="GraniteWidgetsModeButton" id="timeline_switcher">
|
||||
<property name="visible">True</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="TootleWidgetsAccountsButton" id="accounts_button">
|
||||
<property name="visible">True</property>
|
||||
|
@ -57,26 +79,5 @@
|
|||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkStack" id="view_stack">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="transition_type">slide-left-right</property>
|
||||
<child>
|
||||
<object class="GtkStack" id="timeline_stack">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">False</property>
|
||||
<property name="transition_type">slide-left-right</property>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="name">0</property>
|
||||
<property name="title" translatable="yes">0</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</template>
|
||||
</interface>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.22.1 -->
|
||||
<!-- Generated with glade 3.36.0 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.20"/>
|
||||
<object class="GtkPopover" id="popover">
|
||||
|
|
|
@ -138,9 +138,9 @@ namespace Tootle {
|
|||
refresh ();
|
||||
}
|
||||
|
||||
private void switch_timeline_activated (SimpleAction a, Variant? parameter) {
|
||||
int32 timeline_no = parameter.get_int32 ();
|
||||
window.switch_timeline (timeline_no);
|
||||
private void switch_timeline_activated (SimpleAction a, Variant? v) {
|
||||
int32 num = v.get_int32 ();
|
||||
window.switch_timeline (num);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ public class Tootle.Desktop {
|
|||
}
|
||||
info ("OK");
|
||||
cb (file_path);
|
||||
|
||||
|
||||
} catch (Error e) {
|
||||
warning ("Error: %s\n", e.message);
|
||||
ecb (0, e.message);
|
||||
|
@ -68,9 +68,12 @@ public class Tootle.Desktop {
|
|||
.exec ();
|
||||
}
|
||||
|
||||
public static string fallback_icon (string normal, string fallback) {
|
||||
public static string fallback_icon (string normal, string fallback, string fallback2 = "broken") {
|
||||
var theme = Gtk.IconTheme.get_default ();
|
||||
return theme.has_icon (normal) ? normal : fallback;
|
||||
if (theme.has_icon (normal))
|
||||
return normal;
|
||||
else
|
||||
return theme.has_icon (fallback) ? fallback : fallback2;
|
||||
}
|
||||
|
||||
public static void set_hotkey_tooltip (Gtk.Widget widget, string? description, string[] accelerators) {
|
||||
|
|
|
@ -16,9 +16,11 @@ public class Tootle.Dialogs.MainWindow: Gtk.Window, ISavedWindow {
|
|||
[GtkChild]
|
||||
protected Button compose_button;
|
||||
[GtkChild]
|
||||
protected Granite.Widgets.ModeButton timeline_switcher;
|
||||
protected Hdy.ViewSwitcher timeline_switcher;
|
||||
[GtkChild]
|
||||
protected Widgets.AccountsButton accounts_button;
|
||||
|
||||
Views.Base? last_view = null;
|
||||
|
||||
construct {
|
||||
var provider = new Gtk.CssProvider ();
|
||||
|
@ -31,13 +33,14 @@ public class Tootle.Dialogs.MainWindow: Gtk.Window, ISavedWindow {
|
|||
compose_button.clicked.connect (() => new Dialogs.Compose ());
|
||||
Desktop.set_hotkey_tooltip (compose_button, _("Compose"), app.ACCEL_NEW_POST);
|
||||
|
||||
timeline_switcher.mode_changed.connect (on_mode_changed);
|
||||
timeline_switcher.stack = timeline_stack;
|
||||
timeline_switcher.valign = Align.FILL;
|
||||
timeline_stack.notify["visible-child"].connect (on_timeline_changed);
|
||||
|
||||
add_header_view (new Views.Home (), app.ACCEL_TIMELINE_0, 0);
|
||||
add_header_view (new Views.Notifications (), app.ACCEL_TIMELINE_1, 1);
|
||||
add_header_view (new Views.Local (), app.ACCEL_TIMELINE_2, 2);
|
||||
add_header_view (new Views.Federated (), app.ACCEL_TIMELINE_3, 3);
|
||||
timeline_switcher.set_active (0);
|
||||
add_timeline_view (new Views.Home (), app.ACCEL_TIMELINE_0, 0);
|
||||
add_timeline_view (new Views.Notifications (), app.ACCEL_TIMELINE_1, 1);
|
||||
add_timeline_view (new Views.Local (), app.ACCEL_TIMELINE_2, 2);
|
||||
add_timeline_view (new Views.Federated (), app.ACCEL_TIMELINE_3, 3);
|
||||
|
||||
button_press_event.connect (on_button_press);
|
||||
settings.changed.connect (update_theme);
|
||||
|
@ -47,25 +50,17 @@ public class Tootle.Dialogs.MainWindow: Gtk.Window, ISavedWindow {
|
|||
}
|
||||
|
||||
public MainWindow (Gtk.Application app) {
|
||||
Object (application: app, icon_name: Build.DOMAIN, resizable: true, window_position: WindowPosition.CENTER);
|
||||
Object (
|
||||
application: app,
|
||||
icon_name: Build.DOMAIN,
|
||||
resizable: true,
|
||||
window_position: WindowPosition.CENTER
|
||||
);
|
||||
|
||||
if (accounts.is_empty ())
|
||||
open_view (new Views.NewAccount (false));
|
||||
}
|
||||
|
||||
private bool on_button_press (EventButton ev) {
|
||||
if (ev.button == 8)
|
||||
return back ();
|
||||
return false;
|
||||
}
|
||||
|
||||
private void add_header_view (Views.Base view, string[] accelerators, int32 num) {
|
||||
var img = new Image.from_icon_name (view.get_icon (), IconSize.LARGE_TOOLBAR);
|
||||
Desktop.set_hotkey_tooltip (img, view.get_name (), accelerators);
|
||||
timeline_switcher.append (img);
|
||||
view.image = img;
|
||||
timeline_stack.add_named (view, num.to_string ());
|
||||
}
|
||||
|
||||
public int get_visible_id () {
|
||||
return int.parse (view_stack.get_visible_child_name ());
|
||||
}
|
||||
|
@ -110,15 +105,29 @@ public class Tootle.Dialogs.MainWindow: Gtk.Window, ISavedWindow {
|
|||
return false;
|
||||
}
|
||||
|
||||
public void switch_timeline (int32 timeline_no) {
|
||||
timeline_switcher.set_active (timeline_no);
|
||||
public void switch_timeline (int32 num) {
|
||||
timeline_stack.visible_child_name = num.to_string ();
|
||||
}
|
||||
|
||||
private void update_theme () {
|
||||
bool on_button_press (EventButton ev) {
|
||||
if (ev.button == 8)
|
||||
return back ();
|
||||
return false;
|
||||
}
|
||||
|
||||
void add_timeline_view (Views.Base view, string[] accelerators, int32 num) {
|
||||
timeline_stack.add_titled (view, num.to_string (), view.label);
|
||||
timeline_stack.child_set_property (view, "icon-name", view.icon);
|
||||
view.notify["needs-attention"].connect (() => {
|
||||
timeline_stack.child_set_property (view, "needs-attention", view.needs_attention);
|
||||
});
|
||||
}
|
||||
|
||||
void update_theme () {
|
||||
Gtk.Settings.get_default ().gtk_application_prefer_dark_theme = settings.dark_theme;
|
||||
}
|
||||
|
||||
private void update_header () {
|
||||
void update_header () {
|
||||
bool primary_mode = get_visible_id () == 0;
|
||||
timeline_switcher.sensitive = primary_mode;
|
||||
timeline_switcher.opacity = primary_mode ? 1 : 0; //Prevent HeaderBar height jitter
|
||||
|
@ -126,15 +135,16 @@ public class Tootle.Dialogs.MainWindow: Gtk.Window, ISavedWindow {
|
|||
back_button.visible = !primary_mode;
|
||||
}
|
||||
|
||||
private void on_mode_changed (Widget widget) {
|
||||
var visible = timeline_stack.get_visible_child () as Views.Base;
|
||||
visible.current = false;
|
||||
void on_timeline_changed (ParamSpec spec) {
|
||||
var view = timeline_stack.visible_child as Views.Base;
|
||||
|
||||
timeline_stack.set_visible_child_name (timeline_switcher.selected.to_string ());
|
||||
if (last_view != null)
|
||||
last_view.current = false;
|
||||
|
||||
visible = timeline_stack.get_visible_child () as Views.Base;
|
||||
visible.current = true;
|
||||
visible.on_set_current ();
|
||||
if (view != null) {
|
||||
view.current = true;
|
||||
last_view = view;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,9 +6,11 @@ public class Tootle.Views.Base : Box {
|
|||
public static string STATUS_EMPTY = _("Nothing to see here");
|
||||
public static string STATUS_LOADING = " ";
|
||||
|
||||
public bool current = false;
|
||||
public int stack_pos = -1;
|
||||
public Image? image;
|
||||
public int stack_pos { get; set; default = -1; }
|
||||
public string? icon { get; set; default = null; }
|
||||
public string label { get; set; default = ""; }
|
||||
public bool needs_attention { get; set; default = false; }
|
||||
public bool current { get; set; default = false; }
|
||||
|
||||
[GtkChild]
|
||||
protected ScrolledWindow scrolled;
|
||||
|
@ -19,11 +21,11 @@ public class Tootle.Views.Base : Box {
|
|||
[GtkChild]
|
||||
protected Box content;
|
||||
[GtkChild]
|
||||
private Label status_message_label;
|
||||
[GtkChild]
|
||||
protected Button status_button;
|
||||
[GtkChild]
|
||||
private Stack status_stack;
|
||||
Stack status_stack;
|
||||
[GtkChild]
|
||||
Label status_message_label;
|
||||
|
||||
public string state { get; set; default = "status"; }
|
||||
public string status_message { get; set; default = STATUS_EMPTY; }
|
||||
|
@ -48,14 +50,13 @@ public class Tootle.Views.Base : Box {
|
|||
status_message_label.label = @"<span size='large'>$status_message</span>";
|
||||
status_stack.visible_child_name = status_message == STATUS_LOADING ? "spinner" : "message";
|
||||
});
|
||||
}
|
||||
|
||||
public virtual string get_icon () {
|
||||
return "null";
|
||||
}
|
||||
|
||||
public virtual string get_name () {
|
||||
return "unnamed";
|
||||
notify["current"].connect (() => {
|
||||
if (current)
|
||||
on_shown ();
|
||||
else
|
||||
on_hidden ();
|
||||
});
|
||||
}
|
||||
|
||||
public virtual void clear (){
|
||||
|
@ -66,7 +67,8 @@ public class Tootle.Views.Base : Box {
|
|||
}
|
||||
|
||||
public virtual void on_bottom_reached () {}
|
||||
public virtual void on_set_current () {}
|
||||
public virtual void on_shown () {}
|
||||
public virtual void on_hidden () {}
|
||||
|
||||
public virtual void on_content_changed () {
|
||||
if (empty) {
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
public class Tootle.Views.Direct : Views.Timeline {
|
||||
|
||||
public Direct () {
|
||||
Object (timeline: "direct");
|
||||
}
|
||||
|
||||
public override string get_icon () {
|
||||
return "mail-send-symbolic";
|
||||
}
|
||||
|
||||
public override string get_name () {
|
||||
return _("Direct Messages");
|
||||
Object (
|
||||
timeline: "direct",
|
||||
label: _("Direct Messages"),
|
||||
icon: "mail-send-symbolic"
|
||||
);
|
||||
}
|
||||
|
||||
public override string? get_stream_url () {
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
public class Tootle.Views.Federated : Views.Timeline {
|
||||
|
||||
public Federated () {
|
||||
Object (timeline: "public", is_public: true);
|
||||
}
|
||||
|
||||
public override string get_icon () {
|
||||
return "network-workgroup-symbolic";
|
||||
}
|
||||
|
||||
public override string get_name () {
|
||||
return _("Federated Timeline");
|
||||
Object (
|
||||
timeline: "public",
|
||||
is_public: true,
|
||||
label: _("Federated"),
|
||||
icon: "network-workgroup-symbolic"
|
||||
);
|
||||
}
|
||||
|
||||
public override string? get_stream_url () {
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
public class Tootle.Views.Home : Views.Timeline {
|
||||
|
||||
public Home () {
|
||||
Object (timeline: "home");
|
||||
}
|
||||
|
||||
public override string get_icon () {
|
||||
return "user-home-symbolic";
|
||||
}
|
||||
|
||||
public override string get_name () {
|
||||
return _("Home");
|
||||
Object (
|
||||
timeline: "home",
|
||||
label: _("Home"),
|
||||
icon: "user-home-symbolic"
|
||||
);
|
||||
}
|
||||
|
||||
public override string? get_stream_url () {
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
public class Tootle.Views.Local : Views.Federated {
|
||||
|
||||
public override string get_icon () {
|
||||
return Desktop.fallback_icon ("system-users-symbolic", "document-open-recent-symbolic");
|
||||
}
|
||||
|
||||
public override string get_name () {
|
||||
return _("Local Timeline");
|
||||
public Local () {
|
||||
label = _("Local");
|
||||
icon = Desktop.fallback_icon ("system-users-symbolic", "document-open-recent-symbolic");
|
||||
}
|
||||
|
||||
public override Request append_params (Request req) {
|
||||
|
|
|
@ -4,30 +4,15 @@ using Gdk;
|
|||
public class Tootle.Views.Notifications : Views.Timeline, IAccountListener, IStreamListener {
|
||||
|
||||
protected int64 last_id = 0;
|
||||
protected bool force_dot = false;
|
||||
|
||||
public Notifications () {
|
||||
Object ();
|
||||
Object (
|
||||
label: _("Notifications"),
|
||||
icon: Desktop.fallback_icon ("notification-symbolic", "preferences-system-notifications-symbolic", "user-invisible-symbolic")
|
||||
);
|
||||
on_notification.connect (add_notification);
|
||||
}
|
||||
|
||||
public bool has_unread () {
|
||||
if (account == null)
|
||||
return false;
|
||||
return last_id > account.last_seen_notification || force_dot;
|
||||
}
|
||||
|
||||
public override string get_icon () {
|
||||
if (has_unread ())
|
||||
return Desktop.fallback_icon ("notification-new-symbolic", "user-available-symbolic");
|
||||
else
|
||||
return Desktop.fallback_icon ("notification-symbolic", "user-invisible-symbolic");
|
||||
}
|
||||
|
||||
public override string get_name () {
|
||||
return _("Notifications");
|
||||
}
|
||||
|
||||
public override string? get_stream_url () {
|
||||
return account != null ? @"$(account.instance)/api/v1/streaming/?stream=user&access_token=$(account.token)" : null;
|
||||
}
|
||||
|
@ -39,19 +24,12 @@ public class Tootle.Views.Notifications : Views.Timeline, IAccountListener, IStr
|
|||
return "/api/v1/notifications";
|
||||
}
|
||||
|
||||
public override void on_content_changed () {
|
||||
base.on_content_changed ();
|
||||
if (image != null && empty)
|
||||
image.icon_name = get_icon ();
|
||||
}
|
||||
|
||||
public override void on_set_current () {
|
||||
public override void on_shown () {
|
||||
if (has_unread ()) {
|
||||
force_dot = false;
|
||||
account.has_unread_notifications = force_dot;
|
||||
needs_attention = false;
|
||||
account.has_unread_notifications = false;
|
||||
account.last_seen_notification = last_id;
|
||||
accounts.save ();
|
||||
image.icon_name = get_icon ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,17 +39,15 @@ public class Tootle.Views.Notifications : Views.Timeline, IAccountListener, IStr
|
|||
var notification = nw.notification;
|
||||
|
||||
if (reverse && !current) {
|
||||
force_dot = true;
|
||||
accounts.active.has_unread_notifications = force_dot;
|
||||
needs_attention = accounts.active.has_unread_notifications = true;
|
||||
}
|
||||
|
||||
if (notification.id > last_id)
|
||||
last_id = notification.id;
|
||||
|
||||
if (has_unread ()) {
|
||||
needs_attention = has_unread ();
|
||||
if (needs_attention)
|
||||
accounts.save ();
|
||||
image.icon_name = get_icon ();
|
||||
}
|
||||
}
|
||||
|
||||
public override GLib.Object? to_entity (Json.Object? json) {
|
||||
|
@ -94,11 +70,11 @@ public class Tootle.Views.Notifications : Views.Timeline, IAccountListener, IStr
|
|||
base.on_account_changed (acc);
|
||||
if (account == null) {
|
||||
last_id = 0;
|
||||
force_dot = false;
|
||||
needs_attention = false;
|
||||
}
|
||||
else {
|
||||
last_id = account.last_seen_notification;
|
||||
force_dot = account.has_unread_notifications;
|
||||
needs_attention = account.has_unread_notifications;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +88,13 @@ public class Tootle.Views.Notifications : Views.Timeline, IAccountListener, IStr
|
|||
return base.request ();
|
||||
}
|
||||
|
||||
protected virtual void add_notification (API.Notification n) {
|
||||
bool has_unread () {
|
||||
if (account == null)
|
||||
return false;
|
||||
return last_id > account.last_seen_notification || needs_attention;
|
||||
}
|
||||
|
||||
void add_notification (API.Notification n) {
|
||||
prepend (widgetize (n));
|
||||
}
|
||||
|
||||
|
|
|
@ -25,14 +25,6 @@ public class Tootle.Views.Timeline : IAccountListener, IStreamListener, Views.Ba
|
|||
streams.unsubscribe (stream, this);
|
||||
}
|
||||
|
||||
public override string get_icon () {
|
||||
return "user-home-symbolic";
|
||||
}
|
||||
|
||||
public override string get_name () {
|
||||
return _("Home");
|
||||
}
|
||||
|
||||
public virtual bool is_status_owned (API.Status status) {
|
||||
return status.is_owned ();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue