[ease] [editor] Allow the user to change backgrounds
- From: Nate Stedman <natesm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ease] [editor] Allow the user to change backgrounds
- Date: Sat, 24 Jul 2010 21:23:47 +0000 (UTC)
commit 31ee76fcdca1b426c84497eb46b7438ca7ea67f4
Author: Nate Stedman <natesm gmail com>
Date: Sat Jul 24 17:18:46 2010 -0400
[editor] Allow the user to change backgrounds
- Added slide/background pane with GtkBuilder
- Undo support for all background changes
- Load images as a background
Makefile.am | 3 +-
data/themes/build.sh | 2 +-
data/ui/inspector-slide.ui | 315 +++++++++++++++++++++++++++++++++++++
src/ease-color.vala | 42 +++++-
src/ease-editor-window.vala | 6 +-
src/ease-gradient.vala | 55 +++++++
src/ease-inspector-pane.vala | 15 +--
src/ease-inspector.vala | 19 ++-
src/ease-json-parser.vala | 8 +-
src/ease-slide-actor.vala | 7 +-
src/ease-slide-pane.vala | 351 ++++++++++++++++++++++++++++++++++++++----
src/ease-slide.vala | 63 ++++----
src/ease-theme.vala | 3 +
src/ease-undo-action.vala | 16 ++
src/ease-undo-source.vala | 29 ++++
src/ease-utilities.vala | 9 +
16 files changed, 851 insertions(+), 92 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 6fee01c..823b546 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -53,6 +53,7 @@ ease_SOURCES = \
src/ease-transitions.vala \
src/ease-undo-action.vala \
src/ease-undo-controller.vala \
+ src/ease-undo-source.vala \
src/ease-utilities.vala \
src/ease-welcome-actor.vala \
src/ease-welcome-window.vala \
@@ -95,7 +96,7 @@ doc: src/*.vala
valadoc --internal --private --pkg "json-glib-1.0" --pkg "gee-1.0" --pkg "clutter-gtk-0.10" --pkg "libarchive" --directory=./doc --basedir=src ./src/*.vala
gnome-open doc/doc/Ease.html
-archive: themes/* examples/*
+archive: data/themes/* examples/*
sh data/themes/build.sh
sh examples/build.sh
diff --git a/data/themes/build.sh b/data/themes/build.sh
index 91546aa..ae8b6e7 100755
--- a/data/themes/build.sh
+++ b/data/themes/build.sh
@@ -2,7 +2,7 @@
echo " Archiving themes..."
-cd themes
+cd data/themes
for THEME in `find ./* -maxdepth 0 -type d | sed "s/.\///g"`
do
diff --git a/data/ui/inspector-slide.ui b/data/ui/inspector-slide.ui
new file mode 100644
index 0000000..b4dcbab
--- /dev/null
+++ b/data/ui/inspector-slide.ui
@@ -0,0 +1,315 @@
+<?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="vbox-root">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">10</property>
+ <child>
+ <object class="GtkVBox" id="vbox-style">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkHBox" id="hbox-style">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="style-label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Background Style</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="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"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox-color">
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="color-label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Background Color</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="GtkColorButton" id="color-color">
+ <property name="height_request">30</property>
+ <property name="visible">True</property>
+ <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"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox-gradient">
+ <property name="orientation">vertical</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkHBox" id="hbox3">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="gradient-label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Background Gradient</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="GtkHBox" id="hbox4">
+ <property name="visible">True</property>
+ <property name="spacing">4</property>
+ <child>
+ <object class="GtkColorButton" id="color-startgradient">
+ <property name="visible">True</property>
+ <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"/>
+ </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-endgradient">
+ <property name="visible">True</property>
+ <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"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <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"/>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="button-reverse">
+ <property name="label" translatable="yes">Reverse Gradient</property>
+ <property name="height_request">30</property>
+ <property name="visible">True</property>
+ <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"/>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkHBox" id="hbox5">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="label-angle">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Gradient Angle</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="GtkHScale" id="hscale-angle">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="adjustment">adjustment-angle</property>
+ <property name="draw_value">False</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">10</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox-image">
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkHBox" id="hbox1">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="image-label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Background 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="button-image">
+ <property name="height_request">30</property>
+ <property name="visible">True</property>
+ <signal name="file_set" handler="ease_slide_pane_on_file_set"/>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ <object class="GtkAdjustment" id="adjustment-angle">
+ <property name="upper">6.2800000000000002</property>
+ <property name="step_increment">0.10000000000000001</property>
+ <property name="page_increment">1</property>
+ <property name="page_size">1</property>
+ </object>
+</interface>
diff --git a/src/ease-color.vala b/src/ease-color.vala
index e0b0fc2..0ac068f 100644
--- a/src/ease-color.vala
+++ b/src/ease-color.vala
@@ -29,6 +29,22 @@ public class Ease.Color : GLib.Object
* The string placed between each channel in a string representation.
*/
private const string SPLIT = ",";
+
+ /**
+ * A color with the values (1, 1, 1, 1).
+ */
+ public static Color white
+ {
+ owned get { return new Color.rgb(1, 1, 1); }
+ }
+
+ /**
+ * A color with the values (0, 0, 0, 1).
+ */
+ public static Color black
+ {
+ owned get { return new Color.rgb(0, 0, 0); }
+ }
/**
* The red value of this color.
@@ -155,7 +171,7 @@ public class Ease.Color : GLib.Object
get
{
return { 0,
- (uint16)(255 * red),
+ (uint16)(65535 * red),
(uint16)(65535 * green),
(uint16)(65535 * blue) };
}
@@ -234,7 +250,15 @@ public class Ease.Color : GLib.Object
*/
public string to_string()
{
- return STR.printf(red, SPLIT, blue, SPLIT, green, SPLIT, alpha);
+ return STR.printf(red, SPLIT, green, SPLIT, blue, SPLIT, alpha);
+ }
+
+ /**
+ * Returns a copy of this Color
+ */
+ public Color copy()
+ {
+ return new Color.rgba(red, green, blue, alpha);
}
/**
@@ -246,4 +270,18 @@ public class Ease.Color : GLib.Object
{
cr.set_source_rgba(red, green, blue, alpha);
}
+
+ /**
+ * Returns an { link UndoAction} that will restore this Color to its current
+ * state.
+ */
+ public UndoAction undo_action()
+ {
+ var action = new UndoAction(this, "red");
+ action.add(this, "green");
+ action.add(this, "blue");
+ action.add(this, "alpha");
+
+ return action;
+ }
}
diff --git a/src/ease-editor-window.vala b/src/ease-editor-window.vala
index 8d0d9b3..0fd3bd2 100644
--- a/src/ease-editor-window.vala
+++ b/src/ease-editor-window.vala
@@ -152,6 +152,7 @@ public class Ease.EditorWindow : Gtk.Window
// the inspector
inspector = new Inspector();
(builder.get_object("Inspector Align") as Gtk.Alignment).add(inspector);
+ inspector.undo.connect((action) => add_undo_action(action));
// main editor
embed = new EditorEmbed(document, this);
@@ -175,8 +176,9 @@ public class Ease.EditorWindow : Gtk.Window
menu.show_all();
// final window setup
- show_all();
- embed.show();
+ slide_button_panel.show_all();
+ embed.show_all();
+ show();
inspector.hide();
slides_shown = true;
diff --git a/src/ease-gradient.vala b/src/ease-gradient.vala
index 80d9ca6..6595f7e 100644
--- a/src/ease-gradient.vala
+++ b/src/ease-gradient.vala
@@ -51,6 +51,14 @@ public class Ease.Gradient : GLib.Object
public double angle { get; set; }
/**
+ * Returns a copy of the default background gradient.
+ */
+ public static Gradient default_background
+ {
+ owned get { return new Gradient(Color.black, Color.white); }
+ }
+
+ /**
* Creates a new linear gradient, with the specified colors.
*/
public Gradient(Color start_color, Color end_color)
@@ -58,6 +66,7 @@ public class Ease.Gradient : GLib.Object
start = start_color;
end = end_color;
mode = GradientMode.LINEAR;
+ angle = 0;
}
/**
@@ -67,6 +76,7 @@ public class Ease.Gradient : GLib.Object
{
this(start_color, end_color);
mode = GradientMode.LINEAR_MIRRORED;
+ angle = 0;
}
/**
@@ -76,6 +86,7 @@ public class Ease.Gradient : GLib.Object
{
this(start_color, end_color);
mode = GradientMode.RADIAL;
+ angle = 0;
}
/**
@@ -102,6 +113,17 @@ public class Ease.Gradient : GLib.Object
}
/**
+ * Returns a copy of this Gradient.
+ */
+ public Gradient copy()
+ {
+ var grad = new Gradient(start.copy(), end.copy());
+ grad.mode = mode;
+ grad.angle = angle;
+ return grad;
+ }
+
+ /**
* Reverses the Gradient.
*/
public void flip()
@@ -211,4 +233,37 @@ public enum Ease.GradientMode
warning("%s is not a gradient type", str);
return LINEAR;
}
+
+ /**
+ * Returns a string description of the GradientMode
+ */
+ public string description()
+ {
+ switch (this)
+ {
+ case LINEAR: return _("Linear");
+ case LINEAR_MIRRORED: return _("Mirrored Linear");
+ case RADIAL: return _("Radial");
+ }
+ return "undefined";
+ }
+
+ /**
+ * Creates a ListStore with the first column set as the description
+ * and the second column set as the GradientMode.
+ */
+ public static Gtk.ListStore list_store()
+ {
+ var store = new Gtk.ListStore(2, typeof(string), typeof(GradientMode));
+ Gtk.TreeIter itr;
+
+ store.append(out itr);
+ store.set(itr, 0, LINEAR.description(), 1, LINEAR);
+ store.append(out itr);
+ store.set(itr, 0, LINEAR_MIRRORED.description(), 1, LINEAR_MIRRORED);
+ store.append(out itr);
+ store.set(itr, 0, RADIAL.description(), 1, RADIAL);
+
+ return store;
+ }
}
diff --git a/src/ease-inspector-pane.vala b/src/ease-inspector-pane.vala
index a80c71a..b9a2c9d 100644
--- a/src/ease-inspector-pane.vala
+++ b/src/ease-inspector-pane.vala
@@ -18,23 +18,16 @@
/**
* Base class for inspector panes
*/
-public abstract class Ease.InspectorPane : Gtk.VBox
+public abstract class Ease.InspectorPane : Gtk.VBox, UndoSource
{
- private Slide slide_priv;
-
- public Slide slide
- {
- get { return slide_priv; }
- set {
- slide_priv = value;
- slide_updated();
- }
- }
+ public Slide slide { get; set; }
public InspectorPane()
{
homogeneous = false;
spacing = 0;
+
+ notify["slide"].connect((a, b) => slide_updated());
}
/**
diff --git a/src/ease-inspector.vala b/src/ease-inspector.vala
index 2a43815..9a85051 100644
--- a/src/ease-inspector.vala
+++ b/src/ease-inspector.vala
@@ -18,7 +18,7 @@
/**
* Inspector widget for editing slide properties
*/
-public class Ease.Inspector : Gtk.Notebook
+public class Ease.Inspector : Gtk.Notebook, UndoSource
{
private TransitionPane transition_pane;
private SlidePane slide_pane;
@@ -50,12 +50,17 @@ public class Ease.Inspector : Gtk.Notebook
slide_pane = new SlidePane();
// add pages
- append_page(slide_pane,
- new Gtk.Image.from_stock("gtk-page-setup",
- Gtk.IconSize.SMALL_TOOLBAR));
- append_page(transition_pane,
- new Gtk.Image.from_stock("gtk-media-forward",
- Gtk.IconSize.SMALL_TOOLBAR));
+ append(slide_pane, "gtk-page-setup");
+ append(transition_pane, "gtk-media-forward");
+ slide_pane.show();
+ transition_pane.show_all();
+ }
+
+ private void append(InspectorPane i, string stock_id)
+ {
+ append_page(i, new Gtk.Image.from_stock(stock_id,
+ Gtk.IconSize.SMALL_TOOLBAR));
+ i.undo.connect((action) => undo(action));
}
}
diff --git a/src/ease-json-parser.vala b/src/ease-json-parser.vala
index cbf28c1..0e66e5b 100644
--- a/src/ease-json-parser.vala
+++ b/src/ease-json-parser.vala
@@ -97,18 +97,20 @@ public static class Ease.JSONParser
{
slide.background_image =
obj.get_string_member(Theme.BACKGROUND_IMAGE);
+ slide.background_image_source =
+ obj.get_string_member("background-image-source");
}
if (obj.has_member(Theme.BACKGROUND_COLOR))
{
slide.background_color =
new Color.from_string(
- obj.get_string_member(Theme.BACKGROUND_COLOR));
+ obj.get_string_member(Theme.BACKGROUND_COLOR));
}
if (obj.has_member(Theme.BACKGROUND_GRADIENT))
{
slide.background_gradient =
new Gradient.from_string(
- obj.get_string_member(Theme.BACKGROUND_GRADIENT));
+ obj.get_string_member(Theme.BACKGROUND_GRADIENT));
}
slide.background_type = BackgroundType.from_string(
obj.get_string_member(Theme.BACKGROUND_TYPE));
@@ -211,6 +213,8 @@ public static class Ease.JSONParser
{
obj.set_string_member(Theme.BACKGROUND_IMAGE,
slide.background_image);
+ obj.set_string_member("background-image-source",
+ slide.background_image_source);
}
if (slide.background_color != null)
{
diff --git a/src/ease-slide-actor.vala b/src/ease-slide-actor.vala
index 0f8a87f..b2c7704 100644
--- a/src/ease-slide-actor.vala
+++ b/src/ease-slide-actor.vala
@@ -162,6 +162,7 @@ public class Ease.SlideActor : Clutter.Group
// set the background
set_background();
+ add_actor(background);
contents = new Clutter.Group();
@@ -171,6 +172,9 @@ public class Ease.SlideActor : Clutter.Group
}
add_actor(contents);
+
+ // TODO: this completely _destroys_ performance.
+ slide.changed.connect((s) => set_background());
}
/**
@@ -263,9 +267,6 @@ public class Ease.SlideActor : Clutter.Group
background.width = width_px;
background.height = height_px;
-
- add_actor(background);
- lower_child(background, null);
}
/**
diff --git a/src/ease-slide-pane.vala b/src/ease-slide-pane.vala
index a47d8d8..2cc9dc5 100644
--- a/src/ease-slide-pane.vala
+++ b/src/ease-slide-pane.vala
@@ -20,41 +20,332 @@
*/
public class Ease.SlidePane : InspectorPane
{
- public Gtk.ComboBox effect;
- public Gtk.SpinButton duration;
- public Gtk.ComboBox variant;
- public Gtk.Label variant_label;
- public Gtk.ComboBox start_transition;
- public Gtk.SpinButton delay;
+ private const string UI_FILE_PATH = "inspector-slide.ui";
+ private const string BG_DIALOG_TITLE = _("Select Background Image");
+
+ private Gtk.ComboBox background;
+ private Gtk.ListStore store;
+ private Gtk.ComboBox gradient_type;
+ private Gtk.ListStore grad_store = GradientMode.list_store();
+ private Gtk.VBox box_color;
+ private Gtk.VBox box_gradient;
+ private Gtk.VBox box_image;
+
+ private Gtk.ColorButton bg_color;
+ private Gtk.ColorButton grad_color1;
+ private Gtk.ColorButton grad_color2;
+ private Gtk.FileChooserButton bg_image;
+
+ private bool silence_undo;
public SlidePane()
{
base();
- // effect selection
- var vbox = new Gtk.VBox(false, 0);
- var hbox = new Gtk.HBox(false, 0);
- var align = new Gtk.Alignment(0, 0, 0, 0);
- align.add(new Gtk.Label(_("Effect")));
- vbox.pack_start(align, false, false, 0);
- effect = new Gtk.ComboBox();
- align = new Gtk.Alignment(0, 0, 1, 1);
- align.add(effect);
- vbox.pack_start(align, false, false, 0);
- hbox.pack_start(vbox, true, true, 5);
-
- // effect duration
- vbox = new Gtk.VBox(false, 0);
- align = new Gtk.Alignment(0, 0, 0, 0);
- align.add(new Gtk.Label(_("Duration")));
- vbox.pack_start(align, false, false, 0);
- duration = new Gtk.SpinButton.with_range(0, 10, 0.25);
- duration.digits = 2;
- align = new Gtk.Alignment(0, 0.5f, 1, 1);
- align.add(duration);
- vbox.pack_start(align, true, true, 0);
- hbox.pack_start(vbox, false, false, 5);
- pack_start(hbox, false, false, 5);
+ // load the GtkBuilder file
+ 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);
+
+ // add the root of the builder file to this widget
+ pack_start(builder.get_object("root") as Gtk.Widget, true, true, 0);
+
+ // get controls
+ box_color = builder.get_object("vbox-color") as Gtk.VBox;
+ box_gradient = builder.get_object("vbox-gradient") as Gtk.VBox;
+ box_image = builder.get_object("vbox-image") as Gtk.VBox;
+ bg_color = builder.get_object("color-color") as Gtk.ColorButton;
+ grad_color1 =
+ builder.get_object("color-startgradient") as Gtk.ColorButton;
+ grad_color2 =
+ builder.get_object("color-endgradient") as Gtk.ColorButton;
+ bg_image =
+ builder.get_object("button-image") as Gtk.FileChooserButton;
+ gradient_type =
+ builder.get_object("combo-gradient") as Gtk.ComboBox;
+
+ // set up the gradient type combobox
+ gradient_type.model = grad_store;
+
+ // get the combobox
+ background = builder.get_object("combobox-style") as Gtk.ComboBox;
+
+ // build a liststore for the combobox
+ store = new Gtk.ListStore(2, typeof(string), typeof(BackgroundType));
+ Gtk.TreeIter iter;
+ foreach (var b in BackgroundType.TYPES)
+ {
+ store.append(out iter);
+ store.set(iter, 0, b.description(), 1, b);
+ }
+
+ var render = new Gtk.CellRendererText();
+
+ background.pack_start(render, true);
+ background.set_attributes(render, "text", 0);
+
+ background.model = store;
+ }
+
+ private void emit_undo(UndoAction action)
+ {
+ if (!silence_undo) undo(action);
+ }
+
+ [CCode (instance_pos = -1)]
+ public void on_background_changed(Gtk.Widget? sender)
+ {
+ Gtk.TreeIter itr;
+ store.get_iter_first(out itr);
+
+ // find the correct position
+ for (int i = 0; i < background.active; i++) store.iter_next(ref itr);
+
+ // get the background type at that position
+ BackgroundType type;
+ store.get(itr, 1, out type);
+
+ // create an undo action
+ var action = new UndoAction(slide, "background-type");
+
+ // ease can't provide a default for images, so one must be requested
+ if (type == BackgroundType.IMAGE && slide.background_image == null)
+ {
+ var dialog = new Gtk.FileChooserDialog(BG_DIALOG_TITLE,
+ widget_window(this),
+ Gtk.FileChooserAction.OPEN,
+ "gtk-cancel",
+ Gtk.ResponseType.CANCEL,
+ "gtk-open",
+ Gtk.ResponseType.ACCEPT);
+ switch (dialog.run())
+ {
+ case Gtk.ResponseType.ACCEPT:
+ try
+ {
+ var fname = dialog.get_filename();
+ slide.background_image_source = fname;
+ var i = slide.parent.add_media_file(fname);
+ slide.background_image = i;
+ }
+ catch (GLib.Error e)
+ {
+ critical("Error adding background image: %s",
+ e.message);
+ }
+ dialog.destroy();
+ break;
+ case Gtk.ResponseType.CANCEL:
+ action.apply();
+ dialog.destroy();
+ return;
+ }
+ }
+
+ // when the action is applied, if the slide is still current, change ui
+ var local = slide;
+ action.applied.connect((a) => {
+ if (local == slide)
+ {
+ silence_undo = true;
+ background.set_active(slide.background_type);
+ display_bg_ui(slide.background_type);
+ silence_undo = false;
+ }
+ });
+
+ // add properties to the UndoAction and report it to the controller
+ switch (type)
+ {
+ case BackgroundType.COLOR:
+ action.add(slide, "background-color");
+ break;
+ case BackgroundType.GRADIENT:
+ action.add(slide, "background-gradient");
+ break;
+ case BackgroundType.IMAGE:
+ action.add(slide, "background-image");
+ break;
+ }
+ emit_undo(action);
+
+ // switch to that background type
+ display_bg_ui(type);
+ }
+
+ [CCode (instance_pos = -1)]
+ public void on_gradient_type_changed(Gtk.ComboBox? sender)
+ {
+ emit_undo(new UndoAction(slide.background_gradient, "mode"));
+ slide.background_gradient.mode = (GradientMode)sender.get_active();
+ slide.changed(slide);
+ }
+
+ [CCode (instance_pos = -1)]
+ public void on_color_set(Gtk.ColorButton? sender)
+ {
+ if (sender == bg_color)
+ {
+ emit_undo(slide.background_color.undo_action());
+ slide.background_color.gdk = sender.color;
+ }
+ else if (sender == grad_color1)
+ {
+ emit_undo(slide.background_gradient.start.undo_action());
+ slide.background_gradient.start.gdk = sender.color;
+ }
+ else if (sender == grad_color2)
+ {
+ emit_undo(slide.background_gradient.end.undo_action());
+ slide.background_gradient.end.gdk = sender.color;
+ }
+ slide.changed(slide);
+ }
+
+ [CCode (instance_pos = -1)]
+ public void on_file_set(Gtk.FileChooserButton? sender)
+ {
+ var action = new UndoAction(slide, "background-image");
+ action.add(slide, "background-image-source");
+
+ // slide might change in the meantime
+ var local = slide;
+
+ // set the button's filename when the action is applied
+ action.applied.connect((a) => {
+ // if slide changes, this is still ok
+ if (slide.background_image_source != null)
+ {
+ bg_image.set_filename(slide.background_image_source);
+ }
+ else
+ {
+ bg_image.unselect_all();
+ }
+ local.changed(local);
+ display_bg_ui(slide.background_type);
+ });
+
+ try
+ {
+ slide.background_image_source = sender.get_filename();
+ var i = slide.parent.add_media_file(sender.get_filename());
+ slide.background_image = i;
+ }
+ catch (GLib.Error e)
+ {
+ critical("Error adding background image: %s", e.message);
+ }
+
+ slide.changed(slide);
+
+ emit_undo(action);
+ }
+
+ [CCode (instance_pos = -1)]
+ public void on_reverse_gradient(Gtk.Widget? sender)
+ {
+ // create an undo action
+ var action = new UndoAction(slide.background_gradient, "start");
+ action.add(slide.background_gradient, "end");
+
+ // flip the gradient
+ slide.background_gradient.flip();
+
+ // update the ui
+ grad_color1.set_color(slide.background_gradient.start.gdk);
+ grad_color2.set_color(slide.background_gradient.end.gdk);
+ slide.changed(slide);
+
+ // add the undo action
+ emit_undo(action);
+ }
+
+ protected override void slide_updated()
+ {
+ silence_undo = true;
+
+ // set the combo box to the slide's active background type
+ background.set_active(slide.background_type);
+
+ // set the gradient box to the correct mode
+ if (slide.background_gradient != null)
+ {
+ gradient_type.set_active(slide.background_gradient.mode);
+ }
+
+ display_bg_ui(slide.background_type);
+
+ silence_undo = false;
+ }
+
+ private void display_bg_ui(BackgroundType type)
+ {
+ switch (type)
+ {
+ case BackgroundType.COLOR:
+ box_color.show_all();
+ box_gradient.hide_all();
+ box_image.hide_all();
+
+ if (slide.background_color == null)
+ {
+ slide.background_color = Color.white;
+ }
+ slide.background_type = BackgroundType.COLOR;
+
+ bg_color.set_color(slide.background_color.gdk);
+
+ slide.changed(slide);
+
+ break;
+
+ case BackgroundType.GRADIENT:
+ box_color.hide_all();
+ box_gradient.show_all();
+ box_image.hide_all();
+
+ if (slide.background_gradient == null)
+ {
+ slide.background_gradient = new Gradient(Color.black,
+ Color.white);
+ gradient_type.set_active(slide.background_gradient.mode);
+ }
+ slide.background_type = BackgroundType.GRADIENT;
+
+ grad_color1.set_color(slide.background_gradient.start.gdk);
+ grad_color2.set_color(slide.background_gradient.end.gdk);
+
+ slide.changed(slide);
+
+ break;
+
+ case BackgroundType.IMAGE:
+ box_color.hide_all();
+ box_gradient.hide_all();
+ box_image.show_all();
+
+ slide.background_type = BackgroundType.IMAGE;
+ if (slide.background_image_source != null)
+ {
+ bg_image.set_filename(slide.background_image_source);
+ }
+ else
+ {
+ bg_image.unselect_all();
+ }
+
+ slide.changed(slide);
+
+ break;
+ }
}
}
diff --git a/src/ease-slide.vala b/src/ease-slide.vala
index 375bbab..79d7f21 100644
--- a/src/ease-slide.vala
+++ b/src/ease-slide.vala
@@ -63,58 +63,39 @@ public class Ease.Slide : GLib.Object
*/
public double advance_delay { get; set; }
+ /**
+ * The background type of this slide.
+ */
public BackgroundType background_type { get; set; }
/**
* The background color, if this slide uses a solid color for a background.
*
- * Setting this property sets { link background_type} to
+ * To use this property, { link background_type} must also be set to
* { link BackgroundType.COLOR}.
*/
- public Color background_color
- {
- get { return background_color_priv; }
- set
- {
- background_color_priv = value;
- background_type = BackgroundType.COLOR;
- }
- }
- private Color background_color_priv;
+ public Color? background_color { get; set; }
/**
* The background gradient, if this slide uses a gradient for a background.
*
- * Setting this property sets { link background_type} to
+ * To use this property, { link background_type} must also be set to
* { link BackgroundType.GRADIENT}.
*/
- public Gradient background_gradient
- {
- get { return background_gradient_priv; }
- set
- {
- background_gradient_priv = value;
- background_type = BackgroundType.GRADIENT;
- }
- }
- private Gradient background_gradient_priv;
+ public Gradient? background_gradient { get; set; }
/**
* The background image, if this slide uses an image for a background.
*
- * Setting this property sets { link background_type} to
+ * To use this property, { link background_type} must also be set to
* { link BackgroundType.IMAGE}.
*/
- public string background_image
- {
- get { return background_image_priv; }
- set
- {
- background_image_priv = value;
- background_type = BackgroundType.IMAGE;
- }
- }
- private string background_image_priv;
+ public string background_image { get; set; }
+
+ /**
+ * The original path to the background image. This path is used in the UI.
+ */
+ public string background_image_source { get; set; }
/**
* The absolute path of the background image, if one is set.
@@ -394,6 +375,8 @@ public enum Ease.BackgroundType
GRADIENT,
IMAGE;
+ public const BackgroundType[] TYPES = { COLOR, GRADIENT, IMAGE};
+
/**
* Returns a string representation of this BackgroundType.
*/
@@ -423,5 +406,19 @@ public enum Ease.BackgroundType
warning("%s is not a gradient type", str);
return COLOR;
}
+
+ /**
+ * Returns a description of the BackgroundType.
+ */
+ public string description()
+ {
+ switch (this)
+ {
+ case COLOR: return _("Solid Color");
+ case GRADIENT: return _("Gradient");
+ case IMAGE: return _("Image");
+ }
+ return "undefined";
+ }
}
diff --git a/src/ease-theme.vala b/src/ease-theme.vala
index e0fd28d..a051472 100644
--- a/src/ease-theme.vala
+++ b/src/ease-theme.vala
@@ -327,13 +327,16 @@ public class Ease.Theme : GLib.Object
case BACKGROUND_TYPE_COLOR:
slide.background_color = new Color.
from_string(master_get(master, BACKGROUND_COLOR));
+ slide.background_type = BackgroundType.COLOR;
break;
case BACKGROUND_TYPE_GRADIENT:
slide.background_gradient = new Gradient.
from_string(master_get(master, BACKGROUND_GRADIENT));
+ slide.background_type = BackgroundType.GRADIENT;
break;
case BACKGROUND_TYPE_IMAGE:
slide.background_image = master_get(master, BACKGROUND_IMAGE);
+ slide.background_type = BackgroundType.IMAGE;
break;
}
diff --git a/src/ease-undo-action.vala b/src/ease-undo-action.vala
index fa39ba7..472022a 100644
--- a/src/ease-undo-action.vala
+++ b/src/ease-undo-action.vala
@@ -26,6 +26,11 @@ public class Ease.UndoAction : Object
private Gee.LinkedList<UndoPair> pairs = new Gee.LinkedList<UndoPair>();
/**
+ * Emitted after the action is applied.
+ */
+ public signal void applied(UndoAction sender);
+
+ /**
* Creates an UndoAction.
*
* This should be followed up with calls to add() if the action has
@@ -51,6 +56,16 @@ public class Ease.UndoAction : Object
}
/**
+ * Adds all properties of the given UndoAction to this action.
+ *
+ * @param action An UndoAction to add properties from.
+ */
+ public void combine(UndoAction action)
+ {
+ foreach (var p in action.pairs) pairs.add(p);
+ }
+
+ /**
* Applies the { link UndoAction}, restoring previous settings.
*
* Returns an UndoAction that will redo the undo action.
@@ -58,6 +73,7 @@ public class Ease.UndoAction : Object
public UndoAction apply()
{
foreach (var pair in pairs) pair.apply();
+ applied(this);
return this;
}
diff --git a/src/ease-undo-source.vala b/src/ease-undo-source.vala
new file mode 100644
index 0000000..17e0f41
--- /dev/null
+++ b/src/ease-undo-source.vala
@@ -0,0 +1,29 @@
+/* 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/>.
+*/
+
+/**
+ * Provides a signal to notify a controller of UndoActions.
+ */
+public interface Ease.UndoSource : GLib.Object
+{
+ /**
+ * Classes that implement the UndoSource interface should use this signal
+ * to notify a parent controller (typically { link EditorWindow}) of a new
+ * UndoAction.
+ */
+ public signal void undo(UndoAction action);
+}
diff --git a/src/ease-utilities.vala b/src/ease-utilities.vala
index 060906c..0ecafb8 100644
--- a/src/ease-utilities.vala
+++ b/src/ease-utilities.vala
@@ -282,6 +282,15 @@ namespace Ease
{
return Transformations.gdk_color_to_clutter_color(theme_color(color));
}
+
+ /**
+ * Returns the parent window of the specified widget.
+ */
+ public Gtk.Window widget_window(Gtk.Widget widg)
+ {
+ while (widg.get_parent() != null) widg = widg.get_parent();
+ return widg as Gtk.Window;
+ }
public double dmax(double a, double b)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]