33
// TODO: This needs to be completely redone properly
34
// ie: more than 3 layers, scrolling, etc.
35
// is probably supposed to be a treeview?
36
35
[System.ComponentModel.ToolboxItem (true)]
37
public class LayersListWidget : Gtk.DrawingArea
36
public class LayersListWidget : ScrolledWindow
39
private int thumb_width = 56;
40
private int thumb_height = 42;
42
private Cairo.Rectangle layer1_bounds = new Cairo.Rectangle (0, 2, 175, 47);
43
private Cairo.Rectangle layer2_bounds = new Cairo.Rectangle (0, 49, 175, 47);
44
private Cairo.Rectangle layer3_bounds = new Cairo.Rectangle (0, 96, 175, 47);
46
private Cairo.Rectangle layer1_toggle = new Cairo.Rectangle (155, 8, 16, 16);
47
private Cairo.Rectangle layer2_toggle = new Cairo.Rectangle (155, 55, 16, 16);
48
private Cairo.Rectangle layer3_toggle = new Cairo.Rectangle (155, 102, 16, 16);
50
private Gdk.Pixbuf layer_visible;
51
private Gdk.Pixbuf layer_invisible;
53
private Cairo.Surface transparent;
38
private TreeView tree;
39
private TreeStore store;
41
private const int store_index_thumbnail = 0;
42
private const int store_index_name = 1;
43
private const int store_index_visibility = 2;
44
private const int store_index_layer = 3;
46
private const int thumbnail_width = 60;
47
private const int thumbnail_height = 40;
48
private const int thumbnail_column_width = 70;
50
private const int name_column_min_width = 100;
51
private const int name_column_max_width = 300;
53
private const int visibility_column_width = 30;
55
55
public LayersListWidget ()
57
this.AddEvents ((int)Gdk.EventMask.ButtonPressMask);
59
// Insert initialization code here.
60
layer_visible = PintaCore.Resources.GetIcon ("LayersWidget.Visible.png");
61
layer_invisible = PintaCore.Resources.GetIcon ("LayersWidget.Hidden.png");
63
transparent = new Cairo.ImageSurface (Cairo.Format.ARGB32, thumb_width, thumb_height);
64
Cairo.Color gray = new Cairo.Color (.75, .75, .75);
66
// Create checkerboard background
69
using (Cairo.Context g = new Cairo.Context (transparent)) {
70
g.Color = new Cairo.Color (1, 1, 1);
73
for (int y = 0; y < thumb_height; y += grid_width)
74
for (int x = 0; x < thumb_width; x += grid_width) {
75
if ((x / grid_width % 2) + (y / grid_width % 2) == 1)
76
g.FillRectangle (new Cairo.Rectangle (x, y, grid_width, grid_width), gray);
80
PintaCore.Layers.LayerAdded += HandlePintaCoreLayersLayerAddedOrRemoved;
81
PintaCore.Layers.LayerRemoved += HandlePintaCoreLayersLayerAddedOrRemoved;
82
PintaCore.Layers.SelectedLayerChanged += HandlePintaCoreLayersLayerAddedOrRemoved;
83
PintaCore.History.HistoryItemAdded += HandlePintaCoreHistoryHistoryItemAdded;
84
PintaCore.History.ActionRedone += HandlePintaCoreHistoryHistoryItemAdded;
85
PintaCore.History.ActionUndone += HandlePintaCoreHistoryHistoryItemAdded;
88
private void HandlePintaCoreHistoryHistoryItemAdded (object sender, EventArgs e)
90
this.GdkWindow.Invalidate ();
93
private void HandlePintaCoreLayersLayerAddedOrRemoved (object sender, EventArgs e)
95
this.GdkWindow.Invalidate ();
57
SetSizeRequest (200, 300);
59
SetPolicy (PolicyType.Automatic, PolicyType.Automatic);
61
tree = new TreeView ();
63
tree.HeadersVisible = false;
64
tree.FixedHeightMode = true;
65
tree.Reorderable = false;
66
tree.EnableGridLines = TreeViewGridLines.None;
67
tree.EnableTreeLines = false;
68
tree.ShowExpanders = false;
70
var crs = new CellRendererSurface (thumbnail_width, thumbnail_height);
71
var col = new TreeViewColumn ("Thumbnail", crs, "surface", store_index_thumbnail);
72
col.Sizing = TreeViewColumnSizing.Fixed;
73
col.FixedWidth = thumbnail_column_width;
74
tree.AppendColumn (col);
76
col = new TreeViewColumn ("Name", new CellRendererText (), "text", store_index_name);
77
col.Sizing = TreeViewColumnSizing.Fixed;
79
col.MinWidth = name_column_min_width;
80
col.MaxWidth = name_column_max_width;
81
tree.AppendColumn (col);
83
var crt = new CellRendererToggle ();
84
crt.Activatable = true;
85
crt.Toggled += LayerVisibilityToggled;
87
col = new TreeViewColumn ("Visible", crt, "active", store_index_visibility);
88
col.Sizing = TreeViewColumnSizing.Fixed;
89
col.FixedWidth = visibility_column_width;
90
tree.AppendColumn (col);
92
store = new TreeStore (typeof (Cairo.ImageSurface), typeof (string), typeof (bool), typeof (Layer));
95
tree.RowActivated += HandleRowActivated;
99
PintaCore.Layers.LayerAdded += HandleLayerAddedOrRemoved;
100
PintaCore.Layers.LayerRemoved += HandleLayerAddedOrRemoved;
101
PintaCore.Layers.SelectedLayerChanged += HandleSelectedLayerChanged;
102
PintaCore.Layers.LayerPropertyChanged += HandlePintaCoreLayersLayerPropertyChanged;
104
PintaCore.History.HistoryItemAdded += HandleHistoryItemAdded;
105
PintaCore.History.ActionRedone += HandleHistoryItemAdded;
106
PintaCore.History.ActionUndone += HandleHistoryItemAdded;
108
tree.CursorChanged += HandleLayerSelected;
113
private Layer GetSelectedLayerInTreeView ()
118
var paths = tree.Selection.GetSelectedRows ();
120
if (paths != null && paths.Length > 0 && store.GetIter (out iter, paths[0])) {
121
layer = store.GetValue (iter, store_index_layer) as Layer;
127
private void SelectLayerInTreeView (int layerIndex)
129
var path = new TreePath (new int[] { layerIndex });
130
tree.Selection.SelectPath (path);
133
private void HandleLayerSelected (object o, EventArgs e)
135
var layer = GetSelectedLayerInTreeView ();
136
if (PintaCore.Layers.CurrentLayer != layer)
137
PintaCore.Layers.SetCurrentLayer (GetSelectedLayerInTreeView ());
140
private void LayerVisibilityToggled (object o, ToggledArgs args)
143
if (store.GetIter (out iter, new TreePath (args.Path))) {
144
bool b = (bool) store.GetValue (iter, store_index_visibility);
145
store.SetValue(iter, store_index_visibility, !b);
147
var layer = (Layer) store.GetValue (iter, store_index_layer);
148
SetLayerVisibility (layer, !b);
152
private void HandleHistoryItemAdded (object sender, EventArgs e)
154
// TODO: Handle this more efficiently.
158
private void HandleSelectedLayerChanged (object sender, EventArgs e)
160
// TODO: Handle this more efficiently.
164
void HandlePintaCoreLayersLayerPropertyChanged (object sender, PropertyChangedEventArgs e)
166
// TODO: Handle this more efficiently.
170
private void HandleLayerAddedOrRemoved(object sender, EventArgs e)
172
// TODO: Handle this more efficiently.
97
175
// TODO: this should be handled elsewhere
98
176
PintaCore.Workspace.Invalidate ();
101
protected override bool OnButtonPressEvent (Gdk.EventButton ev)
103
Layer toggled = GetClickedLayerVisibleToggle (ev.X, ev.Y);
104
Layer clicked = GetClickedLayer (ev.X, ev.Y);
107
toggled.Hidden = !toggled.Hidden;
108
else if (clicked != null)
109
PintaCore.Layers.SetCurrentLayer (clicked);
111
GdkWindow.Invalidate ();
112
PintaCore.Workspace.Invalidate ();
114
// Insert button press handling code here.
115
return base.OnButtonPressEvent (ev);
118
private Layer GetClickedLayer (double x, double y)
120
int count = PintaCore.Layers.Count;
123
if (layer1_bounds.ContainsPoint (x, y))
124
return PintaCore.Layers[0];
125
} else if (count == 2) {
126
if (layer1_bounds.ContainsPoint (x, y))
127
return PintaCore.Layers[1];
128
else if (layer2_bounds.ContainsPoint (x, y))
129
return PintaCore.Layers[0];
131
if (layer1_bounds.ContainsPoint (x, y))
132
return PintaCore.Layers[2];
133
else if (layer2_bounds.ContainsPoint (x, y))
134
return PintaCore.Layers[1];
135
else if (layer3_bounds.ContainsPoint (x, y))
136
return PintaCore.Layers[0];
142
private Layer GetClickedLayerVisibleToggle (double x, double y)
144
int count = PintaCore.Layers.Count;
147
if (layer1_toggle.ContainsPoint (x, y))
148
return PintaCore.Layers[0];
149
} else if (count == 2) {
150
if (layer1_toggle.ContainsPoint (x, y))
151
return PintaCore.Layers[1];
152
else if (layer2_toggle.ContainsPoint (x, y))
153
return PintaCore.Layers[0];
155
if (layer1_toggle.ContainsPoint (x, y))
156
return PintaCore.Layers[2];
157
else if (layer2_toggle.ContainsPoint (x, y))
158
return PintaCore.Layers[1];
159
else if (layer3_toggle.ContainsPoint (x, y))
160
return PintaCore.Layers[0];
179
private void HandleRowActivated(object o, RowActivatedArgs args)
181
// The double click to activate will have already selected the layer.
182
PintaCore.Actions.Layers.Properties.Activate ();
188
foreach (var layer in PintaCore.Layers.Reverse ()) {
189
store.AppendValues (layer.Surface, layer.Name, !layer.Hidden, layer);
192
SelectLayerInTreeView (PintaCore.Layers.Count - PintaCore.Layers.CurrentLayerIndex - 1);
165
protected override bool OnExposeEvent (Gdk.EventExpose ev)
167
base.OnExposeEvent (ev);
172
foreach (var item in PintaCore.Layers.Reverse ()) {
173
DrawLayer (item, 5, y, item.Name, item == PintaCore.Layers.CurrentLayer);
177
// Insert drawing code here.
181
protected override void OnSizeAllocated (Gdk.Rectangle allocation)
183
base.OnSizeAllocated (allocation);
184
// Insert layout code here.
187
protected override void OnSizeRequested (ref Gtk.Requisition requisition)
189
// Calculate desired size here.
190
requisition.Height = 145;
191
requisition.Width = 175;
194
private void DrawLayer (Layer l, int x, int y, string name, bool selected)
195
private void SetLayerVisibility (Layer layer, bool visibility)
196
using (Cairo.Context g = Gdk.CairoHelper.Create (GdkWindow)) {
199
g.FillRectangle (new Cairo.Rectangle (0, y - 3, 300, 47), new Cairo.Color (0, 0, 1));
205
g.SetSource (transparent);
208
g.Scale (56 / PintaCore.Workspace.ImageSize.X, 42 / PintaCore.Workspace.ImageSize.Y);
210
g.SetSource (l.Surface);
214
g.DrawRectangle (new Cairo.Rectangle (x, y, 56, 42), new Cairo.Color (0, 0, 0), 1);
215
g.MoveTo (x + 70, y + 26);
220
Gdk.CairoHelper.SetSourcePixbuf (g, layer_visible, 155, y + 3);
222
Gdk.CairoHelper.SetSourcePixbuf (g, layer_invisible, 155, y + 3);
198
layer.Hidden = !visibility;
200
var initial = new LayerProperties(layer.Name, visibility, layer.Opacity);
201
var updated = new LayerProperties(layer.Name, !visibility, layer.Opacity);
203
var historyItem = new UpdateLayerPropertiesHistoryItem (
204
"Menu.Layers.LayerProperties.png",
205
(visibility) ? "Layer Shown" : "Layer Hidden",
206
PintaCore.Layers.IndexOf (layer),
210
PintaCore.History.PushNewItem (historyItem);
212
//TODO Call this automatically when the layer visibility changes.
213
PintaCore.Workspace.Invalidate ();