[ease] [editor] Element type-specific inspector panes



commit ecb589eca7951de3028186b31a70f574b1b397bf
Author: Nate Stedman <natesm gmail com>
Date:   Mon Jul 26 17:50:54 2010 -0400

    [editor] Element type-specific inspector panes
    
    All Element subclasses must now implement inspector_widget(),
    which returns a widget that will be placed in the "element"
    pane of the inspector when that element is selected.
    
    Added inspector widgets for text and image elements.
    
    Additionally, a virtual (but not abstract) method on Element
    allows subclasses to define a set of toolbar items. However,
    this is not currently used by EditorWindow, so all functionality
    must be placed in the inspector widget.
    
    Text-specific toolbar items have been removed, replaced by
    the text element inspector widget.
    
    The user can now set the alignment of text.

 Makefile.am                                        |    7 +-
 data/ui/editor-window.ui                           |   35 ------
 data/ui/inspector-element-image.ui                 |   56 +++++++++
 data/ui/inspector-element-none.ui                  |   55 +++++++++
 data/ui/inspector-element-text.ui                  |  124 ++++++++++++++++++++
 data/ui/inspector-slide.ui                         |   14 +-
 src/ease-editor-embed.vala                         |   19 +++
 src/ease-editor-window.vala                        |   18 ++-
 src/ease-element.vala                              |   21 +++-
 src/ease-image-actor.vala                          |    4 +
 src/ease-image-element.vala                        |   46 +++++++
 src/ease-inspector-element-pane.vala               |   68 +++++++++++
 ...de-pane.vala => ease-inspector-slide-pane.vala} |    4 +-
 ...ne.vala => ease-inspector-transition-pane.vala} |    4 +-
 src/ease-inspector.vala                            |   12 ++-
 src/ease-media-element.vala                        |    7 +
 src/ease-text-actor.vala                           |    8 ++
 src/ease-text-element.vala                         |  116 ++++++++++++++++++-
 src/ease-theme.vala                                |    1 +
 19 files changed, 558 insertions(+), 61 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index ef60e4b..903aef3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -30,9 +30,12 @@ ease_SOURCES = \
 	src/ease-html-exporter.vala \
 	src/ease-image-actor.vala \
 	src/ease-image-element.vala \
+	src/ease-inspector-element-pane.vala \
 	src/ease-inspector-pane.vala \
-	src/ease-inspector.vala \
+	src/ease-inspector-slide-pane.vala \
+	src/ease-inspector-transition-pane.vala \
 	src/ease-inspector-window.vala \
+	src/ease-inspector.vala \
 	src/ease-iterables.vala \
 	src/ease-media-element.vala \
 	src/ease-player.vala \
@@ -40,14 +43,12 @@ ease_SOURCES = \
 	src/ease-selection-rectangle.vala \
 	src/ease-slide-actor.vala \
 	src/ease-slide-button-panel.vala \
-	src/ease-slide-pane.vala \
 	src/ease-slide.vala \
 	src/ease-temp.vala \
 	src/ease-text-actor.vala \
 	src/ease-text-element.vala \
 	src/ease-theme.vala \
 	src/ease-transformations.vala \
-	src/ease-transition-pane.vala \
 	src/ease-transitions.vala \
 	src/ease-undo-action.vala \
 	src/ease-undo-actions-element.vala \
diff --git a/data/ui/editor-window.ui b/data/ui/editor-window.ui
index 377fa15..bfb92e5 100644
--- a/data/ui/editor-window.ui
+++ b/data/ui/editor-window.ui
@@ -409,41 +409,6 @@
           </packing>
         </child>
         <child>
-          <object class="GtkSeparatorToolItem" id="toolbutton5">
-            <property name="visible">True</property>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="homogeneous">True</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkToolButton" id="Show Colors">
-            <property name="visible">True</property>
-            <property name="label" translatable="yes">Colors</property>
-            <property name="use_underline">True</property>
-            <property name="stock_id">gtk-select-color</property>
-            <signal name="clicked" handler="ease_editor_window_show_color_dialog"/>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="homogeneous">True</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkToolButton" id="Show Fonts">
-            <property name="visible">True</property>
-            <property name="label" translatable="yes">Fonts</property>
-            <property name="use_underline">True</property>
-            <property name="stock_id">gtk-select-font</property>
-            <signal name="clicked" handler="ease_editor_window_select_font"/>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="homogeneous">True</property>
-          </packing>
-        </child>
-        <child>
           <object class="GtkSeparatorToolItem" id="Expand Separator">
             <property name="visible">True</property>
           </object>
