2006-02-07 Lluis Sanchez Gual <lluis@novell.com>

* libstetic/ItemGroup.cs: Converted to class. Added support for
	Signal items.
	
	* libstetic/wrapper/Container.cs: Added properties for storing
	the width and height of the container (at design time).
	
	* libstetic/wrapper/Widget.cs: Added support for signals. 
	Added some new events: NameChanged, WidgetChanged, SignalAdded,
	SignalRemoved, SignalChanged.
	
	* libstetic/wrapper/Window.cs: Don't show the window when it's
	selected. That's something that the hosting application has to
	decide. The selection change event in Project can be used for this.
	
	* libstetic/wrapper/objects.xml: Added signals.
	
	* libstetic/editor/ResponseId.cs: 
	* libstetic/editor/Translatable.cs:
	* libstetic/editor/Char.cs:
	* libstetic/editor/Color.cs:
	* libstetic/editor/ThemedIcon.cs:
	* libstetic/editor/Boolean.cs:
	* libstetic/editor/Image.cs:
	* libstetic/editor/FloatRange.cs:
	* libstetic/editor/Text.cs:
	* libstetic/editor/Accelerator.cs:
	* libstetic/editor/Enumeration.cs:
	* libstetic/editor/GroupPicker.cs:
	* libstetic/editor/OptIntRange.cs:
	* libstetic/editor/Flags.cs:
	* libstetic/editor/StringArray.cs:
	* libstetic/editor/String.cs:
	* libstetic/editor/IntRange.cs:
	  Implement the new IPropertyEditor interface.
	
	* libstetic/HandleWindow.cs: Use a wider focus rectangle.
	Get the correct top level window when it's embedded in another window.
	
	* libstetic/GladeUtils.cs: Added helper methods for exporting and
	importing widgets. Read/Write signal information.
	
	* libstetic/ClassDescriptor.cs: Added support for signals.
	
	* stetic/Makefile.am:
	* libstetic/Makefile.am: Updated.
	
	* libstetic/Registry.cs: Added some helper methods for locating
	groups.
	
	* Makefile.am:
	* configure.in: Set version to 0.1.0. Added .pc file.
	
	* stetic/WidgetFactory.cs: Don't show the window when it's
	created. The hosting app can do it by subscribing the 
	Project.WidgetAdded event.
	
	* stetic/Glade.cs: Top level widgets don't need to be windows,
	they can be containers.
	
	* stetic/PropertyGrid.cs: Some big changes. This widget is not a Grid
	anymore, but a VBox of grids. There is a grid for every ItemGroup, and
	they are reused for all widgets that share the same ItemGroup. The
	property grid is now much faster.
	
	* stetic/Stetic.cs: Added the signals editor. Handle some events
	previously handled in the widget code, but which I moved here to
	make the code more generic.
	
	* libstetic/IPropertyEditor.cs: New interface to be implemented
	by all property editors.
	
	* stetic/PropertyEditor.cs: Replaced all code that relied on reflection
	to create and initialize property editors. All this is now done through
	the new IPropertyEditor interface. Now it is also possible to reuse
	the same PropertyEditor for different objects that share the same
	property.
	
	* stetic/Palette.cs:
	* stetic/ProjectView.cs: Added support for changing the project to
	which those widgets are bound.
	
	* stetic/stetic.glade: Added the signals editor.
	
	* stetic/Project.cs: Added several events which are needed to
	integrate Stetic in an IDE.
	
	* stetic.pc.in: Added.
	
	* libstetic/SignalDescriptor.cs: New descriptor for signals.
	
	* libstetic/wrapper/WidgetEventHandler.cs:
	* libstetic/wrapper/WidgetNameChangedHandler.cs:
	* libstetic/wrapper/SignalEventHandler.cs:
	* libstetic/wrapper/SignalChangedEventHandler.cs
	
	* libstetic/wrapper/SignalCollection.cs:
	* libstetic/wrapper/Signal.cs: New class. Holds information
	about signal handlers bound to a widgets.
	
	* libstetic/ItemGroupCollection.cs: New collection class.
	
	* stetic/SignalsEditor.cs: The new signals editor.


svn path=/trunk/stetic/; revision=56684
This commit is contained in:
Lluis Sanchez 2006-02-08 21:01:36 +00:00
Родитель cdd9920c3d
Коммит af7029802b
51 изменённых файлов: 2707 добавлений и 420 удалений

105
ChangeLog
Просмотреть файл

@ -1,3 +1,108 @@
2006-02-07 Lluis Sanchez Gual <lluis@novell.com>
* libstetic/ItemGroup.cs: Converted to class. Added support for
Signal items.
* libstetic/wrapper/Container.cs: Added properties for storing
the width and height of the container (at design time).
* libstetic/wrapper/Widget.cs: Added support for signals.
Added some new events: NameChanged, WidgetChanged, SignalAdded,
SignalRemoved, SignalChanged.
* libstetic/wrapper/Window.cs: Don't show the window when it's
selected. That's something that the hosting application has to
decide. The selection change event in Project can be used for this.
* libstetic/wrapper/objects.xml: Added signals.
* libstetic/editor/ResponseId.cs:
* libstetic/editor/Translatable.cs:
* libstetic/editor/Char.cs:
* libstetic/editor/Color.cs:
* libstetic/editor/ThemedIcon.cs:
* libstetic/editor/Boolean.cs:
* libstetic/editor/Image.cs:
* libstetic/editor/FloatRange.cs:
* libstetic/editor/Text.cs:
* libstetic/editor/Accelerator.cs:
* libstetic/editor/Enumeration.cs:
* libstetic/editor/GroupPicker.cs:
* libstetic/editor/OptIntRange.cs:
* libstetic/editor/Flags.cs:
* libstetic/editor/StringArray.cs:
* libstetic/editor/String.cs:
* libstetic/editor/IntRange.cs:
Implement the new IPropertyEditor interface.
* libstetic/HandleWindow.cs: Use a wider focus rectangle.
Get the correct top level window when it's embedded in another window.
* libstetic/GladeUtils.cs: Added helper methods for exporting and
importing widgets. Read/Write signal information.
* libstetic/ClassDescriptor.cs: Added support for signals.
* stetic/Makefile.am:
* libstetic/Makefile.am: Updated.
* libstetic/Registry.cs: Added some helper methods for locating
groups.
* Makefile.am:
* configure.in: Set version to 0.1.0. Added .pc file.
* stetic/WidgetFactory.cs: Don't show the window when it's
created. The hosting app can do it by subscribing the
Project.WidgetAdded event.
* stetic/Glade.cs: Top level widgets don't need to be windows,
they can be containers.
* stetic/PropertyGrid.cs: Some big changes. This widget is not a Grid
anymore, but a VBox of grids. There is a grid for every ItemGroup, and
they are reused for all widgets that share the same ItemGroup. The
property grid is now much faster.
* stetic/Stetic.cs: Added the signals editor. Handle some events
previously handled in the widget code, but which I moved here to
make the code more generic.
* libstetic/IPropertyEditor.cs: New interface to be implemented
by all property editors.
* stetic/PropertyEditor.cs: Replaced all code that relied on reflection
to create and initialize property editors. All this is now done through
the new IPropertyEditor interface. Now it is also possible to reuse
the same PropertyEditor for different objects that share the same
property.
* stetic/Palette.cs:
* stetic/ProjectView.cs: Added support for changing the project to
which those widgets are bound.
* stetic/stetic.glade: Added the signals editor.
* stetic/Project.cs: Added several events which are needed to
integrate Stetic in an IDE.
* stetic.pc.in: Added.
* libstetic/SignalDescriptor.cs: New descriptor for signals.
* libstetic/wrapper/WidgetEventHandler.cs:
* libstetic/wrapper/WidgetNameChangedHandler.cs:
* libstetic/wrapper/SignalEventHandler.cs:
* libstetic/wrapper/SignalChangedEventHandler.cs
* libstetic/wrapper/SignalCollection.cs:
* libstetic/wrapper/Signal.cs: New class. Holds information
about signal handlers bound to a widgets.
* libstetic/ItemGroupCollection.cs: New collection class.
* stetic/SignalsEditor.cs: The new signals editor.
2005-09-27 Dan Winship <danw@novell.com>
* libstetic/HandleWindow.cs (HandleEvent): hack around bgo 316871

Просмотреть файл

@ -1 +1,8 @@
SUBDIRS = glue libstetic stetic
pkgconfigdir = $(prefix)/lib/pkgconfig
pkgconfig_DATA = stetic.pc
EXTRA_DIST = stetic.pc
DISTCLEANFILES = stetic.pc

Просмотреть файл

@ -1,5 +1,5 @@
AC_PREREQ(2.53)
AC_INIT(stetic, 0.0.0)
AC_INIT(stetic, 0.1.0)
AC_CONFIG_SRCDIR(stetic/Stetic.cs)
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
@ -36,4 +36,5 @@ Makefile
glue/Makefile
libstetic/Makefile
stetic/Makefile
stetic.pc
])

Просмотреть файл

