[geary] Support different modes for the inline composer



commit 3c9ab2bd7920aefe2f5d18732ff60bb29c58ad0e
Author: Robert Schroll <rschroll gmail com>
Date:   Fri May 16 14:55:47 2014 -0700

    Support different modes for the inline composer
    
    INLINE_NEW: New message, taking up the full view
    INLINE: Reply or forward, with editable recipients
    INLINE_COMPACT: Reply, without editable recipients
    
    Note that the only allowed paths are
      INLINE_COMPACT -> INLINE -> DETACHED
      INLINE_NEW -> DETACHED

 src/client/application/geary-controller.vala |    7 ++-
 src/client/composer/composer-embed.vala      |    4 +-
 src/client/composer/composer-widget.vala     |   65 ++++++++++++++++++++-----
 ui/composer.glade                            |   34 ++++++++++++--
 4 files changed, 88 insertions(+), 22 deletions(-)
---
diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala
index df44d3a..83a96d0 100644
--- a/src/client/application/geary-controller.vala
+++ b/src/client/application/geary-controller.vala
@@ -1850,7 +1850,8 @@ public class GearyController : Geary.BaseObject {
         Geary.Email? referred = null) {
         if (compose_type != ComposerWidget.ComposeType.NEW_MESSAGE) {
             foreach (ComposerWidget cw in composer_widgets) {
-                if (cw.inline && referred != null && referred.id.equal_to(cw.referred_id)) {
+                if (cw.state != ComposerWidget.ComposerState.DETACHED &&
+                    referred != null && referred.id.equal_to(cw.referred_id)) {
                     cw.change_compose_type(compose_type);
                     return false;
                 }
@@ -1871,7 +1872,7 @@ public class GearyController : Geary.BaseObject {
         if (response == Gtk.ResponseType.OK) {
             Gee.List<ComposerWidget> composers_to_destroy = new Gee.ArrayList<ComposerWidget>();
             foreach (ComposerWidget cw in composer_widgets) {
-                if (cw.inline)
+                if (cw.state != ComposerWidget.ComposerState.DETACHED)
                     composers_to_destroy.add(cw);
             }
             foreach(ComposerWidget cw in composers_to_destroy)
@@ -1883,7 +1884,7 @@ public class GearyController : Geary.BaseObject {
     
     public bool any_inline_composers() {
         foreach (ComposerWidget cw in composer_widgets)
-            if (cw.inline)
+            if (cw.state != ComposerWidget.ComposerState.DETACHED)
                 return true;
         return false;
     }
diff --git a/src/client/composer/composer-embed.vala b/src/client/composer/composer-embed.vala
index 7b1ec02..d6da7f1 100644
--- a/src/client/composer/composer-embed.vala
+++ b/src/client/composer/composer-embed.vala
@@ -58,7 +58,7 @@ public class ComposerEmbed : Gtk.Bin, ComposerContainer {
     }
     
     public void on_detach() {
-        composer.inline = composer.inline_reply = false;
+        composer.state = ComposerWidget.ComposerState.DETACHED;
         if (composer.editor.has_focus)
             on_focus_out();
         composer.editor.focus_in_event.disconnect(on_focus_in);
@@ -110,7 +110,7 @@ public class ComposerEmbed : Gtk.Bin, ComposerContainer {
     
     public void vanish() {
         hide();
-        composer.inline = composer.inline_reply = false;
+        composer.state = ComposerWidget.ComposerState.DETACHED;
         composer.editor.focus_in_event.disconnect(on_focus_in);
         composer.editor.focus_out_event.disconnect(on_focus_out);
         
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index 76c60b1..145e5d5 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -19,6 +19,13 @@ public class ComposerWidget : Gtk.EventBox {
         CANCEL_CLOSE
     }
     
+    public enum ComposerState {
+        DETACHED,
+        INLINE_NEW,
+        INLINE,
+        INLINE_COMPACT
+    }
+    
     public const string ACTION_UNDO = "undo";
     public const string ACTION_REDO = "redo";
     public const string ACTION_CUT = "cut";
@@ -134,8 +141,7 @@ public class ComposerWidget : Gtk.EventBox {
         set { ((Gtk.ToggleAction) actions.get_action(ACTION_COMPOSE_AS_HTML)).active = value; }
     }
     
-    public bool inline { get; set; default = true; }
-    public bool inline_reply { get; set; }
+    public ComposerState state { get; set; }
     
     public ComposeType compose_type { get; private set; default = ComposeType.NEW_MESSAGE; }
     
@@ -168,7 +174,7 @@ public class ComposerWidget : Gtk.EventBox {
     private Gtk.Alignment visible_on_attachment_drag_over;
     private Gtk.Widget hidden_on_attachment_drag_over_child;
     private Gtk.Widget visible_on_attachment_drag_over_child;
-    private Gtk.Label compact_header;
+    private Gtk.Label compact_header_label;
     private Gtk.Label draft_save_label;
     
     private Gtk.Menu menu = new Gtk.Menu();
@@ -208,6 +214,12 @@ public class ComposerWidget : Gtk.EventBox {
         Geary.Email? referred = null, bool is_referred_draft = false) {
         this.account = account;
         this.compose_type = compose_type;
+        if (compose_type == ComposeType.NEW_MESSAGE)
+            state = ComposerState.INLINE_NEW;
+        else if (compose_type == ComposeType.FORWARD)
+            state = ComposerState.INLINE;
+        else
+            state = ComposerState.INLINE_COMPACT;
         
         setup_drag_destination(this);
         
@@ -225,8 +237,11 @@ public class ComposerWidget : Gtk.EventBox {
         send_button.clicked.connect(on_send);
         detach_button = builder.get_object("Detach") as Gtk.Button;
         detach_button.clicked.connect(on_detach);
-        bind_property("inline", detach_button, "visible",
-            BindingFlags.DEFAULT | BindingFlags.SYNC_CREATE);
+        bind_property("state", detach_button, "visible", BindingFlags.SYNC_CREATE,
+            (binding, source_value, ref target_value) => {
+                target_value = (state != ComposerState.DETACHED);
+                return true;
+            });
         add_attachment_button  = builder.get_object("add_attachment_button") as Gtk.Button;
         add_attachment_button.clicked.connect(on_add_attachment_button_clicked);
         pending_attachments_button = builder.get_object("add_pending_attachments") as Gtk.Button;
@@ -240,14 +255,33 @@ public class ComposerWidget : Gtk.EventBox {
         visible_on_attachment_drag_over.remove(visible_on_attachment_drag_over_child);
         
         Gtk.Widget recipients = builder.get_object("recipients") as Gtk.Widget;
-        bind_property("inline-reply", recipients, "visible",
-            BindingFlags.INVERT_BOOLEAN | BindingFlags.SYNC_CREATE);
-        compact_header = builder.get_object("compact_recipients") as Gtk.Label;
-        bind_property("inline-reply", compact_header, "visible",
-            BindingFlags.SYNC_CREATE);
+        bind_property("state", recipients, "visible", BindingFlags.SYNC_CREATE,
+            (binding, source_value, ref target_value) => {
+                target_value = (state != ComposerState.INLINE_COMPACT);
+                return true;
+            });
+        Gtk.Widget compact_header = builder.get_object("compact_recipients") as Gtk.Widget;
+        bind_property("state", compact_header, "visible", BindingFlags.SYNC_CREATE,
+            (binding, source_value, ref target_value) => {
+                target_value = (state == ComposerState.INLINE_COMPACT);
+                return true;
+            });
+        string[] subject_elements = {"subject label", "subject"};
+        foreach (string name in subject_elements) {
+            Gtk.Widget widget = builder.get_object(name) as Gtk.Widget;
+            bind_property("state", widget, "visible", BindingFlags.SYNC_CREATE,
+                (binding, source_value, ref target_value) => {
+                    target_value = (state != ComposerState.INLINE);
+                    return true;
+                });
+        }
+        notify["state"].connect((s, p) => { update_from_field(); });
+        compact_header_label = builder.get_object("compact_recipients_label") as Gtk.Label;
+        Gtk.Button expand_button = builder.get_object("expand_button") as Gtk.Button;
+        expand_button.clicked.connect(() => { state = ComposerState.INLINE; });
         // Set the visibilities later, after show_all is called on the widget.
         Idle.add(() => {
-            inline_reply = (compose_type != ComposeType.NEW_MESSAGE);
+            state = state;  // Triggers visibilities
             show_attachments();
             return false;
         });
@@ -1105,8 +1139,9 @@ public class ComposerWidget : Gtk.EventBox {
             && (!to_entry.empty || !cc_entry.empty || !bcc_entry.empty);
         bool tocc = !to_entry.empty && !cc_entry.empty,
             ccbcc = !(to_entry.empty && cc_entry.empty) && !bcc_entry.empty;
-        compact_header.label = _("To: ") + to_entry.buffer.text + (tocc ? ", " : "")
-            + cc_entry.buffer.text + (ccbcc ? ", " : "") + bcc_entry.buffer.text;
+        if (state == ComposerState.INLINE_COMPACT)
+            compact_header_label.label = to_entry.buffer.text + (tocc ? ", " : "")
+                + cc_entry.buffer.text + (ccbcc ? ", " : "") + bcc_entry.buffer.text;
         
         reset_draft_timer();
     }
@@ -1705,6 +1740,10 @@ public class ComposerWidget : Gtk.EventBox {
             return;
         }
         
+        // Don't show in inline or compact modes.
+        if (state == ComposerState.INLINE || state == ComposerState.INLINE_COMPACT)
+            return;
+        
         // If there's only one account, show nothing. (From fields are hidden above.)
         if (accounts.size <= 1)
             return;
diff --git a/ui/composer.glade b/ui/composer.glade
index 1f4e4fe..b40c7f9 100644
--- a/ui/composer.glade
+++ b/ui/composer.glade
@@ -197,15 +197,41 @@
             <property name="orientation">vertical</property>
             <property name="spacing">6</property>
             <child>
-              <object class="GtkLabel" id="compact_recipients">
+              <object class="GtkBox" id="compact_recipients">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
                 <property name="margin_left">6</property>
                 <property name="margin_right">6</property>
                 <property name="margin_top">6</property>
-                <property name="xalign">0</property>
-                <property name="label" translatable="yes">You're sending an email!</property>
-                <property name="ellipsize">end</property>
+                <property name="resize_mode">queue</property>
+                <child>
+                  <object class="GtkButton" id="expand_button">
+                    <property name="label" translatable="yes">@</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="tooltip_text" translatable="yes">Edit Recipients</property>
+                    <property name="margin_right">6</property>
+                    <property name="xalign">0.54000002145767212</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="compact_recipients_label">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">label</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
               </object>
               <packing>
                 <property name="expand">False</property>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]