[gnome-todo] task-row: introduce inline editing



commit c4912d88fefc4e25e08a2fabf7d7e4c31c3e45fd
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Thu Sep 21 22:38:41 2017 -0300

    task-row: introduce inline editing
    
    The previous way to edit task details was clumsy and
    didn't really make sense. Thanks to our great contributor
    Tobias Bernard, who shared their vision about inline
    editing of tasks and how it should work, we now have
    a super great way to edit tasks.
    
    And it's looking so awsome!

 data/theme/Adwaita.css                        |   19 +-
 data/ui/edit-pane.ui                          |  472 ++++++++++++-------------
 data/ui/list-view.ui                          |   22 +--
 data/ui/new-task-row.ui                       |    1 +
 data/ui/task-row.ui                           |  153 +++++----
 plugins/scheduled-panel/gtd-panel-scheduled.c |    1 -
 src/gtd-edit-pane.c                           |  110 +++----
 src/gtd-task-list-view.c                      |  134 ++------
 src/gtd-task-row.c                            |  221 ++++++++----
 9 files changed, 542 insertions(+), 591 deletions(-)
---
diff --git a/data/theme/Adwaita.css b/data/theme/Adwaita.css
index 37219e3..5f06054 100644
--- a/data/theme/Adwaita.css
+++ b/data/theme/Adwaita.css
@@ -60,6 +60,7 @@ taskrow {
     border-radius: 2px;
     background-color: @theme_base_color;
     box-shadow: 0 0 2px alpha(black, 0.33);
+    min-height: 2.7rem;
 }
 
 taskrow:dir(ltr) { padding-left: 6px;  }
@@ -67,17 +68,16 @@ taskrow:dir(rtl) { padding-right: 6px; }
 
 taskrow entry {
     padding: 6px;
-    border-top: none;
-    border-bottom: none;
+    border: none;
 }
 