@ -18,7 +18,9 @@ namespace Stetic {
Gdk.Pixbuf icon;
bool deprecated, hexpandable, vexpandable;
ArrayList groups = new ArrayList ();
ItemGroupCollection groups = new ItemGroupCollection ();
ItemGroupCollection signals = new ItemGroupCollection ();
int importantGroups;
ItemGroup contextMenu;
ItemGroup internalChildren;
@ -94,6 +96,19 @@ namespace Stetic {
}
}
XmlElement signalsElem = elem["signals"];
if (signalsElem != null) {
foreach (XmlElement groupElem in signalsElem.SelectNodes ("itemgroup")) {
ItemGroup itemgroup;
if (groupElem.HasAttribute ("ref")) {
string refname = groupElem.GetAttribute ("ref");
itemgroup = Registry.LookupSignalGroup (refname);
} else
itemgroup = new ItemGroup (groupElem, this);
signals.Add (itemgroup);
}
}
XmlElement contextElem = elem["contextmenu"];
if (contextElem != null) {
if (contextElem.HasAttribute ("ref")) {
@ -216,12 +231,18 @@ namespace Stetic {
}
}
public ArrayList ItemGroups {
public ItemGroupCollection ItemGroups {
get {
return groups;
}
}
public ItemGroupCollection SignalGroups {
get {
return signals;
}
}
public int ImportantGroups {
get {
return importantGroups;

Просмотреть файл

@ -2,6 +2,7 @@ using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Xml;
using Stetic.Wrapper;
namespace Stetic {
@ -21,11 +22,11 @@ namespace Stetic {
public static XmlDocument XslImportTransform (XmlDocument doc)
{
XmlDocumentType doctype = doc.DocumentType;
if (doctype == null ||
/* if (doctype == null ||
doctype.Name != "glade-interface" ||
doctype.SystemId != Glade20SystemId)
throw new GladeException ("Not a glade file according to doctype");
*/
XmlReader reader = Registry.GladeImportXsl.Transform (doc, null, (XmlResolver)null);
doc = new XmlDocument ();
doc.PreserveWhitespace = true;
@ -46,12 +47,12 @@ namespace Stetic {
return doc;
}
public static void Copy (Gtk.Widget widget, Gtk.SelectionData seldata, bool copyAsText)
public static XmlDocument Export (Gtk.Widget widget)
{
Stetic.Wrapper.Widget wrapper = Stetic.Wrapper.Widget.Lookup (widget);
if (wrapper == null)
return;
return null;
XmlDocument doc = new XmlDocument ();
doc.PreserveWhitespace = true;
@ -71,7 +72,7 @@ namespace Stetic {
if (parent == null) {
elem = wrapper.GladeExport (doc);
if (elem == null)
return;
return null;
if (!(widget is Gtk.Window)) {
XmlElement window = doc.CreateElement ("widget");
window.SetAttribute ("class", "GtkWindow");
@ -98,6 +99,38 @@ namespace Stetic {
elem.SetAttribute ("class", "GtkWindow");
elem.SetAttribute ("id", "glade-dummy-container");
}
return doc;
}
public static Stetic.Wrapper.Widget Import (IProject project, XmlDocument doc)
{
try {
doc = XslImportTransform (doc);
} catch {
return null;
}
XmlElement elem = (XmlElement)doc.SelectSingleNode ("glade-interface/widget");
if (elem.GetAttribute ("class") != "GtkWindow" ||
elem.GetAttribute ("id") != "glade-dummy-container") {
// Creating a new toplevel
Stetic.Wrapper.Widget toplevel = (Stetic.Wrapper.Widget)
Stetic.ObjectWrapper.GladeImport (project, elem);
if (toplevel != null) {
project.AddWindow ((Gtk.Window)toplevel.Wrapped);
}
return toplevel;
}
return (Stetic.Wrapper.Widget)
Stetic.ObjectWrapper.GladeImport (project, (XmlElement)elem.SelectSingleNode ("child/widget"));
}
public static void Copy (Gtk.Widget widget, Gtk.SelectionData seldata, bool copyAsText)
{
XmlDocument doc = Export (widget);
if (doc == null)
return;
if (copyAsText)
seldata.Text = doc.OuterXml;
@ -115,26 +148,11 @@ namespace Stetic {
doc.PreserveWhitespace = true;
try {
doc.LoadXml (data);
doc = XslImportTransform (doc);
} catch {
return null;
}
XmlElement elem = (XmlElement)doc.SelectSingleNode ("glade-interface/widget");
if (elem.GetAttribute ("class") != "GtkWindow" ||
elem.GetAttribute ("id") != "glade-dummy-container") {
// Creating a new toplevel
Stetic.Wrapper.Widget toplevel = (Stetic.Wrapper.Widget)
Stetic.ObjectWrapper.GladeImport (project, elem);
if (toplevel != null) {
project.AddWindow ((Gtk.Window)toplevel.Wrapped);
toplevel.Wrapped.Show ();
}
return toplevel;
}
return (Stetic.Wrapper.Widget)
Stetic.ObjectWrapper.GladeImport (project, (XmlElement)elem.SelectSingleNode ("child/widget"));
return Import (project, doc);
}
static object GetProperty (XmlElement elem, string selector, object defaultValue, bool extract)
@ -367,6 +385,27 @@ namespace Stetic {
}
}
static void ReadSignals (ClassDescriptor klass, ObjectWrapper wrapper, XmlElement elem)
{
Stetic.Wrapper.Widget ob = wrapper as Stetic.Wrapper.Widget;
if (ob == null) return;
foreach (ItemGroup group in klass.SignalGroups) {
foreach (SignalDescriptor signal in group) {
if (signal.GladeName == null)
continue;
XmlElement signal_elem = elem.SelectSingleNode ("signal[@name='" + signal.GladeName + "']") as XmlElement;
if (signal_elem == null)
continue;
string handler = signal_elem.GetAttribute ("handler");
bool after = signal_elem.GetAttribute ("after") == "yes";
ob.Signals.Add (new Signal (signal, handler, after));
}
}
}
static public void ImportWidget (ObjectWrapper wrapper, XmlElement elem)
{
string className = elem.GetAttribute ("class");
@ -376,6 +415,8 @@ namespace Stetic {
ClassDescriptor klass = Registry.LookupClass (className);
if (klass == null)
throw new GladeException ("No stetic ClassDescriptor for " + className);
ReadSignals (klass, wrapper, elem);
Hashtable rawProps, overrideProps;
ExtractProperties (klass, elem, out rawProps, out overrideProps);
@ -393,6 +434,7 @@ namespace Stetic {
throw new GladeException ("Could not create widget", className);
widget = (Gtk.Widget)GLib.Object.GetObject (raw, true);
if (widget == null) {
gtk_object_sink (raw);
throw new GladeException ("Could not create gtk# wrapper", className);
@ -410,7 +452,7 @@ namespace Stetic {
SetOverrideProperties (wrapper, overrideProps);
MarkTranslatables (widget, overrideProps);
}
static void SetOverrideProperties (ObjectWrapper wrapper, Hashtable overrideProps)
{
foreach (PropertyDescriptor prop in overrideProps.Keys) {
@ -477,7 +519,7 @@ namespace Stetic {
SetOverrideProperties (wrapper, overrideProps);
MarkTranslatables (cc, overrideProps);
}
static string PropToString (ObjectWrapper wrapper, PropertyDescriptor prop)
{
object value;
@ -559,6 +601,7 @@ namespace Stetic {
elem.SetAttribute ("id", ((Gtk.Widget)wrapper.Wrapped).Name);
GetProps (wrapper, elem);
GetSignals (wrapper, elem);
return elem;
}
@ -583,7 +626,8 @@ namespace Stetic {
XmlElement prop_elem = parent_elem.OwnerDocument.CreateElement ("property");
prop_elem.SetAttribute ("name", prop.GladeName);
prop_elem.InnerText = val;
if (val.Length > 0)
prop_elem.InnerText = val;
if (prop.Translatable && prop.IsTranslated (wrapper.Wrapped)) {
prop_elem.SetAttribute ("translatable", "yes");
@ -600,6 +644,26 @@ namespace Stetic {
}
}
static public void GetSignals (ObjectWrapper wrapper, XmlElement parent_elem)
{
Stetic.Wrapper.Widget ob = wrapper as Stetic.Wrapper.Widget;
if (ob == null) return;
foreach (Signal signal in ob.Signals) {
if (signal.SignalDescriptor.GladeName == null)
continue;
if (!signal.SignalDescriptor.VisibleFor (wrapper.Wrapped))
continue;
XmlElement signal_elem = parent_elem.OwnerDocument.CreateElement ("signal");
signal_elem.SetAttribute ("name", signal.SignalDescriptor.GladeName);
signal_elem.SetAttribute ("handler", signal.Handler);
if (signal.After)
signal_elem.SetAttribute ("after", "yes");
parent_elem.AppendChild (signal_elem);
}
}
[DllImport("libgobject-2.0-0.dll")]
static extern IntPtr g_type_fundamental (IntPtr gtype);

Просмотреть файл

@ -8,6 +8,10 @@ namespace Stetic {
public class HandleWindow : IDisposable {
static Gdk.Color black, white;
Gtk.Widget topLevel;
const int handleSize = 6;
const int borderSize = 3;
static HandleWindow ()
{
@ -21,6 +25,13 @@ namespace Stetic {
{
this.selection = selection;
this.dragHandles = dragHandles;
topLevel = selection;
Gtk.Widget parent = topLevel;
while (ObjectWrapper.Lookup (parent) != null) {
topLevel = parent;
parent = topLevel.Parent;
}
selection.SizeAllocated += SelectionResized;
@ -36,7 +47,7 @@ namespace Stetic {
Gdk.EventMask.ButtonMotionMask |
Gdk.EventMask.ButtonReleaseMask |
Gdk.EventMask.ExposureMask);
window = new Gdk.Window (selection.Toplevel.GdkWindow, attributes,
window = new Gdk.Window (topLevel.GdkWindow, attributes,
Gdk.WindowAttributesType.Visual |
Gdk.WindowAttributesType.Colormap);
window.UserData = invis.Handle;
@ -44,7 +55,7 @@ namespace Stetic {
Shape ();
}
public void Dispose ()
{
if (selection != null) {
@ -75,19 +86,19 @@ namespace Stetic {
Gdk.Rectangle handleAllocation;
const int handleSize = 6;
public void Shape ()
{
Gdk.GC gc;
Gdk.Pixmap pixmap;
int tlx, tly;
int margin = dragHandles ? 1 : -2;
selection.TranslateCoordinates (selection.Toplevel, 0, 0, out tlx, out tly);
handleAllocation.X = tlx - handleSize / 2;
handleAllocation.Y = tly - handleSize / 2;
handleAllocation.Width = selection.Allocation.Width + handleSize;
handleAllocation.Height = selection.Allocation.Height + handleSize;
selection.TranslateCoordinates (topLevel, 0, 0, out tlx, out tly);
handleAllocation.X = tlx - handleSize / 2 - margin;
handleAllocation.Y = tly - handleSize / 2 - margin;
handleAllocation.Width = selection.Allocation.Width + handleSize + margin*2;
handleAllocation.Height = selection.Allocation.Height + handleSize + margin*2;
int width = handleAllocation.Width, height = handleAllocation.Height;
@ -100,14 +111,17 @@ namespace Stetic {
gc.Foreground = black;
// Draw border
gc.SetDashes (0, new sbyte[] {1,1}, 2);
gc.SetLineAttributes (borderSize, Gdk.LineStyle.OnOffDash, Gdk.CapStyle.NotLast, Gdk.JoinStyle.Miter);
pixmap.DrawRectangle (gc, false, handleSize / 2, handleSize / 2,
width - handleSize, height - handleSize);
if (dragHandles) {
pixmap.DrawRectangle (gc, true, 0, 0, handleSize, handleSize);
pixmap.DrawRectangle (gc, true, 0, height - handleSize, handleSize, handleSize);
pixmap.DrawRectangle (gc, true, width - handleSize, 0, handleSize, handleSize);
pixmap.DrawRectangle (gc, true, width - handleSize, height - handleSize, handleSize, handleSize);
gc.SetLineAttributes (1, Gdk.LineStyle.Solid, Gdk.CapStyle.NotLast, Gdk.JoinStyle.Miter);
DrawHandle (pixmap, gc, 0, 0);
DrawHandle (pixmap, gc, 0, height - handleSize);
DrawHandle (pixmap, gc, width - handleSize, 0);
DrawHandle (pixmap, gc, width - handleSize, height - handleSize);
}
window.Hide ();
@ -115,6 +129,11 @@ namespace Stetic {
window.ShapeCombineMask (pixmap, 0, 0);
window.Show ();
}
void DrawHandle (Gdk.Pixmap pixmap, Gdk.GC gc, int x, int y)
{
pixmap.DrawRectangle (gc, true, x, y, handleSize, handleSize);
}
void SelectionResized (object obj, Gtk.SizeAllocatedArgs args)
{
@ -155,7 +174,7 @@ namespace Stetic {
case Gdk.EventType.Expose:
// hack around bgo 316871 for gtk+ 2.8.0-2.8.3
gdk_synthesize_window_state (window.Handle, 0, 1);
selection.Toplevel.GdkWindow.InvalidateRect (handleAllocation, true);
topLevel.GdkWindow.InvalidateRect (handleAllocation, true);
gdk_synthesize_window_state (window.Handle, 1, 0);
return;

Просмотреть файл

@ -0,0 +1,23 @@
using System;
namespace Stetic
{
// Property editors must be Gtk Widgets and implement this interface
public interface IPropertyEditor: IDisposable
{
// Called once to initialize the editor.
void Initialize (PropertyDescriptor descriptor);
// Called when the object to be edited changes.
void AttachObject (object obj);
// Gets/Sets the value of the editor. If the editor supports
// several value types, it is the responsibility of the editor
// to return values with the expected type.
object Value { get; set; }
// To be fired when the edited value changes.
event EventHandler ValueChanged;
}
}

Просмотреть файл

@ -3,7 +3,7 @@ using System.Collections;
using System.Xml;
namespace Stetic {
public struct ItemGroup : IEnumerable {
public class ItemGroup : IEnumerable {
public static ItemGroup Empty;
static ItemGroup ()
@ -11,13 +11,17 @@ namespace Stetic {
Empty = new ItemGroup ();
Empty.items = new ItemDescriptor[0];
}
private ItemGroup ()
{
}
public ItemGroup (XmlElement elem, ClassDescriptor klass)
{
label = elem.GetAttribute ("label");
name = elem.GetAttribute ("name");
XmlNodeList nodes = elem.SelectNodes ("property | command");
XmlNodeList nodes = elem.SelectNodes ("property | command | signal");
items = new ItemDescriptor[nodes.Count];
for (int i = 0; i < nodes.Count; i++) {
XmlElement item = (XmlElement)nodes[i];
@ -34,6 +38,8 @@ namespace Stetic {
items[i] = new PropertyDescriptor ((XmlElement)item, this, klass);
else if (item.Name == "command")
items[i] = new CommandDescriptor ((XmlElement)item, this, klass);
else if (item.Name == "signal")
items[i] = new SignalDescriptor ((XmlElement)item, this, klass);
else
throw new ApplicationException ("Bad item name " + item.Name + " in " + klass.WrapperType.Name);
}

Просмотреть файл

@ -0,0 +1,32 @@
using System;
using System.Collections;
namespace Stetic
{
public class ItemGroupCollection: CollectionBase
{
public void Add (ItemGroup group)
{
List.Add (group);
}
public ItemGroup this [int n]
{
get {
return (ItemGroup) List [n];
}
}
public ItemGroup this [string name]
{
get {
for (int n=0; n<List.Count; n++) {
if (((ItemGroup) List [n]).Name == name)
return (ItemGroup) List [n];
}
return null;
}
}
}
}

Просмотреть файл

@ -10,7 +10,9 @@ libstetic_dll_sources = \
HandleWindow.cs \
ItemDescriptor.cs \
ItemGroup.cs \
ItemGroupCollection.cs \
IProject.cs \
IPropertyEditor.cs \
ObjectWrapper.cs \
ParamSpec.cs \
Placeholder.cs \
@ -19,6 +21,7 @@ libstetic_dll_sources = \
RadioGroupManager.cs \
Registry.cs \
Set.cs \
SignalDescriptor.cs \
TextBox.cs \
Tooltips.cs \
TranslatableAttribute.cs \
@ -71,6 +74,10 @@ libstetic_dll_sources = \
wrapper/Range.cs \
wrapper/Scale.cs \
wrapper/ScrolledWindow.cs \
wrapper/Signal.cs \
wrapper/SignalChangedEventHandler.cs \
wrapper/SignalCollection.cs \
wrapper/SignalEventHandler.cs \
wrapper/SpinButton.cs \
wrapper/Table.cs \
wrapper/TextView.cs \
@ -81,6 +88,8 @@ libstetic_dll_sources = \
wrapper/VScale.cs \
wrapper/VScrollbar.cs \
wrapper/Widget.cs \
wrapper/WidgetEventHandler.cs \
wrapper/WidgetNameChangedHandler.cs \
wrapper/Window.cs
libstetic_dll_resources = \

Просмотреть файл

@ -97,12 +97,12 @@ namespace Stetic {
{
return (ClassDescriptor)classes_by_cname[cname];
}
public static ItemGroup LookupItemGroup (string name)
static ClassDescriptor FindGroupClass (string name, out string groupname)
{
int sep = name.LastIndexOf ('.');
string classname = name.Substring (0, sep);
string groupname = name.Substring (sep + 1);
groupname = name.Substring (sep + 1);
ClassDescriptor klass = (ClassDescriptor)classes_by_csname[classname];
if (klass == null) {
klass = (ClassDescriptor)classes_by_csname[name];
@ -111,12 +111,31 @@ namespace Stetic {
classname = name;
groupname = "";
}
return klass;
}
foreach (ItemGroup group in klass.ItemGroups) {
if (group.Name == groupname)
return group;
}
throw new ArgumentException ("No itemgroup " + groupname + " in class " + classname);
public static ItemGroup LookupItemGroup (string name)
{
string groupname;
ClassDescriptor klass = FindGroupClass (name, out groupname);
ItemGroup group = klass.ItemGroups [groupname];
if (group != null)
return group;
else
throw new ArgumentException ("No itemgroup '" + groupname + "' in class " + klass.WrappedType);
}
public static ItemGroup LookupSignalGroup (string name)
{
string groupname;
ClassDescriptor klass = FindGroupClass (name, out groupname);
ItemGroup group = klass.SignalGroups [groupname];
if (group != null)
return group;
else
throw new ArgumentException ("No itemgroup '" + groupname + "' in class " + klass.WrappedType);
}
public static ItemDescriptor LookupItem (string name)

Просмотреть файл

@ -0,0 +1,81 @@
using System;
using System.Reflection;
using System.Xml;
namespace Stetic
{
public class SignalDescriptor: ItemDescriptor
{
string name, label, description;
EventInfo eventInfo;
MethodInfo handler;
string gladeName;
const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
public SignalDescriptor (XmlElement elem, ItemGroup group, ClassDescriptor klass) : base (elem, group, klass)
{
name = elem.GetAttribute ("name");
label = elem.GetAttribute ("label");
description = elem.GetAttribute ("description");
eventInfo = FindEvent (klass.WrapperType, klass.WrappedType, name);
handler = eventInfo.EventHandlerType.GetMethod ("Invoke");
if (elem.HasAttribute ("glade-name"))
gladeName = elem.GetAttribute ("glade-name");
else {
object[] att = eventInfo.GetCustomAttributes (typeof(GLib.SignalAttribute), true);
if (att.Length > 0)
gladeName = ((GLib.SignalAttribute)att[0]).CName;
}
}
public override string Name {
get { return name; }
}
public string Label {
get { return label; }
}
public string Description {
get { return description; }
}
public string GladeName {
get { return gladeName; }
}
public Type HandlerType {
get { return eventInfo.EventHandlerType; }
}
public Type HandlerReturnType {
get { return handler.ReturnType; }
}
public ParameterInfo[] HandlerParameters {
get { return handler.GetParameters (); }
}
static EventInfo FindEvent (Type wrapperType, Type objectType, string name)
{
EventInfo info;
if (wrapperType != null) {
info = wrapperType.GetEvent (name, flags);
if (info != null)
return info;
}
info = objectType.GetEvent (name, flags);
if (info != null)
return info;
throw new ArgumentException ("Invalid event name " + objectType.Name + "." + name);
}
}
}

Просмотреть файл

@ -4,7 +4,7 @@ using System.Runtime.InteropServices;
namespace Stetic.Editor {
[PropertyEditor ("Accel", "AccelChanged")]
public class Accelerator : Gtk.Entry {
public class Accelerator : Gtk.Entry, IPropertyEditor {
uint keyval;
Gdk.ModifierType mask;
@ -22,6 +22,17 @@ namespace Stetic.Editor {
IsEditable = false;
}
public void Initialize (PropertyDescriptor descriptor)
{
if (descriptor.PropertyType != typeof(string))
throw new ApplicationException ("Accelerator editor does not support editing values of type " + descriptor.PropertyType);
}
public void AttachObject (object obj)
{
Value = null;
}
protected override bool OnButtonPressEvent (Gdk.EventButton evt)
{
if (editing)
@ -39,7 +50,7 @@ namespace Stetic.Editor {
Gdk.Keyboard.Ungrab (time);
Gdk.Pointer.Ungrab (time);
Text = Accel;
Text = (string) Value;
}
void Grab (Gdk.Window window, uint time)
@ -95,7 +106,7 @@ namespace Stetic.Editor {
}
}
public string Accel {
public object Value {
get {
if (keyval != 0)
return Gtk.Accelerator.Name (keyval, mask);
@ -103,22 +114,23 @@ namespace Stetic.Editor {
return null;
}
set {
if (value == null) {
string s = value as string;
if (s == null) {
keyval = 0;
mask = 0;
} else
Gtk.Accelerator.Parse (value, out keyval, out mask);
Text = Accel;
Gtk.Accelerator.Parse (s, out keyval, out mask);
Text = (string) Value;
EmitAccelChanged ();
}
}
public event EventHandler AccelChanged;
public event EventHandler ValueChanged;
void EmitAccelChanged ()
{
if (AccelChanged != null)
AccelChanged (this, EventArgs.Empty);
if (ValueChanged != null)
ValueChanged (this, EventArgs.Empty);
}
}
}

Просмотреть файл

@ -3,5 +3,30 @@ using System;
namespace Stetic.Editor {
[PropertyEditor ("Active", "Toggled")]
public class Boolean : Gtk.CheckButton { }
public class Boolean : Gtk.CheckButton, IPropertyEditor
{
public void Initialize (PropertyDescriptor descriptor)
{
if (descriptor.PropertyType != typeof(bool))
throw new ApplicationException ("Boolean editor does not support editing values of type " + descriptor.PropertyType);
}
public void AttachObject (object obj)
{
}
public object Value {
get { return Active; }
set { Active = (bool) value; }
}
protected override void OnToggled ()
{
base.OnToggled ();
if (ValueChanged != null)
ValueChanged (this, EventArgs.Empty);
}
public event EventHandler ValueChanged;
}
}

Просмотреть файл

@ -2,16 +2,26 @@ using System;
namespace Stetic.Editor {
public class Char : Gtk.Entry {
public class Char : Gtk.Entry, IPropertyEditor {
public Char ()
{
MaxLength = 1;
}
public void Initialize (PropertyDescriptor descriptor)
{
if (descriptor.PropertyType != typeof(bool))
throw new ApplicationException ("Char editor does not support editing values of type " + descriptor.PropertyType);
}
public void AttachObject (object obj)
{
}
char last;
public char Value {
public object Value {
get {
if (Text.Length == 0)
return last;
@ -20,7 +30,7 @@ namespace Stetic.Editor {
}
set {
Text = value.ToString ();
last = value;
last = (char) value;
}
}

Просмотреть файл

@ -3,5 +3,30 @@ using System;
namespace Stetic.Editor {
[PropertyEditor ("Color", "ColorSet")]
public class Color : Gtk.ColorButton { }
public class Color : Gtk.ColorButton, IPropertyEditor
{
public void Initialize (PropertyDescriptor descriptor)
{
if (descriptor.PropertyType != typeof(Gdk.Color))
throw new ApplicationException ("Color editor does not support editing values of type " + descriptor.PropertyType);
}
public void AttachObject (object obj)
{
}
public object Value {
get { return Color; }
set { Color = (Gdk.Color) value; }
}
protected override void OnColorSet ()
{
base.OnColorSet ();
if (ValueChanged != null)
ValueChanged (this, EventArgs.Empty);
}
public event EventHandler ValueChanged;
}
}

Просмотреть файл

@ -3,15 +3,22 @@ using System.Collections;
namespace Stetic.Editor {
public class Enumeration : Gtk.HBox {
public class Enumeration : Gtk.HBox, IPropertyEditor {
Gtk.EventBox ebox;
Gtk.ComboBox combo;
Gtk.Tooltips tips;
EnumDescriptor enm;
public Enumeration (PropertyDescriptor prop) : base (false, 0)
public Enumeration () : base (false, 0)
{
}
public void Initialize (PropertyDescriptor prop)
{
if (!prop.PropertyType.IsEnum)
throw new ApplicationException ("Enumeration editor does not support editing values of type " + prop.PropertyType);
ebox = new Gtk.EventBox ();
ebox.Show ();
PackStart (ebox, true, true, 0);
@ -28,18 +35,22 @@ namespace Stetic.Editor {
combo.AppendText (enm[value].Label);
}
public void AttachObject (object obj)
{
}
public override void Dispose ()
{
tips.Destroy ();
base.Dispose ();
}
public Enum Value {
public object Value {
get {
return enm.Values[combo.Active];
}
set {
int i = Array.IndexOf (enm.Values, value);
int i = Array.IndexOf (enm.Values, (Enum)value);
if (i != -1)
combo.Active = i;
}
@ -51,7 +62,7 @@ namespace Stetic.Editor {
{
if (ValueChanged != null)
ValueChanged (this, EventArgs.Empty);
EnumValue value = enm[Value];
EnumValue value = enm[(Enum)Value];
if (value != null)
tips.SetTip (ebox, value.Description, value.Description);
else

Просмотреть файл

@ -4,14 +4,21 @@ using System.Collections;
namespace Stetic.Editor {
public class Flags : Gtk.Frame {
public class Flags : Gtk.Frame, IPropertyEditor {
EnumDescriptor enm;
Hashtable flags;
Gtk.Tooltips tips;
public Flags (PropertyDescriptor prop) : base (null)
public Flags ()
{
}
public void Initialize (PropertyDescriptor prop)
{
if (!prop.PropertyType.IsEnum)
throw new ApplicationException ("Flags editor does not support editing values of type " + prop.PropertyType);
Gtk.VBox vbox = new Gtk.VBox (true, 3);
Add (vbox);
@ -37,18 +44,22 @@ namespace Stetic.Editor {
vbox.ShowAll ();
}
public void AttachObject (object ob)
{
}
public override void Dispose ()
{
tips.Destroy ();
base.Dispose ();
}
public Enum Value {
public object Value {
get {
return (Enum)Enum.ToObject (enm.EnumType, UIntValue);
return Enum.ToObject (enm.EnumType, UIntValue);
}
set {
uint newVal = (uint)(int)value;
uint newVal = (uint)(int)(Enum)value;
for (uint i = 1; i <= uintValue || i <= newVal; i = i << 1) {
if ((uintValue & i) != (newVal & i)) {
Gtk.CheckButton check = (Gtk.CheckButton)flags[i];

Просмотреть файл

@ -2,14 +2,46 @@ using System;
namespace Stetic.Editor {
public class FloatRange : Gtk.SpinButton {
public FloatRange (object min, object max) :
base (min == null ? Double.MinValue : (double)min,
max == null ? Double.MaxValue : (double)max,
0.01)
public class FloatRange : Gtk.SpinButton, IPropertyEditor
{
Type propType;
public FloatRange (): base (0, 0, 0.01)
{
}
public void Initialize (PropertyDescriptor prop)
{
propType = prop.PropertyType;
double min, max;
if (propType == typeof(double)) {
min = Double.MinValue;
max = Double.MaxValue;
} else if (propType == typeof(float)) {
min = float.MinValue;
max = float.MaxValue;
} else
throw new ApplicationException ("FloatRange editor does not support editing values of type " + propType);
if (prop.Minimum != null)
min = (double) Convert.ChangeType (prop.Minimum, typeof(double));
if (prop.Maximum != null)
max = (double) Convert.ChangeType (prop.Maximum, typeof(double));
SetRange (min, max);
Digits = 2;
}
public void AttachObject (object ob)
{
}
object IPropertyEditor.Value {
get { return Convert.ChangeType (base.Value, propType); }
set { base.Value = (double) Convert.ChangeType (value, typeof(double)); }
}
}
}

Просмотреть файл

@ -8,7 +8,7 @@ using System.Reflection;
namespace Stetic.Editor {
[PropertyEditor ("Group", "Changed")]
class GroupPicker : Gtk.HBox {
class GroupPicker : Gtk.HBox, IPropertyEditor {
Gtk.ComboBox combo;
RadioGroupManager manager;
@ -17,7 +17,11 @@ namespace Stetic.Editor {
const BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
public GroupPicker (PropertyDescriptor prop) : base (false, 0)
public GroupPicker () : base (false, 0)
{
}
public void Initialize (PropertyDescriptor prop)
{
PropertyInfo info = prop.PropertyInfo;
Type owner = info.DeclaringType;
@ -30,6 +34,10 @@ namespace Stetic.Editor {
manager.GroupsChanged += GroupsChanged;
GroupsChanged ();
}
public void AttachObject (object ob)
{
}
public override void Dispose ()
{
@ -81,12 +89,12 @@ namespace Stetic.Editor {
}
#endif
public string Group {
public object Value {
get {
return group;
}
set {
int index = values.IndexOf (value);
int index = values.IndexOf ((string) value);
if (index != -1) {
combo.Active = index;
group = values[index] as string;
@ -94,7 +102,7 @@ namespace Stetic.Editor {
}
}
public event EventHandler Changed;
public event EventHandler ValueChanged;
void combo_Changed (object o, EventArgs args)
{
@ -104,8 +112,8 @@ namespace Stetic.Editor {
}
group = values[combo.Active] as string;
if (Changed != null)
Changed (this, EventArgs.Empty);
if (ValueChanged != null)
ValueChanged (this, EventArgs.Empty);
}
void doDialog ()
@ -144,7 +152,7 @@ namespace Stetic.Editor {
Gtk.ResponseType response = (Gtk.ResponseType)dialog.Run ();
if (response == Gtk.ResponseType.Cancel || entry.Text.Length == 0) {
dialog.Destroy ();
Group = group; // reset combo.Active
Value = group; // reset combo.Active
return;
}

Просмотреть файл

@ -5,7 +5,7 @@ using System.Reflection;
namespace Stetic.Editor {
[PropertyEditor ("Value", "Changed")]
public class Image : Gtk.HBox {
public class Image : Gtk.HBox, IPropertyEditor {
Gtk.Image image;
Gtk.ComboBoxEntry combo;
Gtk.Entry entry;
@ -118,7 +118,17 @@ namespace Stetic.Editor {
}
}
public event EventHandler Changed;
public void Initialize (PropertyDescriptor prop)
{
if (prop.PropertyType != typeof(string))
throw new ApplicationException ("Image editor does not support editing values of type " + prop.PropertyType);
}
public void AttachObject (object ob)
{
}
public event EventHandler ValueChanged;
bool syncing;
@ -133,8 +143,8 @@ namespace Stetic.Editor {
StockId = stockIds[combo.Active - 1];
else
StockId = null;
if (Changed != null)
Changed (this, EventArgs.Empty);
if (ValueChanged != null)
ValueChanged (this, EventArgs.Empty);
syncing = false;
}
@ -146,8 +156,8 @@ namespace Stetic.Editor {
useStock = true;
syncing = true;
StockId = entry.Text;
if (Changed != null)
Changed (this, EventArgs.Empty);
if (ValueChanged != null)
ValueChanged (this, EventArgs.Empty);
syncing = false;
}
@ -166,8 +176,8 @@ namespace Stetic.Editor {
useStock = false;
entry.Text = file;
File = file;
if (Changed != null)
Changed (this, EventArgs.Empty);
if (ValueChanged != null)
ValueChanged (this, EventArgs.Empty);
syncing = false;
}
}
@ -224,7 +234,7 @@ namespace Stetic.Editor {
}
}
public string Value {
public object Value {
get {
if (useStock) {
if (StockId != null)
@ -239,12 +249,13 @@ namespace Stetic.Editor {
}
}
set {
if (value == null)
string val = value as string;
if (val == null)
File = null;
else if (value.StartsWith ("stock:"))
StockId = value.Substring (6);
else if (value.StartsWith ("file:"))
File = value.Substring (5);
else if (val.StartsWith ("stock:"))
StockId = val.Substring (6);
else if (val.StartsWith ("file:"))
File = val.Substring (5);
}
}
}

Просмотреть файл

@ -2,11 +2,72 @@ using System;
namespace Stetic.Editor {
public class IntRange : Gtk.SpinButton {
public class IntRange : Gtk.SpinButton, IPropertyEditor {
public IntRange (object min, object max) :
base (min == null ? (double)Int32.MinValue : (double)min,
max == null ? (double)Int32.MaxValue : (double)max,
1.0) {}
Type propType;
public IntRange () : base (0, 0, 1.0)
{
}
public void Initialize (PropertyDescriptor prop)
{
propType = prop.PropertyType;
double min, max;
switch (Type.GetTypeCode (propType)) {
case TypeCode.Int16:
min = (double) Int16.MinValue;
max = (double) Int16.MaxValue;
break;
case TypeCode.UInt16:
min = (double) UInt16.MinValue;
max = (double) UInt16.MaxValue;
break;
case TypeCode.Int32:
min = (double) Int32.MinValue;
max = (double) Int32.MaxValue;
break;
case TypeCode.UInt32:
min = (double) UInt32.MinValue;
max = (double) UInt32.MaxValue;
break;
case TypeCode.Int64:
min = (double) Int64.MinValue;
max = (double) Int64.MaxValue;
break;
case TypeCode.UInt64:
min = (double) UInt64.MinValue;
max = (double) UInt64.MaxValue;
break;
case TypeCode.Byte:
min = (double) Byte.MinValue;
max = (double) Byte.MaxValue;
break;
case TypeCode.SByte:
min = (double) SByte.MinValue;
max = (double) SByte.MaxValue;
break;
default:
throw new ApplicationException ("IntRange editor does not support editing values of type " + prop.PropertyType);
}
if (prop.Minimum != null)
min = (double) Convert.ChangeType (prop.Minimum, typeof(double));
if (prop.Maximum != null)
max = (double) Convert.ChangeType (prop.Maximum, typeof(double));
SetRange (min, max);
}
public void AttachObject (object ob)
{
}
object IPropertyEditor.Value {
get { return Convert.ChangeType (base.Value, propType); }
set { base.Value = (double) Convert.ChangeType (value, typeof(double)); }
}
}
}

Просмотреть файл

@ -2,27 +2,54 @@ using System;
namespace Stetic.Editor {
public class OptIntRange : Gtk.HBox {
public class OptIntRange : Gtk.HBox, IPropertyEditor {
Gtk.CheckButton check;
Gtk.SpinButton spin;
object omin, omax;
public OptIntRange (object min, object max) : base (false, 6)
public OptIntRange () : base (false, 6)
{
}
public OptIntRange (object omin, object omax) : base (false, 6)
{
this.omin = omin;
this.omax = omax;
}
public void Initialize (PropertyDescriptor prop)
{
if (prop.PropertyType != typeof(int))
throw new ApplicationException ("OptIntRange editor does not support editing values of type " + prop.PropertyType);
double min = (double) Int32.MinValue;
double max = (double) Int32.MaxValue;
if (omin == null)
omin = prop.Minimum;
if (omax == null)
omax = prop.Maximum;
if (omin != null)
min = (double) Convert.ChangeType (omin, typeof(double));
if (omax != null)
max = (double) Convert.ChangeType (omax, typeof(double));
check = new Gtk.CheckButton ();
check.Show ();
check.Toggled += check_Toggled;
PackStart (check, false, false, 0);
if (min == null)
min = Int32.MinValue;
if (max == null)
max = Int32.MaxValue;
spin = new Gtk.SpinButton ((double)(int)min, (double)(int)max, 1.0);
spin = new Gtk.SpinButton (min, max, 1.0);
spin.Show ();
spin.ValueChanged += spin_ValueChanged;
PackStart (spin, true, true, 0);
}
public void AttachObject (object ob)
{
}
void check_Toggled (object o, EventArgs args)
{
@ -37,7 +64,7 @@ namespace Stetic.Editor {
ValueChanged (this, EventArgs.Empty);
}
public int Value {
public object Value {
get {
if (check.Active)
return (int)spin.Value;
@ -45,13 +72,14 @@ namespace Stetic.Editor {
return -1;
}
set {
if (value == -1) {
int val = (int) value;
if (val == -1) {
check.Active = false;
spin.Sensitive = false;
} else {
check.Active = true;
spin.Sensitive = true;
spin.Value = (double)value;
spin.Value = (double)val;
}
}
}

Просмотреть файл

@ -4,7 +4,7 @@ using System.Reflection;
namespace Stetic.Editor {
public class ResponseId : Gtk.HBox {
public class ResponseId : Gtk.HBox, IPropertyEditor {
Gtk.ComboBoxEntry combo;
Gtk.Entry entry;
@ -30,8 +30,18 @@ namespace Stetic.Editor {
}
}
}
public void Initialize (PropertyDescriptor prop)
{
if (prop.PropertyType != typeof(int))
throw new ApplicationException ("ResponseId editor does not support editing values of type " + prop.PropertyType);
}
public void AttachObject (object ob)
{
}
public int Value {
public object Value {
get {
if (combo.Active != -1)
return (int)values[combo.Active];
@ -44,7 +54,7 @@ namespace Stetic.Editor {
}
}
set {
combo.Active = values.IndexOf (value);
combo.Active = values.IndexOf ((int)value);
if (combo.Active == -1)
entry.Text = value.ToString ();
}

Просмотреть файл

@ -7,15 +7,23 @@ namespace Stetic.Editor {
Gtk.Entry entry;
public String (PropertyDescriptor prop, object obj) : base (prop, obj)
public override void Initialize (PropertyDescriptor prop)
{
base.Initialize (prop);
entry = new Gtk.Entry ();
entry.Show ();
entry.Changed += EntryChanged;
Add (entry);
}
public string Text {
protected override void CheckType (PropertyDescriptor prop)
{
if (prop.PropertyType != typeof(string))
throw new ApplicationException ("String editor does not support editing values of type " + prop.PropertyType);
}
public override object Value {
get {
return entry.Text;
}
@ -23,16 +31,13 @@ namespace Stetic.Editor {
if (value == null)
entry.Text = "";
else
entry.Text = value;
entry.Text = (string) value;
}
}
void EntryChanged (object obj, EventArgs args)
{
if (Changed != null)
Changed (this, EventArgs.Empty);
OnValueChanged ();
}
public event EventHandler Changed;
}
}

Просмотреть файл

@ -5,14 +5,19 @@ namespace Stetic.Editor {
[PropertyEditor ("Value", "Changed")]
public class StringArray : Text {
public StringArray (PropertyDescriptor prop, object obj) : base (prop, obj) {}
public new string[] Value {
protected override void CheckType (PropertyDescriptor prop)
{
if (prop.PropertyType != typeof(string[]))
throw new ApplicationException ("StringArray editor does not support editing values of type " + prop.PropertyType);
}
public override object Value {
get {
return base.Value.Split ('\n');
return ((string)base.Value).Split ('\n');
}
set {
base.Value = string.Join ("\n", value);
base.Value = string.Join ("\n", (string[]) value);
}
}
}

Просмотреть файл

@ -7,30 +7,36 @@ namespace Stetic.Editor {
Stetic.TextBox textbox;
public Text (PropertyDescriptor prop, object obj) : base (prop, obj)
public override void Initialize (PropertyDescriptor prop)
{
base.Initialize (prop);
textbox = new Stetic.TextBox (6);
textbox.Show ();
Add (textbox);
textbox.Changed += Text_Changed;
}
protected override void CheckType (PropertyDescriptor prop)
{
if (prop.PropertyType != typeof(string))
throw new ApplicationException ("Text editor does not support editing values of type " + prop.PropertyType);
}
public void Text_Changed (object obj, EventArgs args)
{
if (Changed != null)
Changed (this, EventArgs.Empty);
OnValueChanged ();
}
public string Value {
public override object Value {
get {
return textbox.Text;
}
set {
textbox.Text = value;
textbox.Text = (string) value;
}
}
public event EventHandler Changed;
}
}

Просмотреть файл

@ -4,7 +4,7 @@ using System;
namespace Stetic.Editor {
[PropertyEditor ("Value", "Changed")]
public class ThemedIcon : Gtk.HBox {
public class ThemedIcon : Gtk.HBox, IPropertyEditor {
Gtk.Image image;
Gtk.Entry entry;
Gtk.Button button;
@ -25,7 +25,17 @@ namespace Stetic.Editor {
button.Clicked += button_Clicked;
}
public event EventHandler Changed;
public void Initialize (PropertyDescriptor prop)
{
if (prop.PropertyType != typeof(string))
throw new ApplicationException ("ThemedIcon editor does not support editing values of type " + prop.PropertyType);
}
public void AttachObject (object ob)
{
}
public event EventHandler ValueChanged;
bool syncing;
@ -42,15 +52,16 @@ namespace Stetic.Editor {
}
string icon;
public string Value {
public object Value {
get {
return icon;
}
set {
if (icon == value)
val = (string) value;
if (icon == val)
return;
icon = value;
icon = val;
try {
image.Pixbuf = Gtk.IconTheme.Default.LoadIcon (icon, 16, 0);
} catch {
@ -61,8 +72,8 @@ namespace Stetic.Editor {
entry.Text = icon;
syncing = false;
if (Changed != null)
Changed (this, EventArgs.Empty);
if (ValueChanged != null)
ValueChanged (this, EventArgs.Empty);
}
}
}

Просмотреть файл

@ -2,7 +2,7 @@ using System;
namespace Stetic.Editor {
public abstract class Translatable : Gtk.VBox {
public abstract class Translatable : Gtk.VBox, IPropertyEditor {
PropertyDescriptor prop;
object obj;
@ -16,67 +16,50 @@ namespace Stetic.Editor {
Gtk.MenuItem addContextItem, remContextItem, addCommentItem, remCommentItem;
Gtk.Entry contextEntry;
Stetic.TextBox commentText;
bool initializing;
public Translatable (PropertyDescriptor prop, object obj) : base (false, 3)
public virtual void Initialize (PropertyDescriptor prop)
{
CheckType (prop);
this.prop = prop;
mainHBox = new Gtk.HBox (false, 6);
PackStart (mainHBox, false, false, 0);
if (!prop.Translatable)
return;
this.prop = prop;
this.obj = obj;
button = new Gtk.Button ();
globe = Gdk.Pixbuf.LoadFromResource ("globe.png");
globe_not = Gdk.Pixbuf.LoadFromResource ("globe-not.png");
image = new Gtk.Image (prop.IsTranslated (obj) ? globe : globe_not);
image = new Gtk.Image (globe);
button.Add (image);
button.ButtonPressEvent += ButtonPressed;
mainHBox.PackEnd (button, false, false, 0);
mainHBox.ShowAll ();
menu = new Gtk.Menu ();
markItem = new Gtk.CheckMenuItem ("Mark for Translation");
markItem.Active = prop.IsTranslated (obj);
markItem.Toggled += ToggleMark;
markItem.Show ();
menu.Add (markItem);
addContextItem = new Gtk.MenuItem ("Add Translation Context Hint");
addContextItem.Activated += AddContext;
menu.Add (addContextItem);
remContextItem = new Gtk.MenuItem ("Remove Translation Context Hint");
remContextItem.Activated += RemoveContext;
menu.Add (remContextItem);
if (prop.IsTranslated (obj)) {
if (prop.TranslationContext (obj) != null)
remContextItem.Show ();
else
addContextItem.Show ();
} else {
addContextItem.Show ();
addContextItem.Sensitive = false;
}
addCommentItem = new Gtk.MenuItem ("Add Comment for Translators");
addCommentItem.Activated += AddComment;
menu.Add (addCommentItem);
remCommentItem = new Gtk.MenuItem ("Remove Comment for Translators");
remCommentItem.Activated += RemoveComment;
menu.Add (remCommentItem);
if (prop.IsTranslated (obj)) {
if (prop.TranslationComment (obj) != null)
remCommentItem.Show ();
else
addCommentItem.Show ();
} else {
addCommentItem.Show ();
addCommentItem.Sensitive = false;
}
contextBox = new Gtk.HBox (false, 6);
Gtk.Label contextLabel = new Gtk.Label ("Translation context");
contextLabel.Xalign = 0.0f;
@ -85,10 +68,6 @@ namespace Stetic.Editor {
contextEntry.WidthChars = 8;
contextBox.PackStart (contextEntry, true, true, 0);
contextBox.ShowAll ();
if (prop.TranslationContext (obj) != null) {
PackStart (contextBox, false, false, 0);
contextEntry.Text = prop.TranslationContext (obj);
}
contextEntry.Changed += ContextChanged;
commentBox = new Gtk.VBox (false, 3);
@ -98,13 +77,68 @@ namespace Stetic.Editor {
commentText = new Stetic.TextBox (3);
commentBox.PackStart (commentText, false, false, 0);
commentBox.ShowAll ();
if (prop.TranslationComment (obj) != null) {
PackEnd (commentBox, false, false, 0);
commentText.Text = prop.TranslationComment (obj);
}
commentText.Changed += CommentChanged;
}
protected virtual void CheckType (PropertyDescriptor prop)
{
}
public virtual void AttachObject (object ob)
{
this.obj = ob;
if (!prop.Translatable)
return;
initializing = true;
if (contextBox.Parent != null)
Remove (contextBox);
if (commentBox.Parent != null)
Remove (commentBox);
markItem.Active = prop.IsTranslated (obj);
image.Pixbuf = markItem.Active ? globe : globe_not;
if (prop.IsTranslated (obj)) {
if (prop.TranslationContext (obj) != null) {
remContextItem.Show ();
PackStart (contextBox, false, false, 0);
contextEntry.Text = prop.TranslationContext (obj);
} else
addContextItem.Show ();
} else {
addContextItem.Show ();
addContextItem.Sensitive = false;
}
if (prop.IsTranslated (obj)) {
if (prop.TranslationComment (obj) != null) {
remCommentItem.Show ();
PackEnd (commentBox, false, false, 0);
commentText.Text = prop.TranslationComment (obj);
} else
addCommentItem.Show ();
} else {
addCommentItem.Show ();
addCommentItem.Sensitive = false;
}
initializing = false;
}
public abstract object Value { get; set; }
public event EventHandler ValueChanged;
protected virtual void OnValueChanged ()
{
if (ValueChanged != null)
ValueChanged (this, EventArgs.Empty);
}
protected override void OnAdded (Gtk.Widget child)
{
mainHBox.PackStart (child, true, true, 0);
@ -128,6 +162,7 @@ namespace Stetic.Editor {
void ToggleMark (object o, EventArgs args)
{
if (initializing) return;
if (!markItem.Active) {
// Make sure we're showing the "Add" menu items
// rather than the "Remove" ones
@ -163,6 +198,7 @@ namespace Stetic.Editor {
void ContextChanged (object o, EventArgs args)
{
if (initializing) return;
prop.SetTranslationContext (obj, contextEntry.Text);
}
@ -186,6 +222,7 @@ namespace Stetic.Editor {
void CommentChanged (object o, EventArgs args)
{
if (initializing) return;
prop.SetTranslationComment (obj, commentText.Text);
}
}

Просмотреть файл

@ -6,6 +6,9 @@ using System.Xml;
namespace Stetic.Wrapper {
public class Container : Widget {
int designWidth;
int designHeight;
public override void Wrap (object obj, bool initialized)
{
@ -45,6 +48,16 @@ namespace Stetic.Wrapper {
return true;
}
}
public int DesignWidth {
get { return designWidth; }
set { designWidth = value; NotifyChanged (); }
}
public int DesignHeight {
get { return designHeight; }
set { designHeight = value; NotifyChanged (); }
}
int freeze;
protected void Freeze ()
@ -89,6 +102,13 @@ namespace Stetic.Wrapper {
}
}
string ds = elem.GetAttribute ("design-size");
if (ds.Length > 0) {
int i = ds.IndexOf (' ');
DesignWidth = int.Parse (ds.Substring (0, i));
DesignHeight = int.Parse (ds.Substring (i+1));
}
Sync ();
}
@ -142,6 +162,8 @@ namespace Stetic.Wrapper {
elem.AppendChild (child_elem);
}
if (DesignWidth != 0 || DesignHeight != 0)
elem.SetAttribute ("design-size", DesignWidth + " " + DesignHeight);
return elem;
}
@ -559,6 +581,7 @@ namespace Stetic.Wrapper {
{
base.EmitNotify (propertyName);
ParentWrapper.Sync ();
ParentWrapper.OnWidgetChanged (new WidgetEventArgs (ParentWrapper));
}
Gtk.Container.ContainerChild cc {

Просмотреть файл

@ -0,0 +1,55 @@
namespace Stetic.Wrapper
{
public class Signal
{
SignalDescriptor descriptor;
string handlerName;
bool after;
internal Wrapper.Widget Owner;
public Signal (SignalDescriptor descriptor): this (descriptor, null, false)
{
}
public Signal (SignalDescriptor descriptor, string handlerName, bool after)
{
this.descriptor = descriptor;
this.handlerName = handlerName;
this.after = after;
}
void NotifyChanged (Signal oldData)
{
if (Owner != null)
Owner.OnSignalChanged (new SignalChangedEventArgs (Owner, oldData, this));
}
Signal Clone ()
{
return new Signal (descriptor, handlerName, after);
}
public SignalDescriptor SignalDescriptor {
get { return descriptor; }
}
public string Handler {
get { return handlerName; }
set {
Signal data = Clone ();
handlerName = value;
NotifyChanged (data);
}
}
public bool After {
get { return after; }
set {
Signal data = Clone ();
after = value;
NotifyChanged (data);
}
}
}
}

Просмотреть файл

@ -0,0 +1,19 @@
namespace Stetic.Wrapper
{
public delegate void SignalChangedEventHandler (object sender, SignalChangedEventArgs args);
public class SignalChangedEventArgs: SignalEventArgs
{
public Signal oldSignal;
public SignalChangedEventArgs (Wrapper.Widget widget, Signal oldSignal, Signal signal): base (widget, signal)
{
this.oldSignal = oldSignal;
}
public Signal OldSignal {
get { return oldSignal; }
}
}
}

Просмотреть файл

@ -0,0 +1,85 @@
using System;
using System.Collections;
namespace Stetic.Wrapper
{
public class SignalCollection: CollectionBase
{
Wrapper.Widget owner;
public SignalCollection ()
{
}
internal SignalCollection (Wrapper.Widget owner)
{
this.owner = owner;
}
public int Add (Signal signal)
{
return List.Add (signal);
}
public Signal this [int n] {
get { return (Signal) List [n]; }
}
public void Remove (Signal signal)
{
List.Remove (signal);
}
public void CopyTo (Signal[] signals, int index)
{
List.CopyTo (signals, index);
}
Signal[] clearedData;
protected override void OnClear ()
{
if (owner != null) {
clearedData = new Signal [Count];
List.CopyTo (clearedData, 0);
}
}
protected override void OnClearComplete ()
{
if (owner != null) {
Signal[] data = clearedData;
clearedData = null;
foreach (Signal s in data) {
s.Owner = null;
owner.OnSignalRemoved (new SignalEventArgs (owner, s));
}
}
}
protected override void OnInsertComplete (int index, object value)
{
if (owner != null) {
((Signal)value).Owner = owner;
owner.OnSignalAdded (new SignalEventArgs (owner, (Signal) value));
}
}
protected override void OnRemoveComplete (int index, object value)
{
if (owner != null) {
((Signal)value).Owner = null;
owner.OnSignalRemoved (new SignalEventArgs (owner, (Signal) value));
}
}
protected override void OnSetComplete (int index, object oldValue, object newValue)
{
if (owner != null) {
((Signal)oldValue).Owner = null;
owner.OnSignalRemoved (new SignalEventArgs (owner, (Signal) oldValue));
((Signal)newValue).Owner = owner;
owner.OnSignalAdded (new SignalEventArgs (owner, (Signal) newValue));
}
}
}
}

Просмотреть файл

@ -0,0 +1,19 @@
namespace Stetic.Wrapper
{
public delegate void SignalEventHandler (object sender, SignalEventArgs args);
public class SignalEventArgs: WidgetEventArgs
{
public Signal signal;
public SignalEventArgs (Widget widget, Signal signal): base (widget)
{
this.signal = signal;
}
public Signal Signal {
get { return signal; }
}
}
}

Просмотреть файл

@ -5,10 +5,30 @@ using System.Xml;
namespace Stetic.Wrapper {
public class Widget : Object {
string oldName;
SignalCollection signals;
public Widget ()
{
signals = new SignalCollection (this);
}
// Fired when the name of the widget changes.
public event WidgetNameChangedHandler NameChanged;
// Fired when any information of the object changes.
public event WidgetEventHandler WidgetChanged;
public event SignalEventHandler SignalAdded;
public event SignalEventHandler SignalRemoved;
public event SignalChangedEventHandler SignalChanged;
public override void Wrap (object obj, bool initialized)
{
base.Wrap (obj, initialized);
oldName = ((Gtk.Widget)obj).Name;
if (!(Wrapped is Gtk.Window))
Wrapped.ShowAll ();
@ -34,7 +54,7 @@ namespace Stetic.Wrapper {
}
}
}
public new Gtk.Widget Wrapped {
get {
return (Gtk.Widget)base.Wrapped;
@ -46,6 +66,14 @@ namespace Stetic.Wrapper {
return Container.LookupParent (Wrapped);
}
}
public bool IsTopLevel {
get { return Wrapped.Parent == null || Widget.Lookup (Wrapped.Parent) == null; }
}
public SignalCollection Signals {
get { return signals; }
}
[GLib.ConnectBefore]
void WidgetEvent (object obj, Gtk.WidgetEventArgs args)
@ -256,6 +284,66 @@ namespace Stetic.Wrapper {
else
return "[" + Wrapped.GetType ().Name + " " + Wrapped.GetHashCode ().ToString () + "]";
}
protected override void EmitNotify (string propertyName)
{
base.EmitNotify (propertyName);
// Don't notify parent change for top level widgets.
if (propertyName == "parent" || propertyName == "has-focus" ||
propertyName == "has-toplevel-focus" || propertyName == "is-active" ||
propertyName == "is-focus")
return;
if (propertyName == "name") {
if (Wrapped.Name != oldName) {
string on = oldName;
oldName = Wrapped.Name;
OnNameChanged (new WidgetNameChangedArgs (this, on, Wrapped.Name));
}
}
else
OnWidgetChanged (new WidgetEventArgs (this));
}
protected virtual void OnNameChanged (WidgetNameChangedArgs args)
{
OnWidgetChanged (args);
if (NameChanged != null)
NameChanged (this, args);
}
internal protected virtual void OnSignalAdded (SignalEventArgs args)
{
OnWidgetChanged (args);
if (SignalAdded != null)
SignalAdded (this, args);
}
internal protected virtual void OnSignalRemoved (SignalEventArgs args)
{
OnWidgetChanged (args);
if (SignalRemoved != null)
SignalRemoved (this, args);
}
internal protected virtual void OnSignalChanged (SignalChangedEventArgs args)
{
OnWidgetChanged (args);
if (SignalChanged != null)
SignalChanged (this, args);
}
internal protected virtual void OnWidgetChanged (WidgetEventArgs args)
{
if (WidgetChanged != null)
WidgetChanged (this, args);
}
protected void NotifyChanged ()
{
OnWidgetChanged (new WidgetEventArgs (this));
}
}
internal static class InsensitiveManager {

Просмотреть файл

@ -0,0 +1,20 @@
using System;
namespace Stetic.Wrapper
{
public delegate void WidgetEventHandler (object sender, WidgetEventArgs args);
public class WidgetEventArgs: EventArgs
{
Stetic.Wrapper.Widget widget;
public WidgetEventArgs (Stetic.Wrapper.Widget widget)
{
this.widget = widget;
}
public Stetic.Wrapper.Widget Widget {
get { return widget; }
}
}
}

Просмотреть файл

@ -0,0 +1,25 @@
namespace Stetic.Wrapper
{
public delegate void WidgetNameChangedHandler (object sender, WidgetNameChangedArgs args);
public class WidgetNameChangedArgs: WidgetEventArgs
{
string oldName;
string newName;
public WidgetNameChangedArgs (Stetic.Wrapper.Widget widget, string oldName, string newName): base (widget)
{
this.oldName = oldName;
this.newName = newName;
}
public string OldName {
get { return oldName; }
}
public string NewName {
get { return newName; }
}
}
}

Просмотреть файл

@ -21,13 +21,6 @@ namespace Stetic.Wrapper {
window.DeleteEvent += DeleteEvent;
}
public override void Select (Stetic.Wrapper.Widget wrapper)
{
if (wrapper == this)
Wrapped.Show ();
base.Select (wrapper);
}
[ConnectBefore]
void DeleteEvent (object obj, Gtk.DeleteEventArgs args)
{

Просмотреть файл

@ -20,6 +20,71 @@
<property name="Name" internal="true" init-with-name="true" />
</itemgroup>
</itemgroups>
<signals>
<itemgroup label="Common Widget Signals">
<signal name="AccelCanActivate" />
<signal name="AccelClosuresChanged" />
<signal name="ButtonPressEvent" />
<signal name="ButtonReleaseEvent" />
<signal name="ChildNotified" />
<signal name="ClientEvent" />
<signal name="ConfigureEvent" />
<signal name="DeleteEvent" />
<signal name="DestroyEvent" />
<signal name="DirectionChanged" />
<signal name="DragBegin" />
<signal name="DragDataDelete"/>
<signal name="DragDataGet" />
<signal name="DragDataReceived" />
<signal name="DragDrop" />
<signal name="DragEnd" />
<signal name="DragLeave" />
<signal name="DragMotion" />
<signal name="EnterNotifyEvent" />
<signal name="ExposeEvent" />
<signal name="Focused" />
<signal name="FocusGrabbed" />
<signal name="FocusInEvent" />
<signal name="FocusOutEvent" />
<signal name="GrabNotify" />
<signal name="HelpShown" />
<signal name="Hidden" />
<signal name="HierarchyChanged" />
<signal name="KeyPressEvent" />
<signal name="KeyReleaseEvent" />
<signal name="LeaveNotifyEvent" />
<signal name="MapEvent" />
<signal name="Mapped" />
<signal name="MnemonicActivated" />
<signal name="MotionNotifyEvent" />
<signal name="NoExposeEvent" />
<signal name="ParentSet" />
<signal name="PopupMenu" />
<signal name="PropertyNotifyEvent" />
<signal name="ProximityInEvent" />
<signal name="ProximityOutEvent" />
<signal name="Realized" />
<signal name="ScreenChanged" />
<signal name="ScrollEvent" />
<signal name="SelectionClearEvent" />
<signal name="SelectionGet" />
<signal name="SelectionNotifyEvent" />
<signal name="SelectionReceived" />
<signal name="SelectionRequestEvent" />
<signal name="Shown" />
<signal name="SizeAllocated" />
<signal name="SizeRequested" />
<signal name="StateChanged" />
<signal name="StyleSet" />
<signal name="UnmapEvent" />
<signal name="Unmapped" />
<signal name="Unrealized" />
<signal name="VisibilityNotifyEvent" />
<signal name="WidgetEvent" />
<signal name="WidgetEventAfter" />
<signal name="WindowStateEvent" />
</itemgroup>
</signals>
<glade-transform>
<!-- "events" property has extra spaces around "|"s -->
@ -70,7 +135,18 @@
</glade-transform>
</object>
<object type="Gtk.Container,gtk-sharp" wrapper="Stetic.Wrapper.Container" />
<object type="Gtk.Container,gtk-sharp" wrapper="Stetic.Wrapper.Container">
<signals>
<itemgroup label="Container Signals">
<signal name="Added" />
<signal name="FocusChildSet" />
<signal name="Removed" />
<signal name="ResizeChecked" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</signals>
</object>
<object type="Gtk.Container+ContainerChild,gtk-sharp" wrapper="Stetic.Wrapper.Container+ContainerChild" />
<object type="Gtk.Window,gtk-sharp" wrapper="Stetic.Wrapper.Window"
@ -104,6 +180,18 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Window Signals">
<signal name="DefaultActivated" />
<signal name="FrameEvent" />
<signal name="FocusActivated" />
<signal name="KeysChanged" />
<signal name="MoveFocus" />
<signal name="SetFocus" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.Misc,gtk-sharp">
@ -126,6 +214,17 @@
<property name="BorderWidth" />
</itemgroup>
</itemgroups>
<signals>
<itemgroup label="Paned Signals">
<signal name="CycleChildFocus" />
<signal name="ToggleHandleFocus" />
<signal name="AcceptPosition" />
<signal name="CancelPosition" />
<signal name="MoveHandle" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.Paned+PanedChild,gtk-sharp">
<itemgroups>
@ -150,6 +249,14 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Range Signals">
<signal name="AdjustBounds" />
<signal name="ValueChanged" />
<signal name="MoveSlider" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</signals>
</object>
<object type="Gtk.Scale,gtk-sharp" wrapper="Stetic.Wrapper.Scale">
@ -173,6 +280,13 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Scale Signals">
<signal name="FormatValue" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Range" />
</signals>
</object>
<object type="Gtk.Alignment,gtk-sharp"
@ -191,6 +305,10 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.Arrow,gtk-sharp"
@ -203,6 +321,9 @@
<itemgroup ref="Gtk.Misc" important="true" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
</signals>
</object>
<object type="Gtk.Bin,gtk-sharp" />
@ -221,6 +342,10 @@
<command name="InsertAfter" label="Insert After"
description="Insert an empty row/column after the selected one" />
</contextmenu>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.Box+BoxChild,gtk-sharp" wrapper="Stetic.Wrapper.Box+BoxChild">
<itemgroups>
@ -252,6 +377,10 @@
<property name="BorderWidth" />
</itemgroup>
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
<contextmenu>
<command name="InsertBefore" label="Insert Button Before"
description="Insert a new button before the selected one" />
@ -331,6 +460,18 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Button Signals">
<signal name="Activated" />
<signal name="Clicked" />
<signal name="Entered" />
<signal name="Left" />
<signal name="Pressed" />
<signal name="Released" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.Calendar,gtk-sharp"
@ -345,6 +486,18 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Calendar Signals">
<signal name="PrevMonth" />
<signal name="DaySelected" />
<signal name="NextMonth" />
<signal name="MonthChanged" />
<signal name="PrevYear" />
<signal name="DaySelectedDoubleClick" />
<signal name="NextYear" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</signals>
</object>
<object type="Gtk.CheckButton,gtk-sharp" wrapper="Stetic.Wrapper.CheckButton"
@ -369,6 +522,10 @@
<itemgroup ref="Gtk.Button.Extra" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Button" />
</signals>
<contextmenu>
<command ref="RemoveLabel" />
<command ref="RestoreLabel" />
@ -390,6 +547,19 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Menu Item Signals">
<signal name="Activated" />
<signal name="ActivateItem" />
<signal name="Deselected" />
<signal name="Selected" />
<signal name="Toggled" />
<signal name="ToggleSizeAllocated" />
<signal name="ToggleSizeRequested" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
<glade-transform>
<!-- A regular MenuItem with no label is really a SeparatorMenuItem -->
@ -425,6 +595,14 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Check Menu Item Signals">
<signal name="Toggled" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.MenuItem" />
</signals>
</object>
<object type="Gtk.ColorButton,gtk-sharp" wrapper="Stetic.Wrapper.ColorButton"
@ -438,6 +616,14 @@
<itemgroup ref="Gtk.Button.Extra" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Color Button Signals">
<signal name="ColorSet" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.Button" />
</signals>
</object>
<object type="Gtk.ComboBox,gtk-sharp" wrapper="Stetic.Wrapper.ComboBox"
@ -453,6 +639,13 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="ComboBox Signals">
<signal name="Changed" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.ComboBoxEntry,gtk-sharp" wrapper="Stetic.Wrapper.ComboBoxEntry"
@ -466,6 +659,11 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.ComboBox" />
</signals>
</object>
<object type="Gtk.Dialog,gtk-sharp" wrapper="Stetic.Wrapper.Dialog"
@ -496,6 +694,15 @@
<itemgroup ref="Gtk.Window.Size" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Dialog Signals">
<signal name="Close" />
<signal name="Response" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.Window" />
</signals>
<internal-children>
<property name="VBox" glade-name="vbox" />
<property name="ActionArea" glade-name="action_area" />
@ -508,6 +715,9 @@
<itemgroups>
<itemgroup ref="Gtk.Widget" important="false" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
</signals>
</object>
<object type="Gtk.Entry,gtk-sharp"
@ -529,6 +739,25 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Entry Signals">
<signal name="InsertAtCursor" />
<signal name="ToggleOverwrite" />
<signal name="PopulatePopup" />
<signal name="ClipboardCopied" />
<signal name="ClipboardPasted" />
<signal name="DeleteFromCursor" />
<signal name="Activated" />
<signal name="ClipboardCut" />
<signal name="MoveCursor" />
<signal name="Changed" />
<signal name="TextDeleted" />
<signal name="TextInserted" />
<signal name="EditingDone" />
<signal name="WidgetRemoved" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</signals>
</object>
<object type="Gtk.EventBox,gtk-sharp"
@ -541,6 +770,10 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.Expander,gtk-sharp" wrapper="Stetic.Wrapper.Expander"
@ -553,6 +786,13 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Expander Signals">
<signal name="Activated" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.FontButton,gtk-sharp" wrapper="Stetic.Wrapper.FontButton"
@ -571,6 +811,14 @@
<itemgroup ref="Gtk.Button.Extra" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Font Button Signals">
<signal name="FontSet" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.Button" />
</signals>
</object>
<object type="Gtk.Frame,gtk-sharp" wrapper="Stetic.Wrapper.Frame"
@ -584,6 +832,10 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.HBox,gtk-sharp"
@ -592,6 +844,10 @@
<itemgroup ref="Gtk.Box" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
<contextmenu ref="Gtk.Box" />
</object>
@ -602,6 +858,10 @@
<itemgroup ref="Gtk.ButtonBox" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
<contextmenu ref="Gtk.ButtonBox" />
<glade-transform>
<!-- If a child has a "response_id" of -11 (GTK_RESPONSE_HELP), it should be packed with the "secondary" property -->
@ -627,6 +887,11 @@
<itemgroup ref="Gtk.Paned" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.Paned" />
</signals>
</object>
<object type="Gtk.HScale,gtk-sharp" wrapper="Stetic.Wrapper.HScale"
@ -636,6 +901,11 @@
<itemgroup ref="Gtk.Scale" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Range" />
<itemgroup ref="Gtk.Scale" />
</signals>
</object>
<object type="Gtk.HScrollbar,gtk-sharp" wrapper="Stetic.Wrapper.HScrollbar"
@ -645,6 +915,11 @@
<itemgroup ref="Gtk.Range" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Range" />
<itemgroup ref="Gtk.Scale" />
</signals>
</object>
<object type="Gtk.HSeparator,gtk-sharp"
@ -653,6 +928,9 @@
<itemgroups>
<itemgroup ref="Gtk.Widget" important="false" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
</signals>
</object>
<object type="Gtk.Image,gtk-sharp" wrapper="Stetic.Wrapper.Image"
@ -680,6 +958,9 @@
<itemgroup ref="Gtk.Misc" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
</signals>
</object>
<object type="Gtk.ImageMenuItem,gtk-sharp" wrapper="Stetic.Wrapper.ImageMenuItem"
@ -693,6 +974,11 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.MenuItem" />
</signals>
</object>
<object type="Gtk.Label,gtk-sharp" wrapper="Stetic.Wrapper.Label"
@ -714,6 +1000,14 @@
<itemgroup ref="Gtk.Misc" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Label Signals">
<signal name="CopyClipboard" />
<signal name="MoveCursor" />
<signal name="PopulatePopup" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</signals>
</object>
<object type="Gtk.MenuBar,gtk-sharp"
@ -721,6 +1015,17 @@
<itemgroups>
<itemgroup ref="Gtk.Widget" important="false" />
</itemgroups>
<signals>
<itemgroup label="Menu Bar Signals">
<signal name="Deactivated" />
<signal name="SelectionDone" />
<signal name="MoveCurrent" />
<signal name="ActivateCurrent" />
<signal name="Canceled" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.Menu,gtk-sharp"
@ -728,6 +1033,17 @@
<itemgroups>
<itemgroup ref="Gtk.Widget" important="false" />
</itemgroups>
<signals>
<itemgroup label="Menu Signals">
<signal name="Deactivated" />
<signal name="SelectionDone" />
<signal name="MoveCurrent" />
<signal name="ActivateCurrent" />
<signal name="Canceled" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.Menu+MenuChild,gtk-sharp" />
@ -753,6 +1069,12 @@
<itemgroup ref="Gtk.Window.Size" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.Window" />
<itemgroup ref="Gtk.Dialog" />
</signals>
</object>
<object type="Gtk.Notebook,gtk-sharp" wrapper="Stetic.Wrapper.Notebook"
@ -772,6 +1094,17 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Notebook Signals">
<signal name="FocusTab" />
<signal name="ChangeCurrentPage" />
<signal name="MoveFocusOut" />
<signal name="SwitchPage" />
<signal name="SelectPage" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
<contextmenu>
<command name="PreviousPage" label="Go to Previous Page"
description="Show the previous page"
@ -812,6 +1145,14 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Option Menu Signals">
<signal name="Changed" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.Button" />
</signals>
<internal-children>
<property name="Menu" glade-name="menu" />
</internal-children>
@ -829,6 +1170,9 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
</signals>
</object>
<object type="Gtk.RadioButton,gtk-sharp" wrapper="Stetic.Wrapper.RadioButton"
@ -849,6 +1193,15 @@
<itemgroup ref="Gtk.Button.Extra" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Radio Button Signals">
<signal name="Toggled" />
<signal name="GroupChanged" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.Button" />
</signals>
<contextmenu>
<command ref="Gtk.CheckButton.RemoveLabel" />
<command ref="Gtk.CheckButton.RestoreLabel" />
@ -870,6 +1223,25 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Radio Menu Item Signals">
<signal name="Toggled" />
<signal name="GroupChanged" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.MenuItem" />
</signals>
</object>
<object type="Gtk.ToolItem,gtk-sharp" wrapper="Stetic.Wrapper.Widget">
<signals>
<itemgroup label="Tool Item Signals">
<signal name="ToolbarReconfigured" />
<signal name="CreateMenuProxy" />
<signal name="TooltipSet" />
</itemgroup>
</signals>
</object>
<object type="Gtk.ToolButton,gtk-sharp" wrapper="Stetic.Wrapper.ToolButton"
@ -884,6 +1256,14 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Tool Button Signals">
<signal name="Clicked" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.ToolItem" />
</signals>
</object>
<object type="Gtk.RadioToolButton,gtk-sharp" wrapper="Stetic.Wrapper.RadioToolButton"
@ -900,6 +1280,15 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Radio Tool Button Signals">
<signal name="Toggled" />
<signal name="Clicked" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.ToolItem" />
</signals>
</object>
<object type="Gtk.ScrolledWindow,gtk-sharp" wrapper="Stetic.Wrapper.ScrolledWindow"
@ -915,6 +1304,14 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Scrolled Window Signals">
<signal name="MoveFocusOut" />
<signal name="ScrollChild" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.SeparatorMenuItem,gtk-sharp"
@ -922,6 +1319,11 @@
<itemgroups>
<itemgroup ref="Gtk.Widget" important="false" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.MenuItem" />
</signals>
</object>
<object type="Gtk.SeparatorToolItem,gtk-sharp"
@ -932,6 +1334,11 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.ToolItem" />
</signals>
</object>
<object type="Gtk.SpinButton,gtk-sharp" wrapper="Stetic.Wrapper.SpinButton"
@ -955,6 +1362,16 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Spin Button Signals">
<signal name="ChangeValue" />
<signal name="Input" />
<signal name="ValueChanged" />
<signal name="Output" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Entry" />
</signals>
</object>
<object type="Gtk.Statusbar,gtk-sharp"
@ -966,6 +1383,14 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Statusbar Signals">
<signal name="TextPopped" />
<signal name="TextPushed" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.Table,gtk-sharp" wrapper="Stetic.Wrapper.Table"
@ -981,6 +1406,10 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
<contextmenu>
<command name="InsertRowBefore" label="Insert Row Before"
description="Insert an empty row above the selected row" />
@ -1116,6 +1545,24 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Text View Signals">
<signal name="PasteClipboard" />
<signal name="InsertAtCursor" />
<signal name="CutClipboard" />
<signal name="ToggleOverwrite" />
<signal name="PageHorizontally" />
<signal name="MoveFocus" />
<signal name="CopyClipboard" />
<signal name="DeleteFromCursor" />
<signal name="PopulatePopup" />
<signal name="MoveCursor" />
<signal name="SetAnchor" />
<signal name="ScrollAdjustmentsSet" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.ToggleButton,gtk-sharp"
@ -1134,6 +1581,14 @@
<itemgroup ref="Gtk.Button.Extra" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Toggle Button Signals">
<signal name="Toggled" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.Button" />
</signals>
</object>
<object type="Gtk.ToggleToolButton,gtk-sharp" wrapper="Stetic.Wrapper.ToggleToolButton"
@ -1147,6 +1602,15 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Toggle Tool Button Signals">
<signal name="Toggled" />
<signal name="Clicked" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.ToolItem" />
</signals>
</object>
<object type="Gtk.Toolbar,gtk-sharp" wrapper="Stetic.Wrapper.Toolbar"
@ -1160,6 +1624,15 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Toolbar Signals">
<signal name="OrientationChanged" />
<signal name="PopupContextMenu" />
<signal name="StyleChanged" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.Toolbar+ToolbarChild,gtk-sharp" wrapper="Stetic.Wrapper.Toolbar+ToolbarChild">
<itemgroups>
@ -1191,6 +1664,28 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Tree View Signals">
<signal name="CursorChanged" />
<signal name="TestCollapseRow" />
<signal name="RowActivated" />
<signal name="ExpandCollapseCursorRow" />
<signal name="ColumnsChanged" />
<signal name="UnselectAll" />
<signal name="SelectCursorParent" />
<signal name="RowCollapsed" />
<signal name="SelectAll" />
<signal name="SelectCursorRow" />
<signal name="TestExpandRow" />
<signal name="StartInteractiveSearch" />
<signal name="MoveCursor" />
<signal name="RowExpanded" />
<signal name="ToggleCursorRow" />
<signal name="ScrollAdjustmentsSet" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.VBox,gtk-sharp"
@ -1199,6 +1694,10 @@
<itemgroup ref="Gtk.Box" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
<contextmenu ref="Gtk.Box" />
</object>
@ -1209,6 +1708,10 @@
<itemgroup ref="Gtk.ButtonBox" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
<contextmenu ref="Gtk.ButtonBox" />
</object>
@ -1220,6 +1723,13 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Viewport Signals">
<signal name="ScrollAdjustmentsSet" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.VPaned,gtk-sharp"
@ -1229,6 +1739,11 @@
<itemgroup ref="Gtk.Paned" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.Paned" />
</signals>
</object>
<object type="Gtk.VScale,gtk-sharp" wrapper="Stetic.Wrapper.VScale"
@ -1238,6 +1753,11 @@
<itemgroup ref="Gtk.Scale" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Range" />
<itemgroup ref="Gtk.Scale" />
</signals>
</object>
<object type="Gtk.VScrollbar,gtk-sharp" wrapper="Stetic.Wrapper.VScrollbar"
@ -1247,6 +1767,11 @@
<itemgroup ref="Gtk.Range" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Range" />
<itemgroup ref="Gtk.Scale" />
</signals>
</object>
<object type="Gtk.VSeparator,gtk-sharp"
@ -1255,6 +1780,9 @@
<itemgroups>
<itemgroup ref="Gtk.Widget" important="false" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
</signals>
</object>
<object type="Stetic.Custom" cname="Custom"
@ -1311,6 +1839,13 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="Color Selection Signals">
<signal name="ColorChanged" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.ColorSelectionDialog,gtk-sharp" wrapper="Stetic.Wrapper.Window"
@ -1326,6 +1861,12 @@
<itemgroup ref="Gtk.Window.Size" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.Window" />
<itemgroup ref="Gtk.Dialog" />
</signals>
<internal-children>
<property name="ColorSelection" glade-name="color_selection" />
<property name="OkButton" glade-name="ok_button" />
@ -1349,6 +1890,16 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="File Chooser Widget Signals">
<signal name="SelectionChanged" />
<signal name="FileActivated" />
<signal name="UpdatePreview" />
<signal name="CurrentFolderChanged" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<!-- 2.6
@ -1391,6 +1942,18 @@
<itemgroup ref="Gtk.Window.Size" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup label="File Chooser Dialog Signals">
<signal name="SelectionChanged" />
<signal name="FileActivated" />
<signal name="UpdatePreview" />
<signal name="CurrentFolderChanged" />
</itemgroup>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.Window" />
<itemgroup ref="Gtk.Dialog" />
</signals>
<internal-children>
<property name="VBox" glade-name="vbox" />
<property name="ActionArea" glade-name="action_area" />
@ -1407,6 +1970,10 @@
</itemgroup>
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
</signals>
</object>
<object type="Gtk.FontSelectionDialog,gtk-sharp" wrapper="Stetic.Wrapper.FontSelectionDialog"
@ -1422,6 +1989,12 @@
<itemgroup ref="Gtk.Window.Size" />
<itemgroup ref="Gtk.Widget" />
</itemgroups>
<signals>
<itemgroup ref="Gtk.Widget" />
<itemgroup ref="Gtk.Container" />
<itemgroup ref="Gtk.Window" />
<itemgroup ref="Gtk.Dialog" />
</signals>
<internal-children>
<property name="FontSelection" glade-name="font_selection" />
<property name="OkButton" glade-name="ok_button" />

9
stetic.pc.in Normal file
Просмотреть файл

@ -0,0 +1,9 @@
prefix=@prefix@
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
Name: Stetic
Description: Stetic - A Gtk# GUI builder
Version: @VERSION@
Requires: gtk-sharp-2.0
Libs: -r:${prefix}/lib/stetic/stetic.exe -r:${prefix}/lib/stetic/libstetic.dll

Просмотреть файл

@ -22,10 +22,10 @@ namespace Stetic {
throw new ApplicationException ("Not a glade file according to node name");
project.BeginGladeImport ();
foreach (XmlNode toplevel in node.SelectNodes ("widget")) {
ObjectWrapper wrapper = Stetic.ObjectWrapper.GladeImport (project, (XmlElement)toplevel);
foreach (XmlElement toplevel in node.SelectNodes ("widget")) {
Wrapper.Container wrapper = Stetic.ObjectWrapper.GladeImport (project, toplevel) as Wrapper.Container;
if (wrapper != null)
project.AddWindow ((Gtk.Window)wrapper.Wrapped);
project.AddWidget ((Gtk.Widget)wrapper.Wrapped);
}
project.EndGladeImport ();
}
@ -39,7 +39,7 @@ namespace Stetic {
doc.AppendChild (toplevel);
foreach (Widget w in project.Toplevels) {
Stetic.Wrapper.Widget wrapper = Stetic.Wrapper.Widget.Lookup (w);
Stetic.Wrapper.Container wrapper = Stetic.Wrapper.Container.Lookup (w);
if (wrapper == null)
continue;

Просмотреть файл

@ -10,6 +10,7 @@ stetic_exe_sources = \
Project.cs \
ProjectView.cs \
PropertyEditor.cs \
SignalsEditor.cs \
PropertyGrid.cs \
Stetic.cs \
UIManager.cs \

Просмотреть файл

@ -9,6 +9,7 @@ namespace Stetic {
public class Palette : Gtk.VBox, IComparer {
Hashtable groups;
Project project;
class Group : Gtk.Expander {
@ -34,9 +35,30 @@ namespace Stetic {
}
}
public Palette (Project project) : base (false, 2)
public Palette () : base (false, 2)
{
groups = new Hashtable ();
}
public Palette (Project project): this ()
{
this.Project = project;
}
public Project Project {
get { return project; }
set {
project = value;
LoadWidgets (project);
}
}
public void LoadWidgets (Project project)
{
foreach (Group g in groups.Values)
Remove (g);
groups.Clear ();
AddOrGetGroup ("widget", "Widgets");
AddOrGetGroup ("container", "Containers");
@ -60,9 +82,10 @@ namespace Stetic {
AddOrGetGroup(klass.Category).Append (factory);
}
ShowAll ();
}
public int Compare (object x, object y)
int IComparer.Compare (object x, object y)
{
return string.Compare (((ClassDescriptor)x).Label,
((ClassDescriptor)y).Label);

Просмотреть файл

@ -7,13 +7,38 @@ namespace Stetic {
public class Project : IProject {
Hashtable nodes;
NodeStore store;
bool modified;
internal bool Syncing;
Gtk.Widget selection;
public event Wrapper.WidgetNameChangedHandler WidgetNameChanged;
public event Wrapper.WidgetEventHandler WidgetAdded;
public event Wrapper.WidgetEventHandler WidgetRemoved;
public event Wrapper.SignalEventHandler SignalAdded;
public event Wrapper.SignalEventHandler SignalRemoved;
public event Wrapper.SignalChangedEventHandler SignalChanged;
public event SelectedHandler Selected;
public event EventHandler ModifiedChanged;
public Project ()
{
nodes = new Hashtable ();
store = new NodeStore (typeof (ProjectNode));
}
public bool Modified {
get { return modified; }
set {
if (modified != value) {
modified = value;
OnModifiedChanged (EventArgs.Empty);
}
}
}
public void AddWindow (Gtk.Window window)
{
AddWindow (window, false);
@ -26,6 +51,13 @@ namespace Stetic {
Selection = window;
}
public void AddWidget (Gtk.Widget widget)
{
if (!typeof(Gtk.Container).IsInstanceOfType (widget))
throw new System.ArgumentException ("widget", "Only containers can be top level widgets");
AddWidget (widget, null, -1);
}
void AddWidget (Widget widget, ProjectNode parent)
{
AddWidget (widget, parent, -1);
@ -33,9 +65,16 @@ namespace Stetic {
void AddWidget (Widget widget, ProjectNode parent, int position)
{
if (Stetic.Wrapper.Widget.Lookup (widget) == null)
Stetic.Wrapper.Widget ww = Stetic.Wrapper.Widget.Lookup (widget);
if (ww == null)
return;
ww.WidgetChanged += OnWidgetChanged;
ww.NameChanged += OnWidgetNameChanged;
ww.SignalAdded += OnSignalAdded;
ww.SignalRemoved += OnSignalRemoved;
ww.SignalChanged += OnSignalChanged;
ProjectNode node = new ProjectNode (widget);
nodes[widget] = node;
if (parent == null) {
@ -53,6 +92,8 @@ namespace Stetic {
parent = node;
OnWidgetAdded (new Stetic.Wrapper.WidgetEventArgs (ww));
Stetic.Wrapper.Container container = Stetic.Wrapper.Container.Lookup (widget);
if (container != null) {
container.ContentsChanged += ContentsChanged;
@ -63,6 +104,15 @@ namespace Stetic {
void UnhashNodeRecursive (ProjectNode node)
{
Stetic.Wrapper.Widget ww = Stetic.Wrapper.Widget.Lookup (node.Widget);
ww.WidgetChanged -= OnWidgetChanged;
ww.NameChanged -= OnWidgetNameChanged;
ww.SignalAdded -= OnSignalAdded;
ww.SignalRemoved -= OnSignalRemoved;
ww.SignalChanged -= OnSignalChanged;
OnWidgetRemoved (new Stetic.Wrapper.WidgetEventArgs (ww));
nodes.Remove (node.Widget);
for (int i = 0; i < node.ChildCount; i++)
UnhashNodeRecursive (node[i] as ProjectNode);
@ -85,6 +135,59 @@ namespace Stetic {
if (node != null)
RemoveNode (node);
}
void OnWidgetChanged (object sender, Wrapper.WidgetEventArgs args)
{
if (!Syncing)
Modified = true;
}
void OnWidgetNameChanged (object sender, Stetic.Wrapper.WidgetNameChangedArgs args)
{
if (!Syncing) {
Modified = true;
OnWidgetNameChanged (args);
}
}
protected virtual void OnWidgetNameChanged (Stetic.Wrapper.WidgetNameChangedArgs args)
{
if (WidgetNameChanged != null)
WidgetNameChanged (this, args);
}
void OnSignalAdded (object sender, Wrapper.SignalEventArgs args)
{
OnSignalAdded (args);
}
protected virtual void OnSignalAdded (Wrapper.SignalEventArgs args)
{
if (SignalAdded != null)
SignalAdded (this, args);
}
void OnSignalRemoved (object sender, Wrapper.SignalEventArgs args)
{
OnSignalRemoved (args);
}
protected virtual void OnSignalRemoved (Wrapper.SignalEventArgs args)
{
if (SignalRemoved != null)
SignalRemoved (this, args);
}
void OnSignalChanged (object sender, Wrapper.SignalChangedEventArgs args)
{
OnSignalChanged (args);
}
protected virtual void OnSignalChanged (Wrapper.SignalChangedEventArgs args)
{
if (SignalChanged != null)
SignalChanged (this, args);
}
void ContentsChanged (Stetic.Wrapper.Container cwrap)
{
@ -121,6 +224,8 @@ namespace Stetic {
while (i < children.Count)
AddWidget (children[i++] as Widget, node);
Modified = true;
}
public IEnumerable Toplevels {
@ -153,9 +258,6 @@ namespace Stetic {
}
public delegate void SelectedHandler (Gtk.Widget selection, ProjectNode node);
public event SelectedHandler Selected;
Gtk.Widget selection;
// IProject
@ -170,6 +272,8 @@ namespace Stetic {
// FIXME: should there be an IsDestroyed property?
if (selection != null && selection.Handle != IntPtr.Zero) {
Stetic.Wrapper.Container parent = Stetic.Wrapper.Container.LookupParent (selection);
if (parent == null)
parent = Stetic.Wrapper.Container.Lookup (selection);
if (parent != null)
parent.UnSelect (selection);
}
@ -223,6 +327,24 @@ namespace Stetic {
if (GladeImportComplete != null)
GladeImportComplete ();
}
protected virtual void OnModifiedChanged (EventArgs args)
{
if (ModifiedChanged != null)
ModifiedChanged (this, args);
}
protected virtual void OnWidgetRemoved (Stetic.Wrapper.WidgetEventArgs args)
{
if (WidgetRemoved != null)
WidgetRemoved (this, args);
}
protected virtual void OnWidgetAdded (Stetic.Wrapper.WidgetEventArgs args)
{
if (WidgetAdded != null)
WidgetAdded (this, args);
}
}
[TreeNode (ColumnCount=2)]
@ -261,6 +383,4 @@ namespace Stetic {
return "[ProjectNode " + GetHashCode().ToString() + " " + widget.GetType().FullName + " '" + Name + "']";
}
}
}

Просмотреть файл

@ -3,8 +3,11 @@ using System;
namespace Stetic {
public class ProjectView : NodeView {
public ProjectView (Project project) : base (project.Store)
public class ProjectView : NodeView
{
Project project;
public ProjectView ()
{
TreeViewColumn col;
CellRenderer renderer;
@ -24,9 +27,26 @@ namespace Stetic {
NodeSelection.Mode = SelectionMode.Single;
NodeSelection.Changed += RowSelected;
project.Selected += WidgetSelected;
}
public ProjectView (Project project): this ()
{
this.Project = project;
}
public Project Project {
get { return project; }
set {
if (project != null)
project.Selected -= WidgetSelected;
project = value;
if (project != null) {
NodeStore = project.Store;
project.Selected += WidgetSelected;
}
}
}
Stetic.Wrapper.Widget SelectedWrapper {
get {
ITreeNode[] nodes = NodeSelection.SelectedNodes;
@ -46,8 +66,9 @@ namespace Stetic {
if (!syncing) {
syncing = true;
Stetic.Wrapper.Widget selection = SelectedWrapper;
if (selection != null)
if (selection != null) {
selection.Select ();
}
syncing = false;
}
}

Просмотреть файл

@ -6,13 +6,11 @@ using System.Reflection;
namespace Stetic {
public class PropertyEditor : VBox {
Widget editor;
IPropertyEditor propEditor;
object obj;
PropertyDescriptor prop;
PropertyInfo editorProp;
EventInfo editorEvent;
static Hashtable editors;
static PropertyEditor ()
@ -35,89 +33,72 @@ namespace Stetic {
editors[typeof (string[])] = typeof (Stetic.Editor.StringArray);
editors[typeof (Gdk.Color)] = typeof (Stetic.Editor.Color);
}
public PropertyEditor (PropertyDescriptor prop, object obj) : base (false, 0)
public PropertyEditor (PropertyDescriptor prop) : base (false, 0)
{
this.obj = obj;
this.prop = prop;
propEditor = CreateEditor (prop);
propEditor.ValueChanged += new EventHandler (EditorValueChanged);
Add ((Gtk.Widget) propEditor);
}
public void AttachObject (object ob)
{
if (ob == null)
throw new ArgumentNullException ("ob");
syncing = true;
this.obj = ob;
propEditor.AttachObject (obj);
// It is the responsibility of the editor to convert value types
object initial = prop.GetValue (obj);
propEditor.Value = initial;
syncing = false;
}
public IPropertyEditor CreateEditor (PropertyDescriptor prop)
{
Type editorType;
object min, max, initial;
object min, max;
IPropertyEditor editor = null;
min = prop.Minimum;
max = prop.Maximum;
initial = prop.GetValue (obj);
editorType = prop.EditorType;
if (editorType == null) {
if (prop.PropertyType.IsEnum) {
if (prop.PropertyType.IsDefined (typeof (FlagsAttribute), true))
editorType = typeof (Stetic.Editor.Flags);
editor = new Stetic.Editor.Flags ();
else
editorType = typeof (Stetic.Editor.Enumeration);
min = max = null;
editor = new Stetic.Editor.Enumeration ();
} else if (prop.PropertyType == typeof (int) && min != null && ((int)min == -1)) {
editorType = typeof (Stetic.Editor.OptIntRange);
min = 0;
editor = new Stetic.Editor.OptIntRange (0, max);
} else {
editorType = editors[prop.PropertyType] as Type;
if (editorType == null) {
Label label = new Gtk.Label ("(" + prop.PropertyType.Name + ")");
label.Show ();
Add (label);
syncing = true;
return;
}
if (editorType == null)
editor = new DummyEditor ();
}
}
editorProp = EditorValueProperty (editorType);
editorEvent = EditorValueEvent (editorType);
// If the passed in values aren't the same type as used by the
// editor, convert them.
if (editorProp.PropertyType != prop.PropertyType && !prop.PropertyType.IsEnum) {
if (min != null)
min = Convert.ChangeType (min, editorProp.PropertyType);
if (max != null)
max = Convert.ChangeType (max, editorProp.PropertyType);
if (initial != null)
initial = Convert.ChangeType (initial, editorProp.PropertyType);
if (editor == null) {
editor = Activator.CreateInstance (editorType) as IPropertyEditor;
if (editor == null)
throw new Exception ("The property editor '" + editorType + "' must implement the interface IPropertyEditor");
}
// Find a constructor.
ConstructorInfo ctor = editorType.GetConstructor (new Type[] { typeof (PropertyDescriptor) });
if (ctor != null)
editor = (Widget)ctor.Invoke (new object[] { prop });
else {
// min/max
ctor = editorType.GetConstructor (new Type[] { typeof (object), typeof (object) });
if (ctor != null)
editor = (Widget)ctor.Invoke (new object[] { min, max });
else {
ctor = editorType.GetConstructor (new Type[] { typeof (PropertyDescriptor), typeof (object) });
if (ctor != null)
editor = (Widget)ctor.Invoke (new object[] { prop, obj });
else {
ctor = editorType.GetConstructor (new Type[0]);
if (ctor == null)
throw new ApplicationException ("No constructor for editor type " + editorType.ToString () + " for " + prop.Name);;
editor = (Widget)ctor.Invoke (new object[0]);
}
}
}
editor.Initialize (prop);
if (editorProp.CanWrite && initial != null)
editorProp.SetValue (editor, initial, null);
editor.ShowAll ();
if (prop.CanWrite && (editorEvent != null))
editorEvent.AddEventHandler (editor, new EventHandler (EditorValueChanged));
else
editor.Sensitive = false;
Add (editor);
Gtk.Widget w = editor as Gtk.Widget;
if (w == null)
throw new Exception ("The property editor '" + editorType + "' must be a Gtk Widget");
w.ShowAll ();
return editor;
}
bool syncing = false;
@ -126,10 +107,7 @@ namespace Stetic {
{
if (!syncing) {
syncing = true;
object value = editorProp.GetValue (editor, null);
if (editorProp.PropertyType != prop.PropertyType && !prop.PropertyType.IsEnum)
value = Convert.ChangeType (value, prop.PropertyType);
prop.SetValue (obj, value);
prop.SetValue (obj, propEditor.Value);
syncing = false;
}
}
@ -138,36 +116,28 @@ namespace Stetic {
{
if (!syncing) {
syncing = true;
object value = prop.GetValue (obj);
if (editorProp.PropertyType != prop.PropertyType && !prop.PropertyType.IsEnum)
value = Convert.ChangeType (value, editorProp.PropertyType);
editorProp.SetValue (editor, value, null);
propEditor.Value = prop.GetValue (obj);
syncing = false;
}
}
protected static PropertyInfo EditorValueProperty (Type editorType)
}
class DummyEditor: Gtk.Label, IPropertyEditor
{
public void Initialize (PropertyDescriptor prop)
{
if (editorType.IsDefined (typeof (Stetic.PropertyEditorAttribute), false)) {
foreach (object attr in editorType.GetCustomAttributes (typeof (Stetic.PropertyEditorAttribute), false)) {
PropertyEditorAttribute peattr = (PropertyEditorAttribute)attr;
return editorType.GetProperty (peattr.Property);
}
}
return editorType.GetProperty ("Value");
Text = "(" + prop.PropertyType.Name + ")";
}
protected static EventInfo EditorValueEvent (Type editorType)
public void AttachObject (object obj)
{
if (editorType.IsDefined (typeof (Stetic.PropertyEditorAttribute), false)) {
foreach (object attr in editorType.GetCustomAttributes (typeof (Stetic.PropertyEditorAttribute), false)) {
PropertyEditorAttribute peattr = (PropertyEditorAttribute)attr;
return editorType.GetEvent (peattr.Event);
}
}
return editorType.GetEvent ("ValueChanged");
}
public object Value {
get { return null; }
set { }
}
public event EventHandler ValueChanged { add {} remove {} }
}
}

Просмотреть файл

@ -6,125 +6,94 @@ using System.Reflection;
namespace Stetic {
public class PropertyGrid : Stetic.Grid {
public class PropertyGrid : Gtk.VBox {
Hashtable editors;
Hashtable sensitives, invisibles;
Hashtable cachedGroups = new Hashtable ();
Stetic.Wrapper.Widget selection;
Stetic.Wrapper.Widget newSelection;
Stetic.Wrapper.Container.ContainerChild packingSelection;
PropertyGridHeader header;
Gtk.Widget noSelection;
Project project;
public PropertyGrid (Project project)
public PropertyGrid ()
{
project.Selected += Selected;
Selected (null, null);
header = new PropertyGridHeader ();
header.Show ();
PackStart (header, false, false, 0);
Label lab = new Label ();
lab.Markup = "<i>No selection</i>";
PackStart (lab, false, false, 0);
noSelection = lab;
}
public PropertyGrid (Project project): this ()
{
this.Project = project;
}
public Project Project {
get { return project; }
set {
if (project != null)
project.Selected -= Selected;
project = value;
project.Selected += Selected;
Selected (null, null);
}
}
new void Clear ()
void Clear ()
{
base.Clear ();
if (selection != null) {
selection.Notify -= Notified;
selection = null;
}
editors = new Hashtable ();
sensitives = new Hashtable ();
invisibles = new Hashtable ();
}
PropertyDescriptor name;
void AppendHeader ()
{
if (name == null)
name = (PropertyDescriptor)Registry.LookupClass ("GtkWidget") ["Name"];
AppendProperty (name, selection.Wrapped);
Gtk.HBox box = new Gtk.HBox (false, 6);
box.PackStart (new Gtk.Image (Registry.LookupClass (selection.Wrapped.GetType ()).Icon), false, false, 0);
box.PackStart (new Gtk.Label (selection.Wrapped.GetType ().FullName), false, false, 0);
box.ShowAll ();
AppendPair ("Widget Class", box, null);
}
void AppendProperty (PropertyDescriptor prop, object obj)
{
PropertyEditor rep = new PropertyEditor (prop, obj);
editors[prop.Name] = rep;
if (prop.ParamSpec != null)
editors[prop.ParamSpec.Name] = rep;
rep.ShowAll ();
AppendPair (prop.Label, rep, prop.Description);
if (prop.HasDependencies)
sensitives[prop] = obj;
if (prop.HasVisibility)
invisibles[prop] = obj;
}
void AppendCommand (CommandDescriptor cmd, object obj)
{
Gtk.Button button = new Gtk.Button (cmd.Label);
button.Clicked += delegate (object o, EventArgs args) {
cmd.Run (obj);
};
button.Show ();
Append (button, cmd.Description);
if (cmd.HasDependencies) {
editors[cmd.Name] = button;
sensitives[cmd] = obj;
}
if (cmd.HasVisibility) {
editors[cmd.Name] = button;
invisibles[cmd] = obj;
}
foreach (Gtk.Widget w in Children)
// Remove (w);
w.Hide ();
}
void Notified (object wrapper, string propertyName)
{
PropertyEditor ed = editors[propertyName] as PropertyEditor;
if (ed != null)
ed.Update ();
UpdateSensitivity ();
}
void UpdateSensitivity ()
{
foreach (ItemDescriptor item in sensitives.Keys) {
Widget w = editors[item.Name] as Widget;
if (w != null)
w.Sensitive = item.EnabledFor (sensitives[item]);
}
foreach (ItemDescriptor item in invisibles.Keys) {
Widget w = editors[item.Name] as Widget;
if (w != null) {
if (!item.VisibleFor (invisibles[item]))
w.Hide ();
else
w.Show ();
}
foreach (object ob in Children) {
PropertyGridGroup grid = ob as PropertyGridGroup;
if (grid != null)
grid.Notified (propertyName);
}
}
void Selected (Gtk.Widget widget, ProjectNode node)
{
newSelection = Stetic.Wrapper.Widget.Lookup (widget);
GLib.Timeout.Add (50, new GLib.TimeoutHandler (SelectedHandler));
}
bool SelectedHandler ()
{
ClassDescriptor klass;
Clear ();
selection = newSelection;
selection = Stetic.Wrapper.Widget.Lookup (widget);
if (selection == null) {
AppendLabel ("<i>No selection</i>");
return;
noSelection.Show ();
return false;
}
header.Show ();
selection.Notify += Notified;
klass = Registry.LookupClass (selection.Wrapped.GetType ());
AppendHeader ();
header.AttachObject (selection.Wrapped);
AppendItemGroups (klass, selection.Wrapped);
packingSelection = Stetic.Wrapper.Container.ChildWrapper (selection);
@ -135,24 +104,157 @@ namespace Stetic {
packingSelection.Notify += Notified;
}
}
UpdateSensitivity ();
return false;
}
void AppendItemGroups (ClassDescriptor klass, object obj)
{
int nImportantGroups = klass.ImportantGroups;
int n = 1;
foreach (ItemGroup igroup in klass.ItemGroups) {
AppendGroup (igroup.Label, nImportantGroups-- > 0);
foreach (ItemDescriptor item in igroup) {
if (item.IsInternal)
continue;
if (item is PropertyDescriptor)
AppendProperty ((PropertyDescriptor)item, obj);
else if (item is CommandDescriptor)
AppendCommand ((CommandDescriptor)item, obj);
PropertyGridGroup grid = (PropertyGridGroup) cachedGroups [igroup];
if (grid == null) {
grid = new PropertyGridGroup ();
grid.AddGroup (igroup);
cachedGroups [igroup] = grid;
PackStart (grid, false, false, 0);
}
ReorderChild (grid, n++);
grid.ShowAll ();
grid.AttachObject (obj);
}
}
}
class PropertyGridGroup: Stetic.Grid
{
Hashtable editors;
Hashtable sensitives, invisibles;
object obj;
public PropertyGridGroup ()
{
editors = new Hashtable ();
sensitives = new Hashtable ();
invisibles = new Hashtable ();
}
public void AddGroup (ItemGroup igroup)
{
AppendGroup (igroup.Label, true);
foreach (ItemDescriptor item in igroup) {
if (item.IsInternal)
continue;
if (item is PropertyDescriptor)
AppendProperty ((PropertyDescriptor)item);
else if (item is CommandDescriptor)
AppendCommand ((CommandDescriptor)item);
}
}
public virtual void AttachObject (object ob)
{
this.obj = ob;
foreach (object ed in editors.Values) {
PropertyEditor pe = ed as PropertyEditor;
if (pe != null)
pe.AttachObject (ob);
}
UpdateSensitivity ();
}
protected void AppendProperty (PropertyDescriptor prop)
{
PropertyEditor rep = new PropertyEditor (prop);
editors[prop.Name] = rep;
if (prop.ParamSpec != null)
editors[prop.ParamSpec.Name] = rep;
AppendPair (prop.Label, rep, prop.Description);
rep.ShowAll ();
if (prop.HasDependencies)
sensitives[prop] = prop;
if (prop.HasVisibility)
invisibles[prop] = prop;
}
void AppendCommand (CommandDescriptor cmd)
{
Gtk.Button button = new Gtk.Button (cmd.Label);
button.Clicked += delegate (object o, EventArgs args) {
cmd.Run (this.obj);
};
button.Show ();
Append (button, cmd.Description);
if (cmd.HasDependencies) {
editors[cmd.Name] = button;
sensitives[cmd] = cmd;
}
if (cmd.HasVisibility) {
editors[cmd.Name] = button;
invisibles[cmd] = cmd;
}
}
void UpdateSensitivity ()
{
foreach (ItemDescriptor item in sensitives.Keys) {
Widget w = editors[item.Name] as Widget;
if (w != null) {
object ob = sensitives.Contains (item) ? obj : null;
w.Sensitive = item.EnabledFor (ob);
}
}
foreach (ItemDescriptor item in invisibles.Keys) {
Widget w = editors[item.Name] as Widget;
if (w != null) {
object ob = invisibles.Contains (item) ? obj : null;
if (!item.VisibleFor (ob))
w.Hide ();
else
w.Show ();
}
}
}
public void Notified (string propertyName)
{
PropertyEditor ed = editors [propertyName] as PropertyEditor;
if (ed != null)
ed.Update ();
UpdateSensitivity ();
}
}
class PropertyGridHeader: PropertyGridGroup
{
PropertyDescriptor name;
Gtk.Image image;
Gtk.Label label;
public PropertyGridHeader ()
{
name = (PropertyDescriptor)Registry.LookupClass ("GtkWidget") ["Name"];
AppendProperty (name);
Gtk.HBox box = new Gtk.HBox (false, 6);
image = new Gtk.Image ();
box.PackStart (image, false, false, 0);
label = new Gtk.Label ();
box.PackStart (label, false, false, 0);
box.ShowAll ();
AppendPair ("Widget Class", box, null);
}
public override void AttachObject (object ob)
{
base.AttachObject (ob);
Gtk.Widget w = (Gtk.Widget) ob;
image.Pixbuf = Registry.LookupClass (w.GetType ()).Icon;
label.Text = w.GetType().FullName;
}
}
}

354
stetic/SignalsEditor.cs Normal file
Просмотреть файл

@ -0,0 +1,354 @@
using System;
using System.Collections;
using Stetic.Wrapper;
namespace Stetic
{
public class SignalsEditor: Gtk.ScrolledWindow
{
Gtk.TreeView tree;
Gtk.TreeStore store;
Project project;
Stetic.Wrapper.Widget selection;
bool internalChange;
const int ColSignal = 0;
const int ColHandler = 1;
const int ColAfter = 2;
const int ColHasHandler = 3;
const int ColIsSignal = 4;
const int ColDescriptorObject = 5;
const int ColSignalObject = 6;
const int ColSignalTextWeight = 7;
public SignalsEditor ()
{
tree = new Gtk.TreeView ();
store = new Gtk.TreeStore (typeof(string), typeof(string), typeof(bool), typeof(bool), typeof(bool), typeof(SignalDescriptor), typeof(Signal), typeof(int));
tree.Model = store;
tree.RowActivated += new Gtk.RowActivatedHandler (OnRowActivated);
Gtk.CellRendererText crtSignal = new Gtk.CellRendererText ();
Gtk.CellRendererText crtHandler = new Gtk.CellRendererText ();
crtHandler.Editable = true;
crtHandler.Edited += new Gtk.EditedHandler (OnHandlerEdited);
Gtk.CellRendererToggle crtogAfter = new Gtk.CellRendererToggle ();
crtogAfter.Activatable = true;
crtogAfter.Toggled += new Gtk.ToggledHandler (OnAfterToggled);
tree.AppendColumn ("Signal", crtSignal, "text", ColSignal, "weight", ColSignalTextWeight);
tree.AppendColumn ("Handler", crtHandler, "markup", ColHandler, "visible", ColIsSignal);
tree.AppendColumn ("After", crtogAfter, "active", ColAfter, "visible", ColHasHandler);
Add (tree);
ShowAll ();
}
public SignalsEditor (Project project): this ()
{
Project = project;
}
public Project Project {
get { return project; }
set {
if (project != null) {
project.Selected -= OnWidgetSelected;
project.SignalAdded -= new SignalEventHandler (OnSignalAddedOrRemoved);
project.SignalRemoved -= new SignalEventHandler (OnSignalAddedOrRemoved);
project.SignalChanged -= new SignalChangedEventHandler (OnSignalChanged);
}
project = value;
project.Selected += OnWidgetSelected;
project.SignalAdded += new SignalEventHandler (OnSignalAddedOrRemoved);
project.SignalRemoved += new SignalEventHandler (OnSignalAddedOrRemoved);
project.SignalChanged += new SignalChangedEventHandler (OnSignalChanged);
OnWidgetSelected (null, null);
}
}
void OnWidgetSelected (Gtk.Widget widget, ProjectNode node)
{
selection = Stetic.Wrapper.Widget.Lookup (widget);
RefreshTree ();
}
void OnSignalAddedOrRemoved (object sender, SignalEventArgs args)
{
if (!internalChange && args.Widget == selection)
RefreshTree ();
}
void OnSignalChanged (object sender, SignalChangedEventArgs args)
{
if (!internalChange && args.Widget == selection)
RefreshTree ();
}
void RefreshTree ()
{
ArrayList status = SaveStatus ();
store.Clear ();
if (selection == null)
return;
ClassDescriptor klass = Registry.LookupClass (selection.Wrapped.GetType ());
foreach (ItemGroup group in klass.SignalGroups) {
Gtk.TreeIter iter = store.AppendNode ();
store.SetValue (iter, ColSignal, group.Label);
if (FillGroup (iter, group))
store.SetValue (iter, ColSignalTextWeight, (int) Pango.Weight.Bold);
else
store.SetValue (iter, ColSignalTextWeight, (int) Pango.Weight.Normal);
}
RestoreStatus (status);
}
bool FillGroup (Gtk.TreeIter parentIter, ItemGroup group)
{
bool hasSignals = false;
foreach (SignalDescriptor sd in group) {
bool foundSignal = false;
Gtk.TreeIter signalParent = parentIter;
foreach (Signal signal in selection.Signals) {
if (signal.SignalDescriptor != sd) continue;
Gtk.TreeIter iter = store.AppendNode (signalParent);
if (!foundSignal) {
signalParent = iter;
store.SetValue (iter, ColSignal, sd.Name);
store.SetValue (iter, ColSignalTextWeight, (int) Pango.Weight.Bold);
foundSignal = true;
}
SetSignalData (iter, signal);
}
Gtk.TreeIter signalIter = store.AppendNode (signalParent);
SetEmptySingalRow (signalIter, sd, !foundSignal);
hasSignals = hasSignals || foundSignal;
}
return hasSignals;
}
void SetSignalData (Gtk.TreeIter iter, Signal signal)
{
store.SetValue (iter, ColHandler, signal.Handler);
store.SetValue (iter, ColAfter, false);
store.SetValue (iter, ColHasHandler, true);
store.SetValue (iter, ColIsSignal, true);
store.SetValue (iter, ColDescriptorObject, signal.SignalDescriptor);
store.SetValue (iter, ColSignalObject, signal);
}
void SetEmptySingalRow (Gtk.TreeIter signalIter, SignalDescriptor sd, bool showName)
{
if (showName)
store.SetValue (signalIter, ColSignal, sd.Name);
store.SetValue (signalIter, ColHandler, "<i><span foreground=\"grey\">" + EmptyHandlerText + "</span></i>");
store.SetValue (signalIter, ColHasHandler, false);
store.SetValue (signalIter, ColIsSignal, true);
store.SetValue (signalIter, ColDescriptorObject, sd);
store.SetValue (signalIter, ColSignalTextWeight, (int) Pango.Weight.Normal);
}
void OnRowActivated (object sender, Gtk.RowActivatedArgs args)
{
Gtk.TreeIter iter;
if (!store.GetIter (out iter, args.Path))
return;
SignalDescriptor sd = GetSignalDescriptor (iter);
if (sd != null)
AddHandler (iter, "On" + sd.Name);
}
void OnHandlerEdited (object sender, Gtk.EditedArgs args)
{
if (args.NewText == EmptyHandlerText)
return;
Gtk.TreeIter iter;
if (!store.GetIterFromString (out iter, args.Path))
return;
AddHandler (iter, args.NewText);
}
void AddHandler (Gtk.TreeIter iter, string name)
{
internalChange = true;
Gtk.TreeIter piter = iter;
while (store.IterDepth (piter) != 0)
store.IterParent (out piter, piter);
Signal signal = GetSignal (iter);
if (signal == null) {
if (name != "") {
SignalDescriptor sd = (SignalDescriptor) store.GetValue (iter, ColDescriptorObject);
signal = new Signal (sd);
signal.Handler = name;
selection.Signals.Add (signal);
SetSignalData (iter, signal);
store.SetValue (iter, ColSignalTextWeight, (int) Pango.Weight.Bold);
if (store.IterDepth (iter) == 1)
SetEmptySingalRow (store.AppendNode (iter), signal.SignalDescriptor, false);
else {
store.IterParent (out iter, iter);
SetEmptySingalRow (store.AppendNode (iter), signal.SignalDescriptor, false);
}
}
} else {
if (name != "") {
signal.Handler = name;
store.SetValue (iter, ColHandler, signal.Handler);
} else {
selection.Signals.Remove (signal);
if (store.IterDepth (iter) == 1) {
if (store.IterNChildren (iter) == 1) {
SetEmptySingalRow (iter, signal.SignalDescriptor, true);
// Remove the empty row
store.IterChildren (out iter, iter);
store.Remove (ref iter);
} else {
Gtk.TreeIter citer;
store.IterChildren (out citer, iter);
Signal csignal = GetSignal (citer);
store.Remove (ref citer);
SetSignalData (iter, csignal);
if (store.IterNChildren (iter) == 1)
tree.CollapseRow (store.GetPath (iter));
}
} else
store.Remove (ref iter);
}
}
UpdateGroupStatus (piter);
internalChange = false;
}
void OnAfterToggled (object o, Gtk.ToggledArgs args)
{
Gtk.TreeIter it;
if (store.GetIterFromString (out it, args.Path)) {
Signal signal = GetSignal (it);
if (signal != null) {
internalChange = true;
signal.After = !signal.After;
internalChange = false;
store.SetValue (it, ColAfter, signal.After);
}
}
}
void UpdateGroupStatus (Gtk.TreeIter iter)
{
Gtk.TreeIter signalIter;
if (store.IterChildren (out signalIter, iter)) {
do {
if (store.IterNChildren (signalIter) > 0) {
store.SetValue (iter, ColSignalTextWeight, (int) Pango.Weight.Bold);
return;
}
} while (store.IterNext (ref signalIter));
}
store.SetValue (iter, ColSignalTextWeight, (int) Pango.Weight.Normal);
}
Signal GetSignal (Gtk.TreeIter iter)
{
if (! (bool) store.GetValue (iter, ColHasHandler))
return null;
return (Signal) store.GetValue (iter, ColSignalObject);
}
SignalDescriptor GetSignalDescriptor (Gtk.TreeIter iter)
{
if (! (bool) store.GetValue (iter, ColIsSignal))
return null;
return (SignalDescriptor) store.GetValue (iter, ColDescriptorObject);
}
ArrayList SaveStatus ()
{
ArrayList list = new ArrayList ();
Gtk.TreeIter it;
if (!store.GetIterFirst (out it))
return list;
do {
SaveStatus (list, "", it);
} while (store.IterNext (ref it));
return list;
}
void SaveStatus (ArrayList list, string path, Gtk.TreeIter iter)
{
string basePath = path + "/" + store.GetValue (iter, ColSignal);
if (tree.GetRowExpanded (store.GetPath (iter)))
list.Add (basePath);
if (store.IterChildren (out iter, iter)) {
do {
SaveStatus (list, basePath, iter);
} while (store.IterNext (ref iter));
}
}
void RestoreStatus (ArrayList list)
{
foreach (string namePath in list) {
string[] names = namePath.Split ('/');
Gtk.TreeIter iter = Gtk.TreeIter.Zero;
bool found = true;
foreach (string name in names) {
if (name == "") continue;
if (!FindChildByName (name, ref iter)) {
found = false;
break;
}
}
if (found)
tree.ExpandRow (store.GetPath (iter), false);
}
}
bool FindChildByName (string name, ref Gtk.TreeIter iter)
{
if (iter.Equals (Gtk.TreeIter.Zero)) {
if (!store.GetIterFirst (out iter))
return false;
} else if (!store.IterChildren (out iter, iter))
return false;
do {
if (name == (string) store.GetValue (iter, ColSignal))
return true;
}
while (store.IterNext (ref iter));
return false;
}
string EmptyHandlerText {
get { return "Click here to add a new handler"; }
}
}
}

Просмотреть файл

@ -12,6 +12,7 @@ namespace Stetic {
static Stetic.Project Project;
static Stetic.ProjectView ProjectView;
static Stetic.PropertyGrid Properties;
static Stetic.SignalsEditor Signals;
public static Stetic.UIManager UIManager;
public static Gtk.Window MainWindow;
@ -20,10 +21,13 @@ namespace Stetic {
Program = new Gnome.Program ("Stetic", "0.0", Gnome.Modules.UI, args);
Project = new Project ();
Project.WidgetAdded += OnWidgetAdded;
Project.Selected += OnSelectionChanged;
Palette = new Stetic.Palette (Project);
ProjectView = new Stetic.ProjectView (Project);
Properties = new Stetic.PropertyGrid (Project);
Signals = new Stetic.SignalsEditor (Project);
UIManager = new Stetic.UIManager (Project);
Glade.XML.CustomHandler = CustomWidgetHandler;
@ -68,6 +72,8 @@ namespace Stetic {
return ProjectView;
else if (name == "PropertyGrid")
return Properties;
else if (name == "SignalsEditor")
return Signals;
else if (name == "MenuBar")
return UIManager.MenuBar;
else
@ -85,5 +91,18 @@ namespace Stetic {
Program.Quit ();
args.RetVal = true;
}
static void OnWidgetAdded (object s, Wrapper.WidgetEventArgs args)
{
if (args.Widget is Wrapper.Window) {
((Gtk.Window)args.Widget.Wrapped).Present ();
}
}
static void OnSelectionChanged (Gtk.Widget selection, ProjectNode node)
{
if (selection is Gtk.Window)
((Gtk.Window)selection).Present ();
}
}
}

Просмотреть файл

@ -45,12 +45,10 @@ namespace Stetic {
protected override bool OnButtonPressEvent (Gdk.EventButton evt)
{
Gtk.Window win = klass.NewInstance (project) as Gtk.Window;
win.Present ();
project.AddWindow (win, true);
return true;
}
protected override bool OnMotionNotifyEvent (Gdk.EventMotion evt)
{
return true;

Просмотреть файл

@ -121,34 +121,109 @@
</child>
<child>
<widget class="GtkScrolledWindow" id="scrolledwindow6">
<widget class="GtkNotebook" id="notebook1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<property name="show_tabs">True</property>
<property name="show_border">True</property>
<property name="tab_pos">GTK_POS_TOP</property>
<property name="scrollable">False</property>
<property name="enable_popup">False</property>
<child>
<widget class="GtkViewport" id="viewport3">
<widget class="GtkScrolledWindow" id="scrolledwindow6">
<property name="visible">True</property>
<property name="events">GDK_BUTTON_PRESS_MASK</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
<child>
<widget class="Custom" id="PropertyGrid">
<widget class="GtkViewport" id="viewport3">
<property name="visible">True</property>
<property name="events">GDK_BUTTON_PRESS_MASK</property>
<property name="int1">0</property>
<property name="int2">0</property>
<property name="last_modification_time">Wed, 01 Jun 2005 15:17:33 GMT</property>
<property name="shadow_type">GTK_SHADOW_NONE</property>
<child>
<widget class="Custom" id="PropertyGrid">
<property name="visible">True</property>
<property name="events">GDK_BUTTON_PRESS_MASK</property>
<property name="int1">0</property>
<property name="int2">0</property>
<property name="last_modification_time">Wed, 01 Jun 2005 15:17:33 GMT</property>
</widget>
</child>
</widget>
</child>
</widget>
<packing>
<property name="tab_expand">False</property>
<property name="tab_fill">True</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">Properties</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="type">tab</property>
</packing>
</child>
<child>
<widget class="Custom" id="SignalsEditor">
<property name="visible">True</property>
<property name="int1">0</property>
<property name="int2">0</property>
<property name="last_modification_time">Sun, 29 Jan 2006 20:20:46 GMT</property>
</widget>
<packing>
<property name="tab_expand">False</property>
<property name="tab_fill">True</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label" translatable="yes">Signals</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
<property name="width_chars">-1</property>
<property name="single_line_mode">False</property>
<property name="angle">0</property>
</widget>
<packing>
<property name="type">tab</property>
</packing>
</child>
</widget>
<packing>
<property name="shrink">False</property>
<property name="shrink">True</property>
<property name="resize">True</property>
</packing>
</child>