3
using System.Collections;
5
namespace Stetic.Editor {
7
public class Flags: PropertyEditorCell
9
protected override string GetValueText ()
14
uint value = (uint)(int)Value;
15
EnumDescriptor enm = Registry.LookupEnum (Property.PropertyType.FullName);
17
foreach (Enum val in enm.Values) {
18
EnumValue eval = enm[val];
22
if ((value & (uint)(int)eval.Value) != 0) {
23
if (txt.Length > 0) txt += ", ";
30
protected override IPropertyEditor CreateEditor (Gdk.Rectangle cell_area, Gtk.StateType state)
32
return new FlagsEditor ();
36
public class FlagsEditor : Gtk.HBox, IPropertyEditor {
48
public void Initialize (PropertyDescriptor prop)
50
if (!prop.PropertyType.IsEnum)
51
throw new ApplicationException ("Flags editor does not support editing values of type " + prop.PropertyType);
53
property = prop.Label;
56
// For small enums, the editor is a list of checkboxes inside a frame
57
// For large enums (>5), use a selector dialog.
59
enm = Registry.LookupEnum (prop.PropertyType.FullName);
61
if (enm.Values.Length < 6)
63
Gtk.VBox vbox = new Gtk.VBox (true, 3);
65
tips = new Gtk.Tooltips ();
66
flags = new Hashtable ();
68
foreach (Enum value in enm.Values) {
69
EnumValue eval = enm[value];
73
Gtk.CheckButton check = new Gtk.CheckButton (eval.Label);
74
tips.SetTip (check, eval.Description, eval.Description);
75
uint uintVal = (uint)(int)eval.Value;
76
flags[check] = uintVal;
77
flags[uintVal] = check;
79
check.Toggled += FlagToggled;
80
vbox.PackStart (check, false, false, 0);
83
Gtk.Frame frame = new Gtk.Frame ();
86
PackStart (frame, true, true, 0);
90
flagsLabel = new Gtk.Entry ();
91
flagsLabel.IsEditable = false;
92
flagsLabel.HasFrame = false;
93
flagsLabel.ShowAll ();
94
PackStart (flagsLabel, true, true, 0);
96
Gtk.Button but = new Gtk.Button ("...");
97
but.Clicked += OnSelectFlags;
99
PackStart (but, false, false, 0);
103
public void AttachObject (object ob)
107
public override void Dispose ()
113
public object Value {
115
return Enum.ToObject (enm.EnumType, UIntValue);
118
uint newVal = (uint)(int)value;
119
if (flagsLabel != null) {
121
foreach (Enum val in enm.Values) {
122
EnumValue eval = enm[val];
123
if (eval.Label == "")
126
if ((newVal & (uint)(int) eval.Value) != 0) {
127
if (txt.Length > 0) txt += ", ";
131
flagsLabel.Text = txt;
135
for (uint i = 1; i <= uintValue || i <= newVal; i = i << 1) {
136
if ((uintValue & i) != (newVal & i)) {
137
Gtk.CheckButton check = (Gtk.CheckButton)flags[i];
139
check.Active = !check.Active;
146
public event EventHandler ValueChanged;
154
if (uintValue != value) {
156
if (ValueChanged != null)
157
ValueChanged (this, EventArgs.Empty);
162
void FlagToggled (object o, EventArgs args)
164
Gtk.CheckButton check = (Gtk.CheckButton)o;
165
uint val = (uint)flags[o];
173
void OnSelectFlags (object o, EventArgs args)
175
using (FlagsSelectorDialog dialog = new FlagsSelectorDialog (null, enm, UIntValue, property)) {
176
if (dialog.Run () == (int) ResponseType.Ok) {
177
Value = Enum.ToObject (enm.EnumType, dialog.Value);