Jelajahi Sumber

Remove the inline selects from color attr editor and use UIColorWidget instead, add Color setter and getter for UIColorWidget (+2 squashed commit)

Squashed commit:

[60aeef6] Support preview of color choice across selected objects, handle closing the window and not hitting ok/cancel, flip ok/cancel to be consistent with other dialogs, swap new/old color widgets, a few cleanups

[61da139] Color Chooser updates
Josh Engebretson 9 tahun lalu
induk
melakukan
f3587e91e8

+ 4 - 4
Resources/EditorData/AtomicEditor/editor/ui/colorchooser.tb.txt

@@ -1,13 +1,13 @@
-TBLayout: axis: y, distribution: gravity, position: left	
+TBLayout: axis: y, distribution: gravity, position: left
 	lp: min-width: 300
 	TBLayout: axis: x, distribution: gravity
 		TBColorWheel: id: colorwheel, skin: HSVSkin
 				lp: width: 256, height: 256
 		TBSlider: id: lslider, axis: y, min: 0, max: 255, value: 128
 	TBLayout: axis: x, distribution: available, gravity: left right
-		TBColorWidget: id: colorold, color: blue, skin: Checkerboard
+		TBColorWidget: id: colornew, color: blue, skin: Checkerboard
 				lp: width: 128, height: 64, max-width: 150, max-height: 80
-		TBColorWidget: id: colornew, color: red, skin: Checkerboard
+		TBColorWidget: id: colorold, color: red, skin: Checkerboard
 				lp: width: 128, height: 64, max-width: 150, max-height: 80
 	TBLayout: axis: y, distribution: gravity
 		TBLayout: axis: x, distribution: gravity
@@ -35,5 +35,5 @@ TBLayout: axis: y, distribution: gravity, position: left
 				font: size: 16
 	TBSeparator: gravity: left right, skin: AESeparator
 	TBLayout:
-		TBButton: text: Cancel, id: ccancelbutton
 		TBButton: text: OK, id: cokbutton
+		TBButton: text: Cancel, id: ccancelbutton

+ 98 - 37
Script/AtomicEditor/ui/frames/inspector/AttributeInfoEdit.ts

@@ -622,68 +622,129 @@ class QuaternionAttributeEdit extends NumberArrayAttributeEdit {
 
 }
 