-taskrow.priority-low:dir(ltr)    { border-left: solid 6px #3465a4;  padding-left: 0;  }
+taskrow.priority-low:dir(ltr)    { border-left:  solid 6px #3465a4; padding-left:  0; }
 taskrow.priority-low:dir(rtl)    { border-right: solid 6px #3465a4; padding-right: 0; }
 
-taskrow.priority-medium:dir(ltr) { border-left: solid 6px #f57900;  padding-left: 0;  }
+taskrow.priority-medium:dir(ltr) { border-left:  solid 6px #f57900; padding-left:  0; }
 taskrow.priority-medium:dir(rtl) { border-right: solid 6px #f57900; padding-right: 0; }
 
-taskrow.priority-hight:dir(ltr)  { border-left: solid 6px #cc0000;  padding-left: 0;  }
+taskrow.priority-hight:dir(ltr)  { border-left:  solid 6px #cc0000; padding-left:  0; }
 taskrow.priority-hight:dir(rtl)  { border-right: solid 6px #cc0000; padding-right: 0; }
 
 taskrow.complete label { text-decoration-line: line-through; }
@@ -102,3 +102,12 @@ list.extension-list row {
 button.circle {
     border-radius: 20px;
 }
+
+/*
+ * Edit Pane
+ */
+
+editpane entry.title {
+    font-size: 1.1rem;
+    font-weight: bold;
+}
diff --git a/data/ui/edit-pane.ui b/data/ui/edit-pane.ui
index 92de3c7..e03a1fb 100644
--- a/data/ui/edit-pane.ui
+++ b/data/ui/edit-pane.ui
@@ -16,7 +16,7 @@
             <property name="visible">True</property>
             <property name="can_focus">True</property>
             <property name="show_week_numbers">True</property>
-            <signal name="day-selected" handler="gtd_edit_pane__date_selected" object="GtdEditPane" 
swapped="no"/>
+            <signal name="day-selected" handler="date_selected_cb" object="GtdEditPane" swapped="no"/>
           </object>
         </child>
         <child>
@@ -38,301 +38,271 @@
     <property name="row_spacing">12</property>
     <property name="column_spacing">12</property>
     <child>
-      <object class="GtkScrolledWindow" id="scrolled_window">
+      <object class="GtkGrid" id="main_grid">
         <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="hexpand">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin">6</property>
+        <property name="margin-top">12</property>
+        <property name="margin-bottom">12</property>
         <property name="vexpand">True</property>
-        <property name="hscrollbar_policy">never</property>
+        <property name="row_spacing">6</property>
+        <property name="column_spacing">6</property>
+        <child>
+          <object class="GtkButton" id="close_button">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">False</property>
+            <property name="relief">none</property>
+            <signal name="clicked" handler="close_button_clicked_cb" object="GtdEditPane" swapped="no"/>
+            <child>
+              <object class="GtkImage">
+                <property name="visible">True</property>
+                <property name="can-focus">False</property>
+                <property name="icon-name">window-close-symbolic</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">1</property>
+            <property name="top_attach">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkEntry" id="title_entry">
+            <property name="visible">True</property>
+            <property name="hexpand">True</property>
+            <property name="has-frame">False</property>
+            <style>
+              <class name="flat" />
+              <class name="title" />
+            </style>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">0</property>
+          </packing>
+        </child>
         <child>
-          <object class="GtkViewport" id="viewport">
+          <object class="GtkSeparator" id="separator">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="shadow_type">none</property>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">1</property>
+            <property name="width">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkGrid" id="grid">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="vexpand">True</property>
+            <property name="row_spacing">12</property>
             <child>
-              <object class="GtkGrid" id="main_grid">
+              <object class="GtkLabel" id="notes_dim_label">
+                <property name="label" translatable="yes">_Notes</property>
+                <property name="use_underline">True</property>
+                <property name="mnemonic_widget">notes_textview</property>
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="margin_top">6</property>
-                <property name="margin_bottom">12</property>
-                <property name="vexpand">True</property>
-                <property name="row_spacing">6</property>
-                <property name="column_spacing">12</property>
+                <property name="xalign">0</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">0</property>
+                <property name="width">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkScrolledWindow" id="notes_scrolled_window">
+                <property name="visible">True</property>
+                <property name="can-focus">True</property>
+                <property name="shadow-type">in</property>
+                <property name="min-content-height">150</property>
+                <property name="max-content-height">400</property>
                 <child>
-                  <object class="GtkButton" id="close_button">
+                  <object class="GtkTextView" id="notes_textview">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="margin_start">12</property>
-                    <property name="margin_end">12</property>
-                    <property name="relief">none</property>
-                    <signal name="clicked" handler="gtd_edit_pane__close_button_clicked" 
object="GtdEditPane" swapped="no"/>
-                    <child>
-                      <object class="GtkImage" id="close_button_image">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="icon_name">window-close-symbolic</property>
-                      </object>
-                    </child>
-                    <style>
-                      <class name="image-button"/>
-                      <class name="flat"/>
-                    </style>
+                    <property name="accepts_tab">False</property>
+                    <property name="left-margin">6</property>
+                    <property name="right-margin">6</property>
+                    <property name="pixels-above-lines">6</property>
+                    <property name="wrap-mode">word-char</property>
                   </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="top_attach">0</property>
-                  </packing>
                 </child>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">1</property>
+                <property name="width">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="due_date_dim_label">
+                <property name="label" translatable="yes">D_ue Date</property>
+                <property name="use_underline">True</property>
+                <property name="mnemonic_widget">date_button</property>
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">2</property>
+                <property name="width">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="priority_dim_label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">_Priority</property>
+                <property name="use_underline">True</property>
+                <property name="mnemonic_widget">priority_combo</property>
+                <property name="xalign">0</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">4</property>
+                <property name="width">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkComboBoxText" id="priority_combo">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="active">0</property>
+                <items>
+                  <item translatable="yes" context="taskpriority">None</item>
+                  <item translatable="yes">Low</item>
+                  <item translatable="yes">Medium</item>
+                  <item translatable="yes">High</item>
+                </items>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">5</property>
+                <property name="width">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="remove_button">
+                <property name="label" translatable="yes">_Delete</property>
+                <property name="use_underline">True</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">start</property>
+                <signal name="clicked" handler="gtd_edit_pane__delete_button_clicked" object="GtdEditPane" 
swapped="no" />
+                <style>
+                  <class name="destructive-action"/>
+                </style>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">6</property>
+                <property name="width">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkBox" id="date_select_box">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
                 <child>
-                  <object class="GtkLabel" id="details_label">
+                  <object class="GtkButton" id="gtd_set_date_today">
+                    <property name="label" translatable="yes">_Today</property>
+                    <property name="use_underline">True</property>
                     <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="margin_start">12</property>
-                    <property name="margin_end">12</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
                     <property name="hexpand">True</property>
-                    <property name="label" translatable="yes">Details</property>
-                    <property name="xalign">0</property>
-                    <attributes>
-                      <attribute name="weight" value="bold"/>
-                    </attributes>
+                    <signal name="clicked" handler="today_button_clicked" object="GtdEditPane" swapped="no" 
/>
                   </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">0</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkSeparator" id="separator">
+                  <object class="GtkButton" id="tomorrow_button">
+                    <property name="label" translatable="yes">To_morrow</property>
+                    <property name="use_underline">True</property>
                     <property name="visible">True</property>
-                    <property name="can_focus">False</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="hexpand">True</property>
+                    <signal name="clicked" handler="tomorrow_button_clicked" object="GtdEditPane" 
swapped="no"/>
                   </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">1</property>
-                    <property name="width">2</property>
-                  </packing>
                 </child>
                 <child>
-                  <object class="GtkGrid" id="grid">
+                  <object class="GtkButton" id="next_week_button">
+                    <property name="label" translatable="yes">Next _Week</property>
+                    <property name="use_underline">True</property>
                     <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="vexpand">True</property>
-                    <property name="border_width">12</property>
-                    <property name="row_spacing">12</property>
-                    <child>
-                      <object class="GtkLabel" id="notes_dim_label">
-                        <property name="label" translatable="yes">_Notes</property>
-                        <property name="use_underline">True</property>
-                        <property name="mnemonic_widget">notes_textview</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="xalign">0</property>
-                        <style>
-                          <class name="dim-label"/>
-                        </style>
-                      </object>
-                      <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">0</property>
-                        <property name="width">2</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkScrolledWindow" id="notes_scrolled_window">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="shadow_type">in</property>
-                        <property name="min_content_width">325</property>
-                        <property name="min_content_height">225</property>
-                        <child>
-                          <object class="GtkTextView" id="notes_textview">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="accepts_tab">False</property>
-                            <property name="left-margin">6</property>
-                            <property name="right-margin">6</property>
-                            <property name="pixels-above-lines">6</property>
-                            <property name="wrap-mode">word-char</property>
-                          </object>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">1</property>
-                        <property name="width">2</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="due_date_dim_label">
-                        <property name="label" translatable="yes">D_ue Date</property>
-                        <property name="use_underline">True</property>
-                        <property name="mnemonic_widget">date_button</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="xalign">0</property>
-                        <style>
-                          <class name="dim-label"/>
-                        </style>
-                      </object>
-                      <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">2</property>
-                        <property name="width">2</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="priority_dim_label">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">_Priority</property>
-                        <property name="use_underline">True</property>
-                        <property name="mnemonic_widget">priority_combo</property>
-                        <property name="xalign">0</property>
-                        <style>
-                          <class name="dim-label"/>
-                        </style>
-                      </object>
-                      <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">4</property>
-                        <property name="width">2</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkComboBoxText" id="priority_combo">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="active">0</property>
-                        <items>
-                          <item translatable="yes" context="taskpriority">None</item>
-                          <item translatable="yes">Low</item>
-                          <item translatable="yes">Medium</item>
-                          <item translatable="yes">High</item>
-                        </items>
-                      </object>
-                      <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">5</property>
-                        <property name="width">2</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkButton" id="remove_button">
-                        <property name="label" translatable="yes">_Delete</property>
-                        <property name="use_underline">True</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
-                        <property name="valign">end</property>
-                        <property name="vexpand">True</property>
-                        <signal name="clicked" handler="gtd_edit_pane__delete_button_clicked" 
object="GtdEditPane" swapped="no" />
-                        <style>
-                          <class name="destructive-action"/>
-                        </style>
-                      </object>
-                      <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">6</property>
-                        <property name="width">2</property>
-                      </packing>
-                    </child>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="hexpand">True</property>
+                    <signal name="clicked" handler="next_week_button_clicked" object="GtdEditPane" 
swapped="no"/>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkMenuButton" id="date_button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="hexpand">True</property>
+                    <property name="popover">date_popover</property>
                     <child>
-                      <object class="GtkBox" id="date_select_box">
+                      <object class="GtkBox" id="date_button_box">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
+                        <property name="spacing">7</property>
                         <child>
-                          <object class="GtkButton" id="gtd_set_date_today">
-                            <property name="label" translatable="yes">_Today</property>
-                            <property name="use_underline">True</property>
+                          <object class="GtkLabel" id="date_label">
                             <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="receives_default">True</property>
+                            <property name="can_focus">False</property>
                             <property name="hexpand">True</property>
-                            <signal name="clicked" handler="today_button_clicked" object="GtdEditPane" 
swapped="no" />
+                            <property name="width-chars">10</property>
                           </object>
                         </child>
                         <child>
-                          <object class="GtkButton" id="tomorrow_button">
-                            <property name="label" translatable="yes">To_morrow</property>
-                            <property name="use_underline">True</property>
+                          <object class="GtkImage" id="date_button_image">
                             <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="receives_default">True</property>
-                            <property name="hexpand">True</property>
-                            <signal name="clicked" handler="tomorrow_button_clicked" object="GtdEditPane" 
swapped="no"/>
+                            <property name="can_focus">False</property>
+                            <property name="icon_name">pan-down-symbolic</property>
                           </object>
                         </child>
-                        <child>
-                          <object class="GtkButton" id="next_week_button">
-                            <property name="label" translatable="yes">Next _Week</property>
-                            <property name="use_underline">True</property>
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="receives_default">True</property>
-                            <property name="hexpand">True</property>
-                            <signal name="clicked" handler="next_week_button_clicked" object="GtdEditPane" 
swapped="no"/>
-                          </object>
-                        </child>
-                        <child>
-                          <object class="GtkMenuButton" id="date_button">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="receives_default">True</property>
-                            <property name="hexpand">True</property>
-                            <property name="popover">date_popover</property>
-                            <child>
-                              <object class="GtkBox" id="date_button_box">
-                                <property name="visible">True</property>
-                                <property name="can_focus">False</property>
-                                <property name="spacing">7</property>
-                                <child>
-                                  <object class="GtkLabel" id="date_label">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">False</property>
-                                    <property name="hexpand">True</property>
-                                    <property name="width-chars">10</property>
-                                  </object>
-                                </child>
-                                <child>
-                                  <object class="GtkImage" id="date_button_image">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">False</property>
-                                    <property name="icon_name">pan-down-symbolic</property>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
-                        <style>
-                          <class name="linked"/>
-                        </style>
                       </object>
-                      <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">3</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <placeholder/>
                     </child>
                   </object>
-                  <packing>
-                    <property name="left_attach">0</property>
-                    <property name="top_attach">2</property>
-                    <property name="width">2</property>
-                  </packing>
                 </child>
+                <style>
+                  <class name="linked"/>
+                </style>
               </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">3</property>
+              </packing>
+            </child>
+            <child>
+              <placeholder/>
             </child>
           </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">2</property>
+            <property name="width">2</property>
+          </packing>
         </child>
       </object>
-      <packing>
-        <property name="left_attach">0</property>
-        <property name="top_attach">0</property>
-      </packing>
     </child>
   </template>
 </interface>
diff --git a/data/ui/list-view.ui b/data/ui/list-view.ui
index d34a7ac..be4d91e 100644
--- a/data/ui/list-view.ui
+++ b/data/ui/list-view.ui
@@ -46,7 +46,7 @@
                         <child>
                           <object class="GtdNewTaskRow" id="new_task_row">
                             <property name="visible">True</property>
-                            <signal name="create-task" handler="gtd_task_list_view__create_task" 
object="GtdTaskListView" swapped="no" />
+                            <signal name="create-task" handler="create_task_cb" object="GtdTaskListView" 
swapped="no" />
                             <signal name="enter" handler="task_row_entered_cb" object="GtdTaskListView" 
swapped="yes" />
                             <signal name="exit" handler="task_row_exited_cb" object="GtdTaskListView" 
swapped="yes" />
                           </object>
@@ -167,26 +167,6 @@
         </child>
       </object>
     </child>
-    <child type="overlay">
-      <object class="GtkRevealer" id="edit_revealer">
-        <property name="visible">True</property>
-        <property name="halign">end</property>
-        <property name="transition_type">slide-left</property>
-        <property name="transition_duration">150</property>
-        <child>
-          <object class="GtdArrowFrame" id="arrow_frame">
-            <property name="visible">True</property>
-            <child>
-              <object class="GtdEditPane" id="edit_pane">
-                <property name="visible">True</property>
-                <signal name="edit-finished" handler="gtd_task_list_view__edit_task_finished" 
object="GtdTaskListView" swapped="no" />
-                <signal name="remove-task" handler="gtd_task_list_view__remove_task_cb" 
object="GtdTaskListView" swapped="no" />
-              </object>
-            </child>
-          </object>
-        </child>
-      </object>
-    </child>
   </template>
   <object class="GtkSizeGroup" id="tasklist_name_sizegroup">
     <property name="mode">horizontal</property>
diff --git a/data/ui/new-task-row.ui b/data/ui/new-task-row.ui
index 8a51d8d..4f4e03e 100644
--- a/data/ui/new-task-row.ui
+++ b/data/ui/new-task-row.ui
@@ -41,6 +41,7 @@
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="hexpand">True</property>
+                <property name="has-frame">False</property>
                 <property name="placeholder-text" translatable="yes">New taskā€¦</property>
                 <signal name="activate" handler="entry_activated_cb" object="GtdNewTaskRow" swapped="yes" />
                 <style>
diff --git a/data/ui/task-row.ui b/data/ui/task-row.ui
index 2555025..76b10ef 100644
--- a/data/ui/task-row.ui
+++ b/data/ui/task-row.ui
@@ -3,7 +3,6 @@
   <requires lib="gtk+" version="3.16"/>
   <template class="GtdTaskRow" parent="GtkListBoxRow">
     <property name="visible">True</property>
-    <property name="can_focus">True</property>
     <property name="activatable">True</property>
     <property name="selectable">False</property>
     <property name="margin">3</property>
@@ -13,91 +12,125 @@
         <property name="can_focus">False</property>
         <property name="transition_type">slide-down</property>
         <property name="transition_duration">200</property>
+
         <child>
-          <object class="GtkBox">
+          <object class="GtkStack" id="stack">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="margin-end">12</property>
             <property name="margin-start">12</property>
             <property name="margin-top">3</property>
             <property name="margin-bottom">3</property>
-            <property name="spacing">6</property>
+            <property name="interpolate-size">True</property>
+            <property name="homogeneous">False</property>
+            <property name="transition-type">slide-up-down</property>
+            <property name="transition-duration">500</property>
 
-            <!-- Box with DnD margin -->
+            <!-- Main page, visible when the task row is unfocused -->
             <child>
-              <object class="GtkBox" id="dnd_box">
+              <object class="GtkBox">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-              </object>
-            </child>
+                <property name="spacing">6</property>
+
+                <!-- Box with DnD margin -->
+                <child>
+                  <object class="GtkBox" id="dnd_box">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                  </object>
+                </child>
+
+                <child>
+                  <object class="GtkEventBox" id="dnd_event_box">
+                    <property name="visible">True</property>
+                    <signal name="button-press-event" handler="button_press_event" object="GtdTaskRow" 
swapped="no" />
+                    <signal name="drag-begin" handler="drag_begin_cb" object="GtdTaskRow" swapped="no" />
+                    <signal name="drag-failed" handler="drag_failed_cb" object="GtdTaskRow" swapped="no" />
+                    <signal name="enter-notify-event" handler="mouse_over_event" object="GtdTaskRow" 
swapped="no" />
+                    <signal name="leave-notify-event" handler="mouse_out_event" object="GtdTaskRow" 
swapped="no" />
+                    <child>
+                      <object class="GtkImage" id="dnd_icon">
+                        <property name="visible">True</property>
+                        <property name="icon-name">open-menu-symbolic</property>
+                        <property name="pixel-size">12</property>
+                        <style>
+                          <class name="dim-label" />
+                        </style>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+
+                <child>
+                  <object class="GtkCheckButton" id="done_check">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="halign">center</property>
+                    <property name="valign">center</property>
+                    <property name="vexpand">True</property>
+                    <property name="draw_indicator">True</property>
+                    <property name="margin-start">6</property>
+                    <signal name="toggled" handler="complete_check_toggled_cb" object="GtdTaskRow" 
swapped="no" />
+                  </object>
+                </child>
 
-            <child>
-              <object class="GtkEventBox" id="dnd_event_box">
-                <property name="visible">True</property>
-                <signal name="button-press-event" handler="button_press_event" object="GtdTaskRow" 
swapped="no" />
-                <signal name="drag-begin" handler="drag_begin_cb" object="GtdTaskRow" swapped="no" />
-                <signal name="drag-failed" handler="drag_failed_cb" object="GtdTaskRow" swapped="no" />
-                <signal name="enter-notify-event" handler="mouse_over_event" object="GtdTaskRow" 
swapped="no" />
-                <signal name="leave-notify-event" handler="mouse_out_event" object="GtdTaskRow" swapped="no" 
/>
                 <child>
-                  <object class="GtkImage" id="dnd_icon">
+                  <object class="GtkLabel" id="title_label">
                     <property name="visible">True</property>
-                    <property name="icon-name">open-menu-symbolic</property>
-                    <property name="pixel-size">12</property>
+                    <property name="can_focus">True</property>
+                    <property name="hexpand">True</property>
+                    <property name="xalign">0.0</property>
+                  </object>
+                </child>
+
+                <child>
+                  <object class="GtkLabel" id="task_date_label">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">0</property>
                     <style>
-                      <class name="dim-label" />
+                      <class name="dim-label"/>
+                    </style>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="task_list_label">
+                    <property name="visible">False</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">0</property>
+                    <property name="max_width_chars">18</property>
+                    <property name="ellipsize">middle</property>
+                    <style>
+                      <class name="dim-label"/>
                     </style>
                   </object>
                 </child>
-              </object>
-            </child>
-
-            <child>
-              <object class="GtkCheckButton" id="done_check">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="halign">center</property>
-                <property name="valign">center</property>
-                <property name="vexpand">True</property>
-                <property name="draw_indicator">True</property>
-                <property name="margin-start">6</property>
-                <signal name="toggled" handler="complete_check_toggled_cb" object="GtdTaskRow" swapped="no" 
/>
-              </object>
-            </child>
 
-            <child>
-              <object class="GtkEntry" id="title_entry">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="hexpand">True</property>
-                <style>
-                  <class name="flat" />
-                </style>
               </object>
+              <packing>
+                <property name="name">unfocused</property>
+              </packing>
             </child>
 
+            <!-- Edit page -->
             <child>
-              <object class="GtkLabel" id="task_date_label">
+              <object class="GtkBox">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="xalign">0</property>
-                <style>
-                  <class name="dim-label"/>
-                </style>
-              </object>
-            </child>
-            <child>
-              <object class="GtkLabel" id="task_list_label">
-                <property name="visible">False</property>
-                <property name="can_focus">False</property>
-                <property name="xalign">0</property>
-                <property name="max_width_chars">18</property>
-                <property name="ellipsize">middle</property>
-                <style>
-                  <class name="dim-label"/>
-                </style>
+                <child>
+                  <object class="GtdEditPane" id="edit_panel">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <signal name="edit-finished" handler="edit_finished_cb" object="GtdTaskRow" swapped="no" 
/>
+                    <signal name="remove-task" handler="remove_task_cb" object="GtdTaskRow" swapped="no" />
+                  </object>
+                </child>
               </object>
+              <packing>
+                <property name="name">edit</property>
+              </packing>
             </child>
 
           </object>
diff --git a/plugins/scheduled-panel/gtd-panel-scheduled.c b/plugins/scheduled-panel/gtd-panel-scheduled.c
index 3f07f64..e1dd33f 100644
--- a/plugins/scheduled-panel/gtd-panel-scheduled.c
+++ b/plugins/scheduled-panel/gtd-panel-scheduled.c
@@ -152,7 +152,6 @@ create_label (const gchar *text,
   box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
 
   gtk_container_add (GTK_CONTAINER (box), label);
-  gtk_container_add (GTK_CONTAINER (box), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL));
 
   gtk_widget_show_all (box);
 
diff --git a/src/gtd-edit-pane.c b/src/gtd-edit-pane.c
index 5ba0d27..3704816 100644
--- a/src/gtd-edit-pane.c
+++ b/src/gtd-edit-pane.c
@@ -29,13 +29,12 @@ typedef struct
   GtkLabel          *date_label;
   GtkTextView       *notes_textview;
   GtkComboBoxText   *priority_combo;
+  GtkWidget         *title_entry;
 
   /* task bindings */
   GBinding          *notes_binding;
   GBinding          *priority_binding;
-
-  /* flags */
-  gint               should_save_task : 1;
+  GBinding          *title_binding;
 
   GtdTask           *task;
 } GtdEditPanePrivate;
@@ -56,7 +55,8 @@ enum {
   LAST_PROP
 };
 
-enum {
+enum
+{
   EDIT_FINISHED,
   REMOVE_TASK,
   NUM_SIGNALS
@@ -64,8 +64,8 @@ enum {
 
 static guint signals[NUM_SIGNALS] = { 0, };
 
-static void             gtd_edit_pane__date_selected              (GtkCalendar      *calendar,
-                                                                   gpointer          user_data);
+static void             date_selected_cb                          (GtkCalendar      *calendar,
+                                                                   GtdEditPane      *self);
 
 static void             gtd_edit_pane_update_date                 (GtdEditPane      *pane);
 
@@ -83,6 +83,19 @@ gtd_edit_pane__no_date_button_clicked (GtkButton *button,
 }
 
 static void
+save_task (GtdEditPane *self)
+{
+  GtdEditPanePrivate *priv;
+  GtdManager *manager;
+
+  priv = gtd_edit_pane_get_instance_private (self);
+  manager = gtd_manager_get_default ();
+
+  gtd_task_save (priv->task);
+  gtd_manager_update_task (manager, priv->task);
+}
+
+static void
 gtd_edit_pane__delete_button_clicked (GtkButton *button,
                                       gpointer   user_data)
 {
@@ -93,23 +106,17 @@ gtd_edit_pane__delete_button_clicked (GtkButton *button,
   priv = GTD_EDIT_PANE (user_data)->priv;
 
   g_signal_emit (user_data, signals[REMOVE_TASK], 0, priv->task);
-
-  priv->should_save_task = FALSE;
-  gtd_edit_pane_set_task (GTD_EDIT_PANE (user_data), NULL);
 }
 
 static void
-gtd_edit_pane__close_button_clicked (GtkButton *button,
-                                     gpointer   user_data)
+close_button_clicked_cb (GtkButton   *button,
+                         GtdEditPane *self)
 {
-  GtdEditPanePrivate *priv;
+  GtdEditPanePrivate *priv = gtd_edit_pane_get_instance_private (self);
 
-  g_return_if_fail (GTD_IS_EDIT_PANE (user_data));
-
-  priv = GTD_EDIT_PANE (user_data)->priv;
+  save_task (self);
 
-  priv->should_save_task = TRUE;
-  gtd_edit_pane_set_task (GTD_EDIT_PANE (user_data), NULL);
+  g_signal_emit (self, signals[EDIT_FINISHED], 0, priv->task);
 }
 
 static void
@@ -126,6 +133,8 @@ today_button_clicked (GtkButton   *button,
   gtd_task_set_due_date (priv->task, new_dt);
   gtd_edit_pane_update_date (self);
 
+  save_task (self);
+
   g_clear_pointer (&new_dt, g_date_time_unref);
 }
 
@@ -145,6 +154,8 @@ tomorrow_button_clicked (GtkButton   *button,
   gtd_task_set_due_date (priv->task, new_dt);
   gtd_edit_pane_update_date (self);
 
+  save_task (self);
+
   g_clear_pointer (&current_date, g_date_time_unref);
   g_clear_pointer (&new_dt, g_date_time_unref);
 }
@@ -165,6 +176,8 @@ next_week_button_clicked (GtkButton   *button,
   gtd_task_set_due_date (priv->task, new_dt);
   gtd_edit_pane_update_date (self);
 
+  save_task (self);
+
   g_clear_pointer (&current_date, g_date_time_unref);
   g_clear_pointer (&new_dt, g_date_time_unref);
 }
@@ -183,7 +196,7 @@ gtd_edit_pane_update_date (GtdEditPane *pane)
   text = dt ? g_date_time_format (dt, "%x") : NULL;
 
   g_signal_handlers_block_by_func (priv->calendar,
-                                   gtd_edit_pane__date_selected,
+                                   date_selected_cb,
                                    pane);
 
   if (dt)
@@ -211,7 +224,7 @@ gtd_edit_pane_update_date (GtdEditPane *pane)
     }
 
   g_signal_handlers_unblock_by_func (priv->calendar,
-                                     gtd_edit_pane__date_selected,
+                                     date_selected_cb,
                                      pane);
 
   gtk_label_set_label (priv->date_label, text ? text : _("No date set"));
@@ -220,8 +233,8 @@ gtd_edit_pane_update_date (GtdEditPane *pane)
 }
 
 static void
-gtd_edit_pane__date_selected (GtkCalendar *calendar,
-                              gpointer     user_data)
+date_selected_cb (GtkCalendar *calendar,
+                  GtdEditPane *self)
 {
   GtdEditPanePrivate *priv;
   GDateTime *new_dt;
@@ -230,9 +243,7 @@ gtd_edit_pane__date_selected (GtkCalendar *calendar,
   guint month;
   guint day;
 
-  g_return_if_fail (GTD_IS_EDIT_PANE (user_data));
-
-  priv = GTD_EDIT_PANE (user_data)->priv;
+  priv = self->priv;
 
   gtk_calendar_get_date (calendar,
                          &year,
@@ -250,7 +261,6 @@ gtd_edit_pane__date_selected (GtkCalendar *calendar,
 
   gtd_task_set_due_date (priv->task, new_dt);
   gtk_label_set_label (priv->date_label, text);
-  priv->should_save_task = TRUE;
 
   g_date_time_unref (new_dt);
   g_free (text);
@@ -375,14 +385,17 @@ gtd_edit_pane_class_init (GtdEditPaneClass *klass)
   gtk_widget_class_bind_template_child_private (widget_class, GtdEditPane, date_label);
   gtk_widget_class_bind_template_child_private (widget_class, GtdEditPane, notes_textview);
   gtk_widget_class_bind_template_child_private (widget_class, GtdEditPane, priority_combo);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdEditPane, title_entry);
 
-  gtk_widget_class_bind_template_callback (widget_class, gtd_edit_pane__close_button_clicked);
-  gtk_widget_class_bind_template_callback (widget_class, gtd_edit_pane__date_selected);
+  gtk_widget_class_bind_template_callback (widget_class, close_button_clicked_cb);
+  gtk_widget_class_bind_template_callback (widget_class, date_selected_cb);
   gtk_widget_class_bind_template_callback (widget_class, gtd_edit_pane__delete_button_clicked);
   gtk_widget_class_bind_template_callback (widget_class, gtd_edit_pane__no_date_button_clicked);
   gtk_widget_class_bind_template_callback (widget_class, next_week_button_clicked);
   gtk_widget_class_bind_template_callback (widget_class, today_button_clicked);
   gtk_widget_class_bind_template_callback (widget_class, tomorrow_button_clicked);
+
+  gtk_widget_class_set_css_name (widget_class, "editpane");
 }
 
 static void
@@ -415,15 +428,6 @@ gtd_edit_pane_get_task (GtdEditPane *pane)
   return pane->priv->task;
 }
 
-static void
-gtd_edit_pane__task_changed_cb (GObject    *gobject,
-                                GParamSpec *pspec,
-                                gpointer    user_data)
-{
-  GtdEditPanePrivate *priv = GTD_EDIT_PANE (user_data)->priv;
-  priv->should_save_task = TRUE;
-}
-
 /**
  * gtd_edit_pane_set_task:
  * @pane: a #GtdEditPane
@@ -444,23 +448,7 @@ gtd_edit_pane_set_task (GtdEditPane *pane,
   if (priv->task == task)
     return;
 
-  if (priv->task)
-    {
-      if (G_IS_BINDING (priv->notes_binding))
-        g_clear_pointer (&priv->notes_binding, g_binding_unbind);
-      if (G_IS_BINDING (priv->priority_binding))
-        g_clear_pointer (&priv->priority_binding, g_binding_unbind);
-      g_signal_handlers_disconnect_by_func (gtk_text_view_get_buffer (priv->notes_textview),
-                                            gtd_edit_pane__task_changed_cb, pane);
-      g_signal_handlers_disconnect_by_func (priv->priority_combo,
-                                            gtd_edit_pane__task_changed_cb, pane);
-
-      if (priv->should_save_task)
-        g_signal_emit (pane, signals[EDIT_FINISHED], 0, priv->task);
-    }
-
   priv->task = task;
-  priv->should_save_task = FALSE;
 
   if (task)
     {
@@ -479,22 +467,22 @@ gtd_edit_pane_set_task (GtdEditPane *pane,
                                                     task,
                                                     "description",
                                                     G_BINDING_BIDIRECTIONAL);
-      g_signal_connect (buffer, "notify::text",
-                        G_CALLBACK (gtd_edit_pane__task_changed_cb),
-                        pane);
 
       /* priority */
-      gtk_combo_box_set_active (GTK_COMBO_BOX (priv->priority_combo), CLAMP (gtd_task_get_priority (task),
-                                                                             0,
-                                                                             3));
+      gtk_combo_box_set_active (GTK_COMBO_BOX (priv->priority_combo),
+                                CLAMP (gtd_task_get_priority (task), 0, 3));
       priv->priority_binding = g_object_bind_property (task,
                                                        "priority",
                                                        priv->priority_combo,
                                                        "active",
                                                        G_BINDING_BIDIRECTIONAL);
-      g_signal_connect (priv->priority_combo, "notify::active",
-                        G_CALLBACK (gtd_edit_pane__task_changed_cb),
-                        pane);
+
+      /* title */
+      priv->priority_binding = g_object_bind_property (task,
+                                                       "title",
+                                                       priv->title_entry,
+                                                       "text",
+                                                       G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
 
     }
 
diff --git a/src/gtd-task-list-view.c b/src/gtd-task-list-view.c
index a0fdd39..2cabc21 100644
--- a/src/gtd-task-list-view.c
+++ b/src/gtd-task-list-view.c
@@ -64,10 +64,7 @@
 
 typedef struct
 {
-  GtdArrowFrame         *arrow_frame;
   GtkWidget             *dnd_row;
-  GtdEditPane           *edit_pane;
-  GtkRevealer           *edit_revealer;
   GtkWidget             *empty_box;
   GtkListBox            *listbox;
   GtkListBoxRow         *new_task_row;
@@ -635,19 +632,18 @@ ask_subtask_removal_warning (GtdTaskListView *self)
 }
 
 static void
-gtd_task_list_view__remove_task_cb (GtdEditPane *pane,
-                                    GtdTask     *task,
-                                    gpointer     user_data)
+remove_task_cb (GtdTaskRow      *row,
+                GtdTaskListView *self)
 {
   GtdTaskListViewPrivate *priv;
   GtdNotification *notification;
   RemoveTaskData *data;
   GtdWindow *window;
+  GtdTask *task;
   GList *subtasks;
   gchar *text;
 
-  g_return_if_fail (GTD_IS_TASK_LIST_VIEW (user_data));
-
+  task = gtd_task_row_get_task (row);
   subtasks = gtd_task_get_subtasks (task);
 
   /*
@@ -658,26 +654,23 @@ gtd_task_list_view__remove_task_cb (GtdEditPane *pane,
     {
       gboolean should_remove_task;
 
-      should_remove_task = ask_subtask_removal_warning (user_data);
+      should_remove_task = ask_subtask_removal_warning (self);
 
       /* The user canceled the operation, do nothing */
       if (!should_remove_task)
         goto out;
     }
 
-  priv = GTD_TASK_LIST_VIEW (user_data)->priv;
+  priv = self->priv;
   text = g_strdup_printf (_("Task <b>%s</b> removed"), gtd_task_get_title (task));
-  window = GTD_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (user_data)));
+  window = GTD_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self)));
 
   data = g_new0 (RemoveTaskData, 1);
-  data->view = user_data;
+  data->view = self;
   data->task = task;
 
   /* Always remove tasks and subtasks */
-  iterate_subtasks (user_data,
-                    task,
-                    remove_task_from_list,
-                    FALSE);
+  iterate_subtasks (self, task, remove_task_from_list, FALSE);
 
   /*
    * Reset the DnD row, to avoid getting into an inconsistent state where
@@ -685,9 +678,6 @@ gtd_task_list_view__remove_task_cb (GtdEditPane *pane,
    */
   gtd_dnd_row_set_row_above (GTD_DND_ROW (priv->dnd_row), NULL);
 
-  /* Hide the edit panel */
-  gtk_revealer_set_reveal_child (priv->edit_revealer, FALSE);
-
   /* Notify about the removal */
   notification = gtd_notification_new (text, 7500.0);
 
@@ -703,7 +693,7 @@ gtd_task_list_view__remove_task_cb (GtdEditPane *pane,
   gtd_window_notify (window, notification);
 
   /* Clear the active row */
-  set_active_row (user_data, NULL);
+  set_active_row (self, NULL);
 
   g_clear_pointer (&text, g_free);
 
@@ -712,31 +702,6 @@ out:
 }
 
 static void
-gtd_task_list_view__edit_task_finished (GtdEditPane *pane,
-                                        GtdTask     *task,
-                                        gpointer     user_data)
-{
-  GtdTaskListViewPrivate *priv;
-
-  g_return_if_fail (GTD_IS_TASK (task));
-  g_return_if_fail (GTD_IS_EDIT_PANE (pane));
-  g_return_if_fail (GTD_IS_TASK_LIST_VIEW (user_data));
-
-  priv = GTD_TASK_LIST_VIEW (user_data)->priv;
-
-  set_active_row (user_data, NULL);
-
-  gtk_revealer_set_reveal_child (priv->edit_revealer, FALSE);
-
-  gtd_task_save (task);
-
-  gtd_manager_update_task (gtd_manager_get_default (), task);
-  real_save_task (GTD_TASK_LIST_VIEW (user_data), task);
-
-  gtk_list_box_invalidate_sort (priv->listbox);
-}
-
-static void
 gtd_task_list_view__color_changed (GtdTaskListView *self)
 {
   GtdTaskListViewPrivate *priv = GTD_TASK_LIST_VIEW (self)->priv;
@@ -835,31 +800,7 @@ static void
 task_row_entered_cb (GtdTaskListView *self,
                      GtdTaskRow      *row)
 {
-  GtdTaskListViewPrivate *priv = self->priv;
-  GtdTask *old_task;
-
-  old_task = gtd_edit_pane_get_task (priv->edit_pane);
-
-  /* Save the task previously edited */
-  if (old_task)
-    {
-      gtd_manager_update_task (gtd_manager_get_default (), old_task);
-      real_save_task (self, old_task);
-    }
-
   set_active_row (self, GTK_WIDGET (row));
-
-  /* If we focused the new task row, only activate it */
-  if (GTD_IS_NEW_TASK_ROW (row))
-    {
-      gtk_revealer_set_reveal_child (priv->edit_revealer, FALSE);
-      return;
-    }
-
-  gtd_edit_pane_set_task (priv->edit_pane, gtd_task_row_get_task (row));
-
-  gtk_revealer_set_reveal_child (priv->edit_revealer, TRUE);
-  gtd_arrow_frame_set_row (priv->arrow_frame, row);
 }
 
 static void
@@ -867,21 +808,6 @@ task_row_exited_cb (GtdTaskListView *self,
                     GtdTaskRow      *row)
 {
   GtdTaskListViewPrivate *priv = self->priv;
-  GtdTask *old_task;
-
-  old_task = gtd_edit_pane_get_task (priv->edit_pane);
-
-  /* Save the task previously edited */
-  if (old_task)
-    {
-      gtd_manager_update_task (gtd_manager_get_default (), old_task);
-      real_save_task (self, old_task);
-    }
-
-  gtd_edit_pane_set_task (priv->edit_pane, NULL);
-
-  gtk_revealer_set_reveal_child (priv->edit_revealer, FALSE);
-  gtd_arrow_frame_set_row (priv->arrow_frame, NULL);
 
   if (GTK_WIDGET (row) == priv->active_row &&
       priv->active_row != GTK_WIDGET (priv->new_task_row))
@@ -929,9 +855,12 @@ insert_task (GtdTaskListView *self,
                             G_CALLBACK (task_row_exited_cb),
                             self);
 
-  gtk_list_box_insert (priv->listbox,
-                       new_row,
-                       0);
+  g_signal_connect (new_row,
+                    "remove-task",
+                    G_CALLBACK (remove_task_cb),
+                    self);
+
+  gtk_list_box_insert (priv->listbox, new_row, 0);
 
   /*
    * Setup a sizegroup to let all the tasklist labels have
@@ -965,8 +894,6 @@ remove_task (GtdTaskListView *view,
   GList *children;
   GList *l;
 
-  gtd_arrow_frame_set_row (view->priv->arrow_frame, NULL);
-
   children = gtk_container_get_children (GTK_CONTAINER (view->priv->listbox));
 
   for (l = children; l != NULL; l = l->next)
@@ -990,7 +917,6 @@ remove_task (GtdTaskListView *view,
     }
 
   gtk_revealer_set_reveal_child (priv->revealer, FALSE);
-  gtk_revealer_set_reveal_child (priv->edit_revealer, FALSE);
 
   g_list_free (children);
 }
@@ -1112,17 +1038,6 @@ task_completed_cb (GtdTask         *task,
   else
     priv->complete_tasks--;
 
-  /*
-   * If we're editing the task and it get completed, hide the edit
-   * pane and the task.
-   */
-  if (task_complete &&
-      task == gtd_edit_pane_get_task (priv->edit_pane))
-    {
-      gtk_revealer_set_reveal_child (priv->edit_revealer, FALSE);
-      gtd_edit_pane_set_task (priv->edit_pane, NULL);
-    }
-
   if (!priv->show_completed)
     {
       IterateSubtaskFunc func;
@@ -1158,10 +1073,10 @@ gtd_task_list_view__task_added (GtdTaskList     *list,
 }
 
 static void
-gtd_task_list_view__create_task (GtdTaskRow  *row,
-                                 GtdTask     *task,
-                                 GtdTaskList *list,
-                                 gpointer     user_data)
+create_task_cb (GtdTaskRow  *row,
+                GtdTask     *task,
+                GtdTaskList *list,
+                gpointer     user_data)
 {
   GtdTaskListViewPrivate *priv;
 
@@ -1678,11 +1593,8 @@ gtd_task_list_view_class_init (GtdTaskListViewClass *klass)
 
   gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/todo/ui/list-view.ui");
 
-  gtk_widget_class_bind_template_child_private (widget_class, GtdTaskListView, arrow_frame);
   gtk_widget_class_bind_template_child_private (widget_class, GtdTaskListView, dnd_row);
   gtk_widget_class_bind_template_child_private (widget_class, GtdTaskListView, due_date_sizegroup);
-  gtk_widget_class_bind_template_child_private (widget_class, GtdTaskListView, edit_pane);
-  gtk_widget_class_bind_template_child_private (widget_class, GtdTaskListView, edit_revealer);
   gtk_widget_class_bind_template_child_private (widget_class, GtdTaskListView, empty_box);
   gtk_widget_class_bind_template_child_private (widget_class, GtdTaskListView, listbox);
   gtk_widget_class_bind_template_child_private (widget_class, GtdTaskListView, revealer);
@@ -1693,10 +1605,8 @@ gtd_task_list_view_class_init (GtdTaskListViewClass *klass)
   gtk_widget_class_bind_template_child_private (widget_class, GtdTaskListView, viewport);
   gtk_widget_class_bind_template_child_private (widget_class, GtdTaskListView, scrolled_window);
 
-  gtk_widget_class_bind_template_callback (widget_class, gtd_task_list_view__create_task);
+  gtk_widget_class_bind_template_callback (widget_class, create_task_cb);
   gtk_widget_class_bind_template_callback (widget_class, gtd_task_list_view__done_button_clicked);
-  gtk_widget_class_bind_template_callback (widget_class, gtd_task_list_view__edit_task_finished);
-  gtk_widget_class_bind_template_callback (widget_class, gtd_task_list_view__remove_task_cb);
   gtk_widget_class_bind_template_callback (widget_class, listbox_drag_drop);
   gtk_widget_class_bind_template_callback (widget_class, listbox_drag_leave);
   gtk_widget_class_bind_template_callback (widget_class, listbox_drag_motion);
@@ -1911,7 +1821,6 @@ gtd_task_list_view_set_task_list (GtdTaskListView *view,
 
   if (!list)
     {
-      gtd_edit_pane_set_task (GTD_EDIT_PANE (priv->edit_pane), NULL);
       gtd_task_list_view_set_list (view, NULL);
       return;
     }
@@ -1939,7 +1848,6 @@ gtd_task_list_view_set_task_list (GtdTaskListView *view,
   task_list = gtd_task_list_get_tasks (list);
 
   gtd_task_list_view_set_list (view, task_list);
-  gtd_edit_pane_set_task (priv->edit_pane, NULL);
 
   g_list_free (task_list);
 
diff --git a/src/gtd-task-row.c b/src/gtd-task-row.c
index a52cfd4..a99fd20 100644
--- a/src/gtd-task-row.c
+++ b/src/gtd-task-row.c
@@ -16,6 +16,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "gtd-edit-pane.h"
+#include "gtd-manager.h"
 #include "gtd-provider.h"
 #include "gtd-task-row.h"
 #include "gtd-task.h"
@@ -33,9 +35,11 @@ struct _GtdTaskRow
   GtkRevealer               *revealer;
 
   GtkWidget                 *done_check;
+  GtkWidget                 *edit_panel;
+  GtkWidget                 *stack;
 
   /* task widgets */
-  GtkEntry                  *title_entry;
+  GtkEntry                  *title_label;
   GtkLabel                  *task_date_label;
   GtkLabel                  *task_list_label;
 
@@ -64,10 +68,12 @@ G_DEFINE_TYPE (GtdTaskRow, gtd_task_row, GTK_TYPE_LIST_BOX_ROW)
 enum {
   ENTER,
   EXIT,
+  REMOVE_TASK,
   NUM_SIGNALS
 };
 
-enum {
+enum
+{
   PROP_0,
   PROP_HANDLE_SUBTASKS,
   PROP_TASK,
@@ -83,6 +89,11 @@ typedef enum
 
 static guint signals[NUM_SIGNALS] = { 0, };
 
+
+/*
+ * Auxiliary methods
+ */
+
 static void
 set_dnd_cursor (GtkWidget  *widget,
                 CursorType  type)
@@ -152,6 +163,27 @@ get_dnd_icon (GtdTaskRow *self)
   return surface;
 }
 
+
+/*
+ * Callbacks
+ */
+
+static void
+edit_finished_cb (GtdEditPane *edit_panel,
+                  GtdTask     *task,
+                  GtdTaskRow  *self)
+{
+  gtd_task_row_set_active (self, FALSE);
+}
+
+static void
+remove_task_cb (GtdEditPane *edit_panel,
+                GtdTask     *task,
+                GtdTaskRow  *self)
+{
+  g_signal_emit (self, signals[REMOVE_TASK], 0);
+}
+
 static gboolean
 mouse_out_event (GtkWidget  *widget,
                  GdkEvent   *event,
@@ -213,9 +245,9 @@ drag_failed_cb (GtkWidget   *widget,
 }
 
 static void
-gtd_task_row__priority_changed_cb (GtdTaskRow *row,
-                                   GParamSpec *spec,
-                                   GObject    *object)
+priority_changed_cb (GtdTaskRow *row,
+                     GParamSpec *spec,
+                     GObject    *object)
 {
   GtkStyleContext *context;
   gint priority;
@@ -383,13 +415,10 @@ gtd_task_row__destroy_cb (GtkWidget *row)
   return G_SOURCE_REMOVE;
 }
 
-GtkWidget*
-gtd_task_row_new (GtdTask *task)
-{
-  return g_object_new (GTD_TYPE_TASK_ROW,
-                       "task", task,
-                       NULL);
-}
+
+/*
+ * GtkWidget overrides
+ */
 
 static gboolean
 gtd_task_row__key_press_event (GtkWidget   *row,
@@ -416,6 +445,11 @@ gtd_task_row_focus_in_event (GtkWidget     *widget,
   return GDK_EVENT_PROPAGATE;
 }
 
+
+/*
+ * GObject overrides
+ */
+
 static void
 gtd_task_row_finalize (GObject *object)
 {
@@ -437,17 +471,10 @@ gtd_task_row_dispose (GObject *object)
 
   if (task)
     {
-      g_signal_handlers_disconnect_by_func (task,
-                                        depth_changed_cb,
-                                        self);
+      g_signal_handlers_disconnect_by_func (task, depth_changed_cb, self);
+      g_signal_handlers_disconnect_by_func (task, complete_changed_cb, self);
 
-      g_signal_handlers_disconnect_by_func (task,
-                                            complete_changed_cb,
-                                            self);
-
-      g_signal_handlers_disconnect_by_func (task,
-                                            gtd_task_row__priority_changed_cb,
-                                            self);
+      g_signal_handlers_disconnect_by_func (task, priority_changed_cb, self);
     }
 
   G_OBJECT_CLASS (gtd_task_row_parent_class)->dispose (object);
@@ -571,23 +598,42 @@ gtd_task_row_class_init (GtdTaskRowClass *klass)
                                 G_TYPE_NONE,
                                 0);
 
+  /**
+   * GtdTaskRow::remove-task:
+   *
+   * Emitted when the user wants to delete the task represented by this row.
+   */
+  signals[REMOVE_TASK] = g_signal_new ("remove-task",
+                                       GTD_TYPE_TASK_ROW,
+                                       G_SIGNAL_RUN_LAST,
+                                       0,
+                                       NULL,
+                                       NULL,
+                                       NULL,
+                                       G_TYPE_NONE,
+                                       0);
+
   gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/todo/ui/task-row.ui");
 
   gtk_widget_class_bind_template_child (widget_class, GtdTaskRow, dnd_box);
   gtk_widget_class_bind_template_child (widget_class, GtdTaskRow, dnd_event_box);
   gtk_widget_class_bind_template_child (widget_class, GtdTaskRow, dnd_icon);
   gtk_widget_class_bind_template_child (widget_class, GtdTaskRow, done_check);
+  gtk_widget_class_bind_template_child (widget_class, GtdTaskRow, edit_panel);
   gtk_widget_class_bind_template_child (widget_class, GtdTaskRow, revealer);
+  gtk_widget_class_bind_template_child (widget_class, GtdTaskRow, stack);
   gtk_widget_class_bind_template_child (widget_class, GtdTaskRow, task_date_label);
   gtk_widget_class_bind_template_child (widget_class, GtdTaskRow, task_list_label);
-  gtk_widget_class_bind_template_child (widget_class, GtdTaskRow, title_entry);
+  gtk_widget_class_bind_template_child (widget_class, GtdTaskRow, title_label);
 
   gtk_widget_class_bind_template_callback (widget_class, button_press_event);
   gtk_widget_class_bind_template_callback (widget_class, complete_check_toggled_cb);
   gtk_widget_class_bind_template_callback (widget_class, drag_begin_cb);
   gtk_widget_class_bind_template_callback (widget_class, drag_failed_cb);
+  gtk_widget_class_bind_template_callback (widget_class, edit_finished_cb);
   gtk_widget_class_bind_template_callback (widget_class, mouse_out_event);
   gtk_widget_class_bind_template_callback (widget_class, mouse_over_event);
+  gtk_widget_class_bind_template_callback (widget_class, remove_task_cb);
 
   gtk_widget_class_set_css_name (widget_class, "taskrow");
 }
@@ -607,6 +653,14 @@ gtd_task_row_init (GtdTaskRow *self)
                        GDK_ACTION_COPY);
 }
 
+GtkWidget*
+gtd_task_row_new (GtdTask *task)
+{
+  return g_object_new (GTD_TYPE_TASK_ROW,
+                       "task", task,
+                       NULL);
+}
+
 /**
  * gtd_task_row_get_task:
  * @row: a #GtdTaskRow
@@ -638,63 +692,65 @@ gtd_task_row_set_task (GtdTaskRow *row,
 {
   g_return_if_fail (GTD_IS_TASK_ROW (row));
 
-  if (g_set_object (&row->task, task))
-    {
-      if (task)
-        {
-          gtk_label_set_label (row->task_list_label, gtd_task_list_get_name (gtd_task_get_list (task)));
-
-          g_signal_handlers_block_by_func (row->done_check, complete_check_toggled_cb, row);
-
-          g_object_bind_property (task,
-                                  "title",
-                                  row->title_entry,
-                                  "text",
-                                  G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
-
-          g_object_bind_property (task,
-                                  "complete",
-                                  row->done_check,
-                                  "active",
-                                  G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
-
-          g_object_bind_property_full (task,
-                                       "due-date",
-                                       row->task_date_label,
-                                       "label",
-                                       G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE,
-                                       gtd_task_row__date_changed_binding,
-                                       NULL,
-                                       row,
-                                       NULL);
-
-          /*
-           * Here we generate a false callback call just to reuse the method to
-           * sync the initial state of the priority icon.
-           */
-          gtd_task_row__priority_changed_cb (row, NULL, G_OBJECT (task));
-          g_signal_connect_swapped (task,
-                                    "notify::priority",
-                                    G_CALLBACK (gtd_task_row__priority_changed_cb),
-                                    row);
-
-          complete_changed_cb (row, NULL, task);
-          g_signal_connect_swapped (task,
-                                    "notify::complete",
-                                    G_CALLBACK (complete_changed_cb),
-                                    row);
-
-          depth_changed_cb (row, NULL, task);
-          g_signal_connect_swapped (task,
-                                    "notify::depth",
-                                    G_CALLBACK (depth_changed_cb),
-                                    row);
-
-          g_signal_handlers_unblock_by_func (row->done_check, complete_check_toggled_cb, row);
-        }
+  if (!g_set_object (&row->task, task))
+    return;
 
-      g_object_notify (G_OBJECT (row), "task");
+  if (task)
+    {
+      gtk_label_set_label (row->task_list_label, gtd_task_list_get_name (gtd_task_get_list (task)));
+
+      g_signal_handlers_block_by_func (row->done_check, complete_check_toggled_cb, row);
+
+      g_object_bind_property (task,
+                              "title",
+                              row->title_label,
+                              "label",
+                              G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
+
+      g_object_bind_property (task,
+                              "complete",
+                              row->done_check,
+                              "active",
+                              G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
+
+      g_object_bind_property_full (task,
+                                   "due-date",
+                                   row->task_date_label,
+                                   "label",
+                                   G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE,
+                                   gtd_task_row__date_changed_binding,
+                                   NULL,
+                                   row,
+                                   NULL);
+
+      /*
+       * Here we generate a false callback call just to reuse the method to
+       * sync the initial state of the priority icon.
+       */
+      priority_changed_cb (row, NULL, G_OBJECT (task));
+      g_signal_connect_swapped (task,
+                                "notify::priority",
+                                G_CALLBACK (priority_changed_cb),
+                                row);
+
+      complete_changed_cb (row, NULL, task);
+      g_signal_connect_swapped (task,
+                                "notify::complete",
+                                G_CALLBACK (complete_changed_cb),
+                                row);
+
+      depth_changed_cb (row, NULL, task);
+      g_signal_connect_swapped (task,
+                                "notify::depth",
+                                G_CALLBACK (depth_changed_cb),
+                                row);
+
+      g_signal_handlers_unblock_by_func (row->done_check, complete_check_toggled_cb, row);
+
+      gtd_edit_pane_set_task (GTD_EDIT_PANE (row->edit_panel), task);
     }
+
+  g_object_notify (G_OBJECT (row), "task");
 }
 
 /**
@@ -816,11 +872,18 @@ gtd_task_row_set_active (GtdTaskRow *self,
 
   self->active = active;
 
+  gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (self), !active);
+  gtk_widget_set_can_focus (GTK_WIDGET (self), !active);
+
   if (active)
     {
-      gtk_widget_grab_focus (GTK_WIDGET (self->title_entry));
+      gtk_stack_set_visible_child_name (GTK_STACK (self->stack), "edit");
       g_signal_emit (self, signals[ENTER], 0);
     }
+  else
+    {
+      gtk_stack_set_visible_child_name (GTK_STACK (self->stack), "unfocused");
+    }
 }
 
 void


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