diff --git a/data/ui/inspector-element-image.ui b/data/ui/inspector-element-image.ui
new file mode 100644
index 0000000..bb93bc4
--- /dev/null
+++ b/data/ui/inspector-element-image.ui
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkAlignment" id="root">
+    <property name="visible">True</property>
+    <property name="top_padding">4</property>
+    <property name="bottom_padding">4</property>
+    <property name="left_padding">4</property>
+    <property name="right_padding">4</property>
+    <child>
+      <object class="GtkVBox" id="vbox1">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">4</property>
+        <child>
+          <object class="GtkHBox" id="hbox1">
+            <property name="visible">True</property>
+            <child>
+              <object class="GtkLabel" id="label1">
+                <property name="visible">True</property>
+                <property name="label" translatable="yes">Select Image</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <placeholder/>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkFileChooserButton" id="file-button">
+            <property name="visible">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/data/ui/inspector-element-none.ui b/data/ui/inspector-element-none.ui
new file mode 100644
index 0000000..6f519ee
--- /dev/null
+++ b/data/ui/inspector-element-none.ui
@@ -0,0 +1,55 @@
+<?xml version="1.0"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkVBox" id="root">
+    <property name="visible">True</property>
+    <property name="orientation">vertical</property>
+    <child>
+      <object class="GtkAlignment" id="alignment1">
+        <property name="visible">True</property>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+      <packing>
+        <property name="position">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkImage" id="image1">
+        <property name="visible">True</property>
+        <property name="ypad">4</property>
+        <property name="stock">gtk-dialog-warning</property>
+        <property name="icon-size">6</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">False</property>
+        <property name="position">1</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="label1">
+        <property name="visible">True</property>
+        <property name="label" translatable="yes">Nothing is selected</property>
+      </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="padding">16</property>
+        <property name="position">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkAlignment" id="alignment2">
+        <property name="visible">True</property>
+        <child>
+          <placeholder/>
+        </child>
+      </object>
+      <packing>
+        <property name="position">3</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/data/ui/inspector-element-text.ui b/data/ui/inspector-element-text.ui
new file mode 100644
index 0000000..a848385
--- /dev/null
+++ b/data/ui/inspector-element-text.ui
@@ -0,0 +1,124 @@
+<?xml version="1.0"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkAlignment" id="root">
+    <property name="visible">True</property>
+    <property name="top_padding">4</property>
+    <property name="bottom_padding">4</property>
+    <property name="left_padding">4</property>
+    <property name="right_padding">4</property>
+    <child>
+      <object class="GtkVBox" id="vbox1">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">4</property>
+        <child>
+          <object class="GtkFontButton" id="font-button">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkColorButton" id="color-button">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <property name="color">#000000000000</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkAlignment" id="alignment1">
+            <property name="visible">True</property>
+            <property name="xscale">0</property>
+            <child>
+              <object class="GtkHBox" id="hbox1">
+                <property name="visible">True</property>
+                <property name="spacing">4</property>
+                <child>
+                  <object class="GtkButton" id="left-button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="relief">none</property>
+                    <signal name="clicked" handler="ease_text_element_on_inspector_alignment"/>
+                    <child>
+                      <object class="GtkImage" id="image3">
+                        <property name="visible">True</property>
+                        <property name="stock">gtk-justify-left</property>
+                        <property name="icon-size">5</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="center-button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="relief">none</property>
+                    <signal name="clicked" handler="ease_text_element_on_inspector_alignment"/>
+                    <child>
+                      <object class="GtkImage" id="image2">
+                        <property name="visible">True</property>
+                        <property name="stock">gtk-justify-center</property>
+                        <property name="icon-size">5</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="right-button">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="relief">none</property>
+                    <signal name="clicked" handler="ease_text_element_on_inspector_alignment"/>
+                    <child>
+                      <object class="GtkImage" id="image1">
+                        <property name="visible">True</property>
+                        <property name="stock">gtk-justify-right</property>
+                        <property name="icon-size">5</property>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/data/ui/inspector-slide.ui b/data/ui/inspector-slide.ui
index b4dcbab..cf0a756 100644
--- a/data/ui/inspector-slide.ui
+++ b/data/ui/inspector-slide.ui
@@ -45,7 +45,7 @@
               <object class="GtkComboBox" id="combobox-style">
                 <property name="height_request">30</property>
                 <property name="visible">True</property>
-                <signal name="changed" handler="ease_slide_pane_on_background_changed"/>
+                <signal name="changed" handler="ease_inspector_slide_pane_on_background_changed"/>
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -94,7 +94,7 @@
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
                 <property name="color">#000000000000</property>
-                <signal name="color_set" handler="ease_slide_pane_on_color_set"/>
+                <signal name="color_set" handler="ease_inspector_slide_pane_on_color_set"/>
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -147,7 +147,7 @@
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
                     <property name="color">#000000000000</property>
-                    <signal name="color_set" handler="ease_slide_pane_on_color_set"/>
+                    <signal name="color_set" handler="ease_inspector_slide_pane_on_color_set"/>
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -161,7 +161,7 @@
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
                     <property name="color">#000000000000</property>
-                    <signal name="color_set" handler="ease_slide_pane_on_color_set"/>
+                    <signal name="color_set" handler="ease_inspector_slide_pane_on_color_set"/>
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -173,7 +173,7 @@
                   <object class="GtkComboBox" id="combo-gradient">
                     <property name="height_request">30</property>
                     <property name="visible">True</property>
-                    <signal name="changed" handler="ease_slide_pane_on_gradient_type_changed"/>
+                    <signal name="changed" handler="ease_inspector_slide_pane_on_gradient_type_changed"/>
                     <child>
                       <object class="GtkCellRendererText" id="cellrenderertext1"/>
                       <attributes>
@@ -198,7 +198,7 @@
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
                 <property name="xalign">0</property>
-                <signal name="clicked" handler="ease_slide_pane_on_reverse_gradient"/>
+                <signal name="clicked" handler="ease_inspector_slide_pane_on_reverse_gradient"/>
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -290,7 +290,7 @@
               <object class="GtkFileChooserButton" id="button-image">
                 <property name="height_request">30</property>
                 <property name="visible">True</property>
-                <signal name="file_set" handler="ease_slide_pane_on_file_set"/>
+                <signal name="file_set" handler="ease_inspector_slide_pane_on_file_set"/>
               </object>
               <packing>
                 <property name="position">1</property>
diff --git a/src/ease-editor-embed.vala b/src/ease-editor-embed.vala
index bfda5ed..40405f1 100644
--- a/src/ease-editor-embed.vala
+++ b/src/ease-editor-embed.vala
@@ -140,6 +140,9 @@ public class Ease.EditorEmbed : ScrollableEmbed, UndoSource
 	 */
 	private Document document;
 	
+	public signal void element_selected(Element selected);
+	public signal void element_deselected(Element? deselected);
+	
 	/**
 	 * The zoom level of the slide displayed by this EditorEmbed.
 	 * 
@@ -257,6 +260,8 @@ public class Ease.EditorEmbed : ScrollableEmbed, UndoSource
 		}
 		
 		connect_keys();
+		deselect_actor();
+		element_deselected(null);
 		
 		// clean up the previous slide
 		if (slide_actor != null)
@@ -271,6 +276,7 @@ public class Ease.EditorEmbed : ScrollableEmbed, UndoSource
 			
 			slide_actor.ease_actor_added.disconnect(on_ease_actor_added);
 			slide_actor.ease_actor_removed.disconnect(on_ease_actor_removed);
+			slide_actor.slide.element_removed.disconnect(on_element_removed);
 		}
 		
 		// remove the selection rectangle
@@ -292,6 +298,7 @@ public class Ease.EditorEmbed : ScrollableEmbed, UndoSource
 		
 		slide_actor.ease_actor_added.connect(on_ease_actor_added);
 		slide_actor.ease_actor_removed.connect(on_ease_actor_removed);
+		slide_actor.slide.element_removed.connect(on_element_removed);
 		
 		contents.add_actor(slide_actor);
 		reposition_group();
@@ -449,6 +456,7 @@ public class Ease.EditorEmbed : ScrollableEmbed, UndoSource
 		connect_keys();
 		
 		selected = sender as Actor;
+		element_selected(selected.element);
 		
 		// make a new selection rectangle
 		selection_rectangle = new SelectionRectangle();
@@ -491,6 +499,7 @@ public class Ease.EditorEmbed : ScrollableEmbed, UndoSource
 		{
 			selected.end_edit(this);
 			is_editing = false;
+			element_deselected(selected.element);
 		}
 		connect_keys();
 		
@@ -774,6 +783,7 @@ public class Ease.EditorEmbed : ScrollableEmbed, UndoSource
 				var i = slide.index_of(selected.element);
 				undo(new ElementRemoveUndoAction(slide.element_at(i)));
 				slide.remove_at(i);
+				element_deselected(null);
 				
 				return true;
 		}
@@ -782,6 +792,15 @@ public class Ease.EditorEmbed : ScrollableEmbed, UndoSource
 	}
 	
 	/**
+	 * Handles { link Slide.element_removed}.
+	 */
+	public void on_element_removed(Slide slide, Element element, int index)
+	{
+		if (slide != slide_actor.slide) return;
+		if (selected == null) element_deselected(element);
+	}
+	
+	/**
 	 * Connects the key event handlers.
 	 */
 	public void connect_keys()
diff --git a/src/ease-editor-window.vala b/src/ease-editor-window.vala
index a161028..d44174c 100644
--- a/src/ease-editor-window.vala
+++ b/src/ease-editor-window.vala
@@ -116,7 +116,7 @@ public class Ease.EditorWindow : Gtk.Window
 	 * Creates a new EditorWindow.
 	 * 
 	 * An EditorWindow includes a toolbar, an
-	 * { link EditorEmbed}, a { link SlidePane}, a menu bar, and other
+	 * { link EditorEmbed}, a { link InspectorSlidePane}, a menu bar, and other
 	 * interface elements.
 	 *
 	 * @param node The initial XML node to begin with.
@@ -149,15 +149,20 @@ public class Ease.EditorWindow : Gtk.Window
 		undo_button = builder.get_object("Undo") as Gtk.ToolButton;
 		redo_button = builder.get_object("Redo") as Gtk.ToolButton;
 		
+		// main editor
+		embed = new EditorEmbed(document, this);
+		(builder.get_object("Embed Align") as Gtk.Alignment).add(embed);
+		embed.undo.connect((action) => add_undo_action(action));
+		
 		// the inspector
 		inspector = new Inspector();
 		(builder.get_object("Inspector Align") as Gtk.Alignment).add(inspector);
 		inspector.undo.connect((action) => add_undo_action(action));
+		embed.element_selected.connect(
+			inspector.element_pane.on_element_selected);
+		embed.element_deselected.connect(
+			inspector.element_pane.on_element_deselected);
 		
-		// main editor
-		embed = new EditorEmbed(document, this);
-		(builder.get_object("Embed Align") as Gtk.Alignment).add(embed);
-		embed.undo.connect((action) => add_undo_action(action));
 		
 		// zoom slider
 		(builder.get_object("Zoom Slider Item") as Gtk.ToolItem).
@@ -230,7 +235,7 @@ public class Ease.EditorWindow : Gtk.Window
 	 *
 	 * @param action The new { link UndoItem}.
 	 */
-	private void add_undo_action(UndoItem action)
+	public void add_undo_action(UndoItem action)
 	{
 		undo.add_action(action);
 		undo.clear_redo();
@@ -388,6 +393,7 @@ public class Ease.EditorWindow : Gtk.Window
 				e.element_type = Slide.IMAGE_TYPE;
 				e.identifier = Theme.CUSTOM_MEDIA;
 				e.filename = document.add_media_file(dialog.get_filename());
+				e.source_filename = dialog.get_filename();
 				
 				// add the element
 				slide.add(e);
diff --git a/src/ease-element.vala b/src/ease-element.vala
index ab7a0d9..c4ab1c3 100644
--- a/src/ease-element.vala
+++ b/src/ease-element.vala
@@ -40,6 +40,11 @@ public abstract class Ease.Element : GLib.Object
 	public Slide parent { get; set; }
 	
 	/**
+	 * The { link Document} that this Element is part of. get-only.
+	 */
+	public Document document { get { return parent.parent; } }
+	
+	/**
 	 * Creates an Element from a JsonObject
 	 */
 	public Element.from_json(Json.Object obj)
@@ -61,7 +66,7 @@ public abstract class Ease.Element : GLib.Object
 		var obj = new Json.Object();
 		
 		obj.set_string_member(Theme.E_IDENTIFIER, identifier);
-		obj.set_string_member(Theme.ELEMENT_TYPE, element_type);
+		obj.set_string_member(Theme.ELEMENT_TYPE, get_type().name());
 		obj.set_string_member(Theme.X, x.to_string());
 		obj.set_string_member(Theme.Y, y.to_string());
 		obj.set_string_member(Theme.WIDTH, width.to_string());
@@ -126,6 +131,20 @@ public abstract class Ease.Element : GLib.Object
 	public abstract Actor actor(ActorContext c);
 	
 	/**
+	 * Returns an { link Inspector} widget for editing this Element.
+	 */
+	public abstract Gtk.Widget inspector_widget();
+	
+	/**
+	 * Returns a GList of ToolItems to add to the main toolbar when this
+	 * Element is selected.
+	 */
+	public virtual GLib.List<Gtk.ToolItem>? tool_items()
+	{
+		return null;
+	}
+	
+	/**
 	 * If applicable, this method sets the color of an Element and returns true.
 	 * Otherwise, it returns false. The method should be overridden by
 	 * subclasses that provide a "color" property.
diff --git a/src/ease-image-actor.vala b/src/ease-image-actor.vala
index 71708b8..72a9906 100644
--- a/src/ease-image-actor.vala
+++ b/src/ease-image-actor.vala
@@ -53,6 +53,10 @@ public class Ease.ImageActor : Actor
 			contents.height = e.height;
 			x = e.x;
 			y = e.y;
+			
+			e.notify["filename"].connect((obj, spec) => {
+				(contents as Clutter.Texture).filename = e.full_filename;
+			});
 		}
 	}
 }
diff --git a/src/ease-image-element.vala b/src/ease-image-element.vala
index 5a97582..8560fc9 100644
--- a/src/ease-image-element.vala
+++ b/src/ease-image-element.vala
@@ -21,6 +21,9 @@
  */
 public class Ease.ImageElement : MediaElement
 {
+	private const string UI_FILE_PATH = "inspector-element-image.ui";
+	private Gtk.Widget inspector_pane;
+	
 	/**
 	 * Create a new element.
 	 */
@@ -38,6 +41,49 @@ public class Ease.ImageElement : MediaElement
 		return new ImageActor(this, c);
 	}
 	
+	public override Gtk.Widget inspector_widget()
+	{
+		if (inspector_pane != null) return inspector_pane;
+		
+		var builder = new Gtk.Builder();
+		try
+		{
+			builder.add_from_file(data_path(Path.build_filename(Temp.UI_DIR,
+				                                                UI_FILE_PATH)));
+		}
+		catch (Error e) { error("Error loading UI: %s", e.message); }
+		
+		// connect signals
+		builder.connect_signals(this);
+		
+		// set up the file button
+		var file_b = builder.get_object("file-button") as Gtk.FileChooserButton;
+		file_b.set_filename(source_filename);
+		
+		file_b.file_set.connect((button) => {
+			// create an undo action to redo the old file
+			var action = new UndoAction(this, "filename");
+			action.add(this, "source-filename");
+			try
+			{
+				filename = parent.parent.add_media_file(file_b.get_filename());
+				source_filename = file_b.get_filename();
+				(widget_window(button) as EditorWindow).add_undo_action(action);
+			}
+			catch (Error e)
+			{
+				error_dialog(_("Error Inserting Image"), e.message);
+			}
+		});
+		
+		notify["source-filename"].connect((obj, spec) => {
+			file_b.set_filename(source_filename);
+		});
+		
+		// return the root
+		return inspector_pane = builder.get_object("root") as Gtk.Widget;
+	}
+	
 	public override void write_html(ref string html, HTMLExporter exporter)
 	{
 		// open the img tag
diff --git a/src/ease-inspector-element-pane.vala b/src/ease-inspector-element-pane.vala
new file mode 100644
index 0000000..2e3f7dc
--- /dev/null
+++ b/src/ease-inspector-element-pane.vala
@@ -0,0 +1,68 @@
+/*  Ease, a GTK presentation application
+    Copyright (C) 2010 Nate Stedman
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+internal class Ease.InspectorElementPane : InspectorPane
+{
+	private Gtk.Widget none;
+	private Gtk.Widget current;
+	private const string UI_FILE_PATH = "inspector-element-none.ui";
+	
+	internal InspectorElementPane()
+	{
+		// build the "nothing selected" widget
+		var builder = new Gtk.Builder();
+		try
+		{
+			builder.add_from_file(data_path(Path.build_filename(Temp.UI_DIR,
+				                                                UI_FILE_PATH)));
+		}
+		catch (Error e) { error("Error loading UI: %s", e.message); }
+		none = builder.get_object("root") as Gtk.Widget;
+		
+		// add the "nothing selected" widget
+		pack_start(none, true, true, 0);
+	}
+	
+	internal void on_element_selected(Element selected)
+	{
+		if (current != null)
+		{
+		 	if (current.get_parent() == this) remove(current);
+		}
+		else if (none.get_parent() == this) remove(none);
+		current = selected.inspector_widget();
+		pack_start(current, false, false, 0);
+	}
+	
+	internal void on_element_deselected(Element? deselected)
+	{
+		if (none.get_parent() != this) pack_start(none, true, true, 0);
+		none.show();
+		if (current != null)
+		{
+			if (current.get_parent() == this) remove(current);
+		}
+		current = null;
+	}
+	
+	internal override void slide_updated()
+	{
+		if (none.get_parent() != this) pack_start(none, true, true, 0);
+		if (current == null) return;
+		if (current.get_parent() == this) remove(current);
+	}
+}
diff --git a/src/ease-slide-pane.vala b/src/ease-inspector-slide-pane.vala
similarity index 99%
rename from src/ease-slide-pane.vala
rename to src/ease-inspector-slide-pane.vala
index 9844002..188f77f 100644
--- a/src/ease-slide-pane.vala
+++ b/src/ease-inspector-slide-pane.vala
@@ -18,7 +18,7 @@
 /**
  * The inspector pane concerning slides
  */
-public class Ease.SlidePane : InspectorPane
+public class Ease.InspectorSlidePane : InspectorPane
 {
 	private const string UI_FILE_PATH = "inspector-slide.ui";
 	private const string BG_DIALOG_TITLE = _("Select Background Image");
@@ -38,7 +38,7 @@ public class Ease.SlidePane : InspectorPane
 	
 	private bool silence_undo;
 
-	public SlidePane()
+	public InspectorSlidePane()
 	{	
 		base();
 		
diff --git a/src/ease-transition-pane.vala b/src/ease-inspector-transition-pane.vala
similarity index 99%
rename from src/ease-transition-pane.vala
rename to src/ease-inspector-transition-pane.vala
index eee6688..acf9274 100644
--- a/src/ease-transition-pane.vala
+++ b/src/ease-inspector-transition-pane.vala
@@ -19,7 +19,7 @@
 /**
  * The inspector pane for changing transitions
  */
-public class Ease.TransitionPane : InspectorPane
+public class Ease.InspectorTransitionPane : InspectorPane
 {
 	public Gtk.ComboBox effect;
 	private Gtk.SpinButton transition_time;
@@ -46,7 +46,7 @@ public class Ease.TransitionPane : InspectorPane
 	// silence undo if needed
 	private bool silence_undo;
 	
-	public TransitionPane()
+	public InspectorTransitionPane()
 	{
 		base();
 		
diff --git a/src/ease-inspector.vala b/src/ease-inspector.vala
index 9a85051..0ac9ea7 100644
--- a/src/ease-inspector.vala
+++ b/src/ease-inspector.vala
@@ -20,8 +20,9 @@
  */
 public class Ease.Inspector : Gtk.Notebook, UndoSource
 {
-	private TransitionPane transition_pane;
-	private SlidePane slide_pane;
+	private InspectorTransitionPane transition_pane;
+	private InspectorSlidePane slide_pane;
+	internal InspectorElementPane element_pane;
 	
 	// constants
 	private const int REQUEST_WIDTH = 200;
@@ -46,13 +47,16 @@ public class Ease.Inspector : Gtk.Notebook, UndoSource
 	{
 		set_size_request(REQUEST_WIDTH, REQUEST_HEIGHT);
 	
-		transition_pane = new TransitionPane();
-		slide_pane = new SlidePane();
+		transition_pane = new InspectorTransitionPane();
+		element_pane = new InspectorElementPane();
+		slide_pane = new InspectorSlidePane();
 		
 		// add pages
 		append(slide_pane, "gtk-page-setup");
+		append(element_pane, "gtk-index");
 		append(transition_pane, "gtk-media-forward");
 		slide_pane.show();
+		element_pane.show_all();
 		transition_pane.show_all();
 	}
 	
diff --git a/src/ease-media-element.vala b/src/ease-media-element.vala
index df34b06..51f0b98 100644
--- a/src/ease-media-element.vala
+++ b/src/ease-media-element.vala
@@ -27,6 +27,7 @@ public abstract class Ease.MediaElement : Element
 	{
 		base.from_json(obj);
 		filename = obj.get_string_member(Theme.MEDIA_FILENAME);
+		source_filename = obj.get_string_member(Theme.MEDIA_SOURCE_FILENAME);
 	}
 	
 	public override Json.Object to_json()
@@ -34,6 +35,7 @@ public abstract class Ease.MediaElement : Element
 		var obj = base.to_json();
 		
 		obj.set_string_member(Theme.MEDIA_FILENAME, filename);
+		obj.set_string_member(Theme.MEDIA_SOURCE_FILENAME, source_filename);
 		
 		return obj;
 	}
@@ -44,6 +46,11 @@ public abstract class Ease.MediaElement : Element
 	public string filename { get; set; }
 	
 	/**
+	 * The path where the media file was originally found.
+	 */
+	public string source_filename { get; set; }
+	
+	/**
 	 * The full path to a media file.
 	 */
 	public string full_filename
diff --git a/src/ease-text-actor.vala b/src/ease-text-actor.vala
index 42a1bad..a54998b 100644
--- a/src/ease-text-actor.vala
+++ b/src/ease-text-actor.vala
@@ -70,6 +70,14 @@ public class Ease.TextActor : Actor
 		e.notify["font-description"].connect((sender, spec) => {
 			format(element as TextElement);
 		});
+		
+		e.notify["text-align"].connect((sender, spec) => {
+			text.line_alignment = e.text_align;
+		});
+		
+		e.notify["color"].connect((sender, spec) => {
+			text.color = e.color.clutter;
+		});
 	}
 	
 	private void format(TextElement e)
diff --git a/src/ease-text-element.vala b/src/ease-text-element.vala
index d73fad9..b8de459 100644
--- a/src/ease-text-element.vala
+++ b/src/ease-text-element.vala
@@ -20,7 +20,9 @@
  */
 public class Ease.TextElement : Element
 {
+	private const string UI_FILE_PATH = "inspector-element-text.ui";
 	private bool freeze = false;
+	private Gtk.Widget inspector_pane;
 	
 	/**
 	 * Creates a new TextElement.
@@ -83,7 +85,116 @@ public class Ease.TextElement : Element
 	{
 		return color.clutter;
 	}
-
+	
+	public override Gtk.Widget inspector_widget()
+	{
+		if (inspector_pane != null) return inspector_pane;
+		
+		var builder = new Gtk.Builder();
+		try
+		{
+			builder.add_from_file(data_path(Path.build_filename(Temp.UI_DIR,
+				                                                UI_FILE_PATH)));
+		}
+		catch (Error e) { error("Error loading UI: %s", e.message); }
+		
+		// connect signals
+		builder.connect_signals(this);
+		
+		// get the alignment buttons
+		var left = builder.get_object("left-button") as Gtk.Button;
+		var center = builder.get_object("center-button") as Gtk.Button;
+		var right = builder.get_object("right-button") as Gtk.Button;
+		
+		// highlight the current alignment
+		switch (text_align)
+		{
+			case Pango.Alignment.LEFT:
+				left.relief = Gtk.ReliefStyle.NORMAL;
+				break;
+			case Pango.Alignment.CENTER:
+				center.relief = Gtk.ReliefStyle.NORMAL;
+				break;
+			case Pango.Alignment.RIGHT:
+				right.relief = Gtk.ReliefStyle.NORMAL;
+				break;
+		}
+		
+		// when the alignment is changed, select the correct button
+		notify["text-align"].connect((obj, spec) => {
+			switch (text_align)
+			{
+				case Pango.Alignment.LEFT:
+					left.relief = Gtk.ReliefStyle.NORMAL;
+					center.relief = Gtk.ReliefStyle.NONE;
+					right.relief = Gtk.ReliefStyle.NONE;
+					break;
+				case Pango.Alignment.CENTER:
+					left.relief = Gtk.ReliefStyle.NONE;
+					center.relief = Gtk.ReliefStyle.NORMAL;
+					right.relief = Gtk.ReliefStyle.NONE;
+					break;
+				case Pango.Alignment.RIGHT:
+					left.relief = Gtk.ReliefStyle.NONE;
+					center.relief = Gtk.ReliefStyle.NONE;
+					right.relief = Gtk.ReliefStyle.NORMAL;
+					break;
+			}
+		});
+		
+		// set up the font button
+		var font = builder.get_object("font-button") as Gtk.FontButton;
+		font.set_font_name(font_description.to_string());
+		
+		font.font_set.connect((button) => {
+			var action = new UndoAction(this, "font-description");
+			(widget_window(button) as EditorWindow).add_undo_action(action);
+			font_description =
+				Pango.FontDescription.from_string(font.font_name);
+		});
+		
+		notify["font-description"].connect((obj, spec) => {
+			font.set_font_name(font_description.to_string());
+		});
+		
+		// set up the color button
+		var color_b = builder.get_object("color-button") as Gtk.ColorButton;
+		color_b.set_color(color.gdk);
+		
+		color_b.color_set.connect((button) => {
+			var action = new UndoAction(this, "color");
+			(widget_window(button) as EditorWindow).add_undo_action(action);
+			color = new Color.from_gdk(color_b.color);
+		});
+		
+		notify["color"].connect((obj, spec) => {
+			color_b.color = color.gdk;
+		});
+		
+		// return the root
+		return inspector_pane = builder.get_object("root") as Gtk.Widget;
+	}
+	
+	[CCode (instance_pos = -1)]
+	public void on_inspector_alignment(Gtk.Widget sender)
+	{
+		(sender.get_parent() as Gtk.Container).foreach((widget) => {
+			(widget as Gtk.Button).relief = Gtk.ReliefStyle.NONE;
+		});
+		
+		(sender as Gtk.Button).relief = Gtk.ReliefStyle.NORMAL;
+		
+		var action = new UndoAction(this, "text-align");
+		var old = text_align;
+		
+		text_align_from_string(
+			(((sender as Gtk.Bin).get_child() as Gtk.Image).stock));
+		
+		if (text_align != old)
+		{
+			(widget_window(sender) as EditorWindow).add_undo_action(action);
+		}
+	}
 
 	protected override void write_html(ref string html, HTMLExporter exporter)
 	{
@@ -303,12 +414,15 @@ public class Ease.TextElement : Element
 		switch (str)
 		{
 			case "right":
+			case "gtk-justify-right":
 				text_align = Pango.Alignment.RIGHT;
 				break;
 			case "center":
+			case "gtk-justify-center":
 				text_align = Pango.Alignment.CENTER;
 				break;
 			case "left":
+			case "gtk-justify-left":
 				text_align = Pango.Alignment.LEFT;
 				break;
 			default:
diff --git a/src/ease-theme.vala b/src/ease-theme.vala
index a89226b..72a1ea9 100644
--- a/src/ease-theme.vala
+++ b/src/ease-theme.vala
@@ -90,6 +90,7 @@ public class Ease.Theme : GLib.Object
 	
 	// media properties
 	public const string MEDIA_FILENAME = "media-filename";
+	public const string MEDIA_SOURCE_FILENAME = "media-source-filename";
 	
 	// gradient types
 	public const string GRAD_LINEAR = "linear";



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