-class ColorAttributeEdit extends NumberArrayAttributeEdit {
+class ColorAttributeEdit extends AttributeInfoEdit {
 
-    constructor() {
 
-        super(4);
+    createLayout() {
 
-    }
+        var layout = new Atomic.UILayout();
+        var o = InspectorUtils.createAttrColorFieldWithSelectButton(this.attrInfo.name, layout);
 
-    createLayout() {
+        var colorWidget = this.colorWidget = o.colorWidget;
+        var selectButton = o.selectButton;
 
-        this.createEditWidget();
+        layout.layoutSize = Atomic.UI_LAYOUT_SIZE_AVAILABLE;
+        layout.gravity = Atomic.UI_GRAVITY_LEFT_RIGHT;
+        layout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_GRAVITY;
+
+
+        var lp = new Atomic.UILayoutParams();
+        lp.width = 140;
+        lp.height = 24;
+        colorWidget.layoutParams = lp;
+
+        this.editWidget = layout;
 
         this.editWidget.subscribeToEvent(this.editWidget, "WidgetEvent", (data) => this.handleWidgetEvent(data));
 
-        var attr = this.attrInfo;
-        var attrNameLP = AttributeInfoEdit.attrNameLP;
+        selectButton.onClick = () => {
 
-        this.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_GRAVITY;
+            // store original color
+            let color = [1, 1, 1, 1];
+            let object = this.editType.getFirstObject();
 
-        if ( attr.type == Atomic.VAR_COLOR) {
-            this.axis = Atomic.UI_AXIS_Y;
-            this.layoutPosition = Atomic.UI_LAYOUT_POSITION_LEFT_TOP;
-            this.skinBg = "InspectorVectorAttrLayout";
-        }
+            if (object) {
+                color = object.getAttribute(this.attrInfo.name);
+            }
 
-        if (!this.hideName) {
+            colorWidget.color = color;
 
-            var name = new Atomic.UITextField();
-            name.textAlign = Atomic.UI_TEXT_ALIGN_LEFT;
-            name.skinBg = "InspectorTextAttrName";
-            name.layoutParams = attrNameLP;
-            var bname = attr.name;
+            let restore = null;
+            let chooser = new ColorChooser ( color );
 
-            if (bname == "Is Enabled")
-                bname = "Enabled";
+            this.subscribeToEvent(chooser, "ColorChooserChanged", (ev) => {
 
-            if (this.nameOverride)
-                name.text = this.nameOverride;
-            else
-                name.text = bname;
+                restore = color;
+                this.updateColor(chooser.getRGBA());
 
-            name.fontDescription = AttributeInfoEdit.fontDesc;
+            });
 
-            this.addChild(name);
+            this.subscribeToEvent(chooser, "UIWidgetEditCanceled", (ev) => {
+
+                if (restore) {
+
+                    colorWidget.color = restore;
+                    this.updateColor(restore);
+
+                }
+
+            });
+
+            this.subscribeToEvent(chooser, "UIWidgetEditComplete", (ev) => {
+
+                let newColor = chooser.getRGBA();
+
+                // check for new color edit
+                let committed = false;
+                for (let i = 0; i < 4; i++) {
+
+                    if (color[i] != newColor[i]) {
+
+                        this.editType.onAttributeInfoEdited(this.attrInfo, newColor);
+                        this.refresh();
+                        committed = true;
+                        break;
+
+                    }
+                }
+
+                if (restore && !committed) {
+
+                    for (let i = 0; i < 4; i++) {
+
+                        if (color[i] != restore[i]) {
+
+                            this.updateColor(color);
+                            break;
 
-            var selectButton = new Atomic.UIButton();
-            selectButton.text = "...";
-            selectButton.fontDescription = AttributeInfoEdit.fontDesc;
-            this.addChild(selectButton);
+                        }
 
-            selectButton.onClick = () => {
+                    }
 
-                    new ColorChooser ( this.selects[0], this.selects[1],
-                        this.selects[2], this.selects[3] );
+                }
 
-            };
+            });
 
-         };
+        };
 
         this.addChild(this.editWidget);
+
+    }
+
+    refresh() {
+
+        let object = this.editType.getFirstObject();
+
+        if (object) {
+            this.colorWidget.color = object.getAttribute(this.attrInfo.name);
+        }
+    }
+
+    // updates color on selection without committing to undo/redo for preview
+    updateColor(rgba:number[]) {
+
+        this.colorWidget.color = rgba;
+
+        for (var i in this.editType.objects) {
+
+            let object = this.editType.objects[i];
+            object.setAttribute(this.attrInfo.name, rgba );
+
+        }
+
     }
 
+    colorWidget : Atomic.UIColorWidget;
 
 }
 

+ 82 - 90
Script/AtomicEditor/ui/frames/inspector/ColorChooser.ts

@@ -41,8 +41,7 @@ class ColorChooser extends Atomic.UIWindow {
     infohex : Atomic.UIEditField;
     infohsl : Atomic.UIEditField;
 
-    constructor( pred : Atomic.UIInlineSelect, pgreen : Atomic.UIInlineSelect,
-                pblue : Atomic.UIInlineSelect, palpha : Atomic.UIInlineSelect ) {
+    constructor( startRGBA:number[] ) {
 
         super();
 
@@ -50,7 +49,6 @@ class ColorChooser extends Atomic.UIWindow {
         view.addChild(this);
 
         this.text = "Color Chooser";
-
         this.load("AtomicEditor/editor/ui/colorchooser.tb.txt");
 
         this.r_ils = <Atomic.UIInlineSelect>this.getWidget("redselect");
@@ -69,43 +67,37 @@ class ColorChooser extends Atomic.UIWindow {
         this.lslide = <Atomic.UISlider>this.getWidget("lslider");
 
         (<Atomic.UIButton>this.getWidget("ccancelbutton")).onClick = () => {
+
+            this.sendEvent("UIWidgetEditCanceled", { widget : this });
+            this.unsubscribeFromEvent("WidgetDeleted");
             this.close();
+
         };
 
         (<Atomic.UIButton>this.getWidget("cokbutton")).onClick = () => {
 
-            var rr = this.rgbhsla[0] / 255;
-            var gg = this.rgbhsla[1] / 255;
-            var bb = this.rgbhsla[2] / 255;
-            var aa = this.rgbhsla[6] / 255;
-            var wr = pred;
-			var wg = pgreen;
-			var wb = pblue;
-			var wa = palpha;
-			wr.setValue ( rr );
- 			wr.sendEvent( "UIWidgetEditComplete", { widget: wr } );
-			wg.setValue ( gg );
- 			wg.sendEvent( "UIWidgetEditComplete", { widget: wg } );
-			wb.setValue ( bb );
- 			wb.sendEvent( "UIWidgetEditComplete", { widget: wb } );
-			wa.setValue ( aa );
- 			wa.sendEvent( "UIWidgetEditComplete", { widget: wa } );
-
+            this.sendEvent("UIWidgetEditComplete", { widget : this });
+            this.unsubscribeFromEvent("WidgetDeleted");
             this.close();
         };
 
+        this.subscribeToEvent(this, "WidgetDeleted", (event: Atomic.UIWidgetDeletedEvent) => {
+
+            this.sendEvent("UIWidgetEditCanceled", { widget : this });
+
+        });
+
         this.subscribeToEvent(this, "WidgetEvent", (data) => this.handleWidgetEvent(data));
 
         this.resizeToFitContent();
         this.center();
         this.setFocus();
 
-        let rx = pred.getValue() * 255;
-        if ( rx > 255 ) rx = 255;
-        let gx = pgreen.getValue() * 255;
-        if ( gx > 255 ) gx = 255;
-        let bx = pblue.getValue() * 255;
-        if ( bx > 255 ) bx = 255;
+        let rx = Math.min(startRGBA[0] * 255, 255);
+        let gx = Math.min(startRGBA[1] * 255, 255);
+        let bx = Math.min(startRGBA[2] * 255, 255);
+        let ax = Math.min(startRGBA[3] * 255, 255);
+
         let oldcolor = "#";
         var rrr =  Math.round(rx).toString(16);
         if (rrr.length < 2) oldcolor = oldcolor + "0";
@@ -116,11 +108,20 @@ class ColorChooser extends Atomic.UIWindow {
         var bbb =  Math.round(bx).toString(16);
         if (bbb.length < 2) oldcolor = oldcolor + "0";
         oldcolor = oldcolor + bbb;
-        this.oldcolor.setColor( oldcolor );
+        this.oldcolor.setColorString( oldcolor );
+
+        // start with current color instead of black
+        this.rgbhsla[0] = rx;
+        this.rgbhsla[1] = gx;
+        this.rgbhsla[2] = bx;
+        this.recalc_hsl();
+        this.fixcolor();
+        this.update_rgbwidgets();
+        this.update_hslwidgets();
 
         Atomic.ui.blockChangedEvents = true;
 
-        this.oldcolor.setAlpha( palpha.getValue() * 255 );
+        this.oldcolor.setAlpha( startRGBA[3] * 255 );
         this.a_sld.setValue(this.rgbhsla[6]);
 
         Atomic.ui.blockChangedEvents = false;
@@ -129,71 +130,62 @@ class ColorChooser extends Atomic.UIWindow {
 
     handleWidgetEvent(ev: Atomic.UIWidgetEvent) {
 
-        if (ev.target.id == "colorwheel" && ev.type == Atomic.UI_EVENT_TYPE_CHANGED ) {
-            var myhue = this.wheel.getHue();
-            var mysat = this.wheel.getSaturation();
-            var mylit = this.lslide.getValue();
-            this.rgbhsla[3] = myhue / 360;
-            this.rgbhsla[4] = mysat / 128;
-            this.rgbhsla[5] = mylit / 255;
-            this.recalc_rgb();
-            this.fixcolor();
-            this.update_rgbwidgets();
-        }
-        if (ev.target.id == "lslider" && ev.type == Atomic.UI_EVENT_TYPE_CHANGED ) {
-            var myhue = this.wheel.getHue();
-            var mysat = this.wheel.getSaturation();
-            var mylit = ev.target.getValue();
-            this.rgbhsla[3] = myhue / 360;
-            this.rgbhsla[4] = mysat / 128;
-            this.rgbhsla[5] = mylit / 255;
-            this.recalc_rgb();
-            this.fixcolor();
-            this.update_rgbwidgets();
-        }
-        if ( ev.target.id == "redselect" && ev.type == Atomic.UI_EVENT_TYPE_CHANGED ) {
-            this.rgbhsla[0] = ev.target.getValue();
-            this.recalc_hsl();
-            this.fixcolor();
-            this.update_hslwidgets();
-        }
-        if ( ev.target.id == "redslider" && ev.type == Atomic.UI_EVENT_TYPE_CHANGED ) {
-            this.rgbhsla[0] = ev.target.getValue();
-            this.recalc_hsl();
-            this.fixcolor();
-            this.update_hslwidgets();
-        }
-        if ( ev.target.id == "greenselect" && ev.type == Atomic.UI_EVENT_TYPE_CHANGED ) {
-            this.rgbhsla[1] = ev.target.getValue();
-            this.recalc_hsl();
-            this.fixcolor();
-            this.update_hslwidgets();
-        }
-        if ( ev.target.id == "greenslider"  && ev.type == Atomic.UI_EVENT_TYPE_CHANGED ) {
-            this.rgbhsla[1] = ev.target.getValue();
-            this.recalc_hsl();
-            this.fixcolor();
-            this.update_hslwidgets();
-        }
-        if ( ev.target.id == "blueselect" && ev.type == Atomic.UI_EVENT_TYPE_CHANGED ) {
-            this.rgbhsla[2] = ev.target.getValue();
-            this.recalc_hsl();
-            this.fixcolor();
-            this.update_hslwidgets();
-        }
-        if ( ev.target.id == "blueslider" && ev.type == Atomic.UI_EVENT_TYPE_CHANGED ) {
-            this.rgbhsla[2] = ev.target.getValue();
-            this.recalc_hsl();
-            this.fixcolor();
-            this.update_hslwidgets();
-        }
-        if ( ev.target.id == "alphaslider" && ev.type == Atomic.UI_EVENT_TYPE_CHANGED ) {
-            this.rgbhsla[6] = ev.target.getValue();
-            this.fixcolor();
+        if (ev.type == Atomic.UI_EVENT_TYPE_CHANGED) {
+
+            let changed = false;
+            let hsltargets = ["colorwheel", "lslider"];
+            let rgbtargets = {
+                "redselect" : 0,
+                "redslider" : 0,
+                "greenselect" : 1,
+                "greenslider" : 1,
+                "blueselect" : 2,
+                "blueslider" : 2,
+                "alphaslider" : 3
+            }
+
+            if (hsltargets.indexOf(ev.target.id) > -1) {
+
+                changed = true;
+                this.rgbhsla[3] = this.wheel.getHue() / 360;
+                this.rgbhsla[4] = this.wheel.getSaturation() / 128;
+                this.rgbhsla[5] = this.lslide.getValue() / 255;
+                this.recalc_rgb();
+                this.fixcolor();
+                this.update_rgbwidgets();
+
+            } else if (ev.target.id in rgbtargets) {
+
+                changed = true;
+                this.rgbhsla[rgbtargets[ev.target.id]] = ev.target.getValue();
+                this.recalc_hsl();
+                this.fixcolor();
+                this.update_hslwidgets();
+
+            }
+
+            if (changed) {
+
+                this.sendEvent("ColorChooserChanged", { widget : this });
+
+            }
+
         }
 
     }
 
+    // return current color choice as a RGBA array
+    getRGBA() : number[] {
+
+        var rr = this.rgbhsla[0] / 255;
+        var gg = this.rgbhsla[1] / 255;
+        var bb = this.rgbhsla[2] / 255;
+        var aa = this.rgbhsla[6] / 255;
+
+        return [rr, gg, bb, aa];
+
+    }
+
     hue2rgb(p: number, q: number, t: number) { // part of rgb conversion
         if (t < 0) t += 1;
         if (t > 1) t -= 1;
@@ -282,7 +274,7 @@ class ColorChooser extends Atomic.UIWindow {
         if (bbb.length < 2) mycolor = mycolor + "0";
         mycolor = mycolor + bbb;
 
-        this.newcolor.setColor( mycolor );
+        this.newcolor.setColorString( mycolor );
         this.newcolor.setAlpha( this.rgbhsla[6] / 255 );
         this.infohex.text = mycolor;
 

+ 43 - 0
Script/AtomicEditor/ui/frames/inspector/InspectorUtils.ts

@@ -84,6 +84,21 @@ class InspectorUtils {
 
   }
 
+  static createColorWidget():Atomic.UIColorWidget {
+
+    var colorWidget = new Atomic.UIColorWidget();
+    colorWidget.id = "colorfield";
+
+    var lp = new Atomic.UILayoutParams();
+    lp.width = 160;
+    lp.height = 24;
+    colorWidget.layoutParams = lp;
+
+    return colorWidget;
+
+  }
+
+
   static createAttrEditField(name:string, parent:Atomic.UIWidget):Atomic.UIEditField {
 
     var attrLayout = new Atomic.UILayout();
@@ -154,6 +169,34 @@ class InspectorUtils {
 
   }
 
+  static createAttrColorFieldWithSelectButton(name:string, parent:Atomic.UIWidget):{colorWidget:Atomic.UIColorWidget, selectButton:Atomic.UIButton} {
+
+    var attrLayout = new Atomic.UILayout();
+    attrLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_POSITION_LEFT_TOP;
+
+    if (name) {
+      var _name = InspectorUtils.createAttrName(name);
+      attrLayout.addChild(_name);
+    }
+
+    var fieldLayout = new Atomic.UILayout();
+    fieldLayout.layoutDistribution = Atomic.UI_LAYOUT_DISTRIBUTION_POSITION_LEFT_TOP;
+
+    var colorWidget = InspectorUtils.createColorWidget();
+
+    var selectButton = new Atomic.UIButton();
+    selectButton.text = "...";
+    selectButton.fontDescription = InspectorUtils.attrFontDesc;
+
+    fieldLayout.addChild(colorWidget);
+    fieldLayout.addChild(selectButton);
+
+    attrLayout.addChild(fieldLayout);
+    parent.addChild(attrLayout);
+
+    return {colorWidget:colorWidget, selectButton:selectButton};
+
+  }
 
   // "static constructor"
   static attrFontDesc:Atomic.UIFontDescription;

+ 21 - 1
Source/Atomic/UI/UIColorWidget.cpp

@@ -57,13 +57,33 @@ bool UIColorWidget::OnEvent(const tb::TBWidgetEvent &ev)
     return UIWidget::OnEvent(ev);
 }
 
-void UIColorWidget::SetColor ( const String &name )
+void UIColorWidget::SetColorString( const String &name )
 {
      if (!widget_)
         return;
     ((TBColorWidget*) widget_)->SetColor(name.CString());
 }
 
+void UIColorWidget::SetColor(const Color& color)
+{
+    if (!widget_)
+        return;
+
+    ((TBColorWidget*)widget_)->SetColor(color.r_ * 255.0f, color.g_ * 255.0f, color.b_ * 255.0f, color.a_ * 255.0f);
+}
+
+Color UIColorWidget::GetColor() const
+{
+    if (!widget_)
+        return Color::BLACK;
+
+    const TBColor& color = ((TBColorWidget*)widget_)->GetColor();
+    float alpha = ((TBColorWidget*)widget_)->GetAlpha();
+
+    return Color(color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, alpha / 255.0f);
+
+}
+
 void UIColorWidget::SetAlpha ( float value )
 {
      if (!widget_)

+ 8 - 1
Source/Atomic/UI/UIColorWidget.h

@@ -40,7 +40,14 @@ public:
     UIColorWidget(Context* context, bool createWidget = true);
     virtual ~UIColorWidget();
 
-    void SetColor ( const String &name );
+    /// Set color from a Color value
+    void SetColor(const Color& color);
+
+    /// Set color from hex string
+    void SetColorString(const String &name);
+
+    Color GetColor() const;
+
     void SetAlpha ( float value );
 
 protected:

+ 9 - 1
Source/ThirdParty/TurboBadger/tb_atomic_widgets.cpp

@@ -35,7 +35,7 @@ namespace tb {
 
 // == TBColorWidget =======================================
 
-TBColorWidget::TBColorWidget() : color_(), alpha_ ( 1.0)
+TBColorWidget::TBColorWidget() : color_(), alpha_ ( 1.0f)
 {
 }
 
@@ -48,6 +48,14 @@ void TBColorWidget::SetColor ( const char *name )
     Invalidate();
 }
 
+void TBColorWidget::SetColor(float r, float g, float b, float a)
+{
+    color_.Set(TBColor(r, g, b, a));
+
+    InvalidateSkinStates();
+    Invalidate();
+}
+
 void TBColorWidget::SetAlpha ( float value )
 {
     if ( value < 0.0 || value > 1.0 ) 

+ 8 - 2
Source/ThirdParty/TurboBadger/tb_atomic_widgets.h

@@ -43,8 +43,14 @@ public:
 
     TBColorWidget();
 
-    virtual void SetColor ( const char * );
-    virtual void SetAlpha ( float );
+    void SetColor ( const char * );
+    void SetColor (float r, float g, float b, float a);
+
+    void SetAlpha ( float );
+
+    const TBColor& GetColor() const { return color_; }
+    float GetAlpha() const { return alpha_; }
+
     virtual void OnInflate(const INFLATE_INFO &info);
     virtual void OnPaint(const PaintProps &paint_props);