Browse Source

new files for 379 and 914

JimMarlowe 9 years ago
parent
commit
c3e14db66f

BIN
Resources/EditorData/AtomicEditor/editor/skin/HSV21.png


BIN
Resources/EditorData/AtomicEditor/editor/skin/checkerboard.png


BIN
Resources/EditorData/AtomicEditor/editor/skin_light/HSV21.png


BIN
Resources/EditorData/AtomicEditor/editor/skin_light/checkerboard.png


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

@@ -0,0 +1,38 @@
+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
+				lp: width: 128, height: 64, max-width: 150, max-height: 80
+		TBColorWidget: id: colornew, 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
+			TBTextField: text: " R ", id: redlabel
+			TBInlineSelect: id: redselect, min: 0, max: 255, connection: rconn
+			TBSlider: id: redslider, min: 0, max: 255, connection: rconn
+		TBLayout: axis: x, distribution: gravity
+			TBTextField: text: " G ", id: greenlabel
+			TBInlineSelect: id: greenselect, min: 0, max: 255, connection: gconn
+			TBSlider: id: greenslider, min: 0, max: 255, connection: gconn
+		TBLayout: axis: x, distribution: gravity
+			TBTextField: text: " B ", id: bluelabel
+			TBInlineSelect: id: blueselect, min: 0, max: 255, connection: bconn
+			TBSlider: id: blueslider, min: 0, max: 255, connection: bconn
+		TBSeparator: gravity: left right
+		TBLayout: axis: x, distribution: gravity
+			TBTextField: text: " A ", id: alphalabel
+			TBInlineSelect: id: alphaselect, min: 0, max: 255, connection: aconn
+			TBSlider: id: alphaslider, min: 0, max: 255, value: 255, connection: aconn
+		TBSeparator: gravity: left right
+		TBLayout: axis: y, gravity: left right
+			TBEditField: id: infotext, text: "#000000", readonly: 1
+				font: size: 16
+				lp: min-width: 180
+	TBSeparator: gravity: left right, skin: AESeparator
+	TBLayout:
+		TBButton: text: Cancel, id: ccancelbutton
+		TBButton: text: OK, id: cokbutton

+ 285 - 0
Script/AtomicEditor/ui/frames/inspector/ColorChooser.ts

@@ -0,0 +1,285 @@
+//
+// Copyright (c) 2016 THUNDERBEAST GAMES LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+// http://axonflux.com/handy-rgb-to-hsl-and-rgb-to-hsv-color-model-c
+
+import EditorUI = require("ui/EditorUI");
+
+class ColorChooser extends Atomic.UIWindow {
+
+    rgbhsla : number[] = [ 0, 0, 0, 0, 0, 0, 255 ]; // 0=R, 1=G , 2=B, 3=H, 4=S, 5=L, 6=Alpha
+    r_ils : Atomic.UIInlineSelect;
+    g_ils : Atomic.UIInlineSelect;
+    b_ils : Atomic.UIInlineSelect;
+    a_ils : Atomic.UIInlineSelect;
+    r_sld : Atomic.UISlider;
+    g_sld : Atomic.UISlider;
+    b_sld : Atomic.UISlider;
+    a_sld : Atomic.UISlider;
+    oldcolor : Atomic.UIColorWidget;
+    newcolor : Atomic.UIColorWidget;
+    wheel : Atomic.UIColorWheel;
+    lslide : Atomic.UISlider;
+    infotext : Atomic.UIEditField;
+    parent_rils : Atomic.UIInlineSelect;
+    parent_gils : Atomic.UIInlineSelect;
+    parent_bils : Atomic.UIInlineSelect;
+    parent_ails : Atomic.UIInlineSelect;
+
+    constructor( pred : Atomic.UIInlineSelect, pgreen : Atomic.UIInlineSelect,
+                pblue : Atomic.UIInlineSelect, palpha : Atomic.UIInlineSelect ) {
+
+        super();
+
+        var view = EditorUI.getView();
+        view.addChild(this);
+
+        this.parent_rils = pred;
+        this.parent_gils = pgreen;
+        this.parent_bils = pblue;
+        this.parent_ails = palpha;
+        this.text = "Color Chooser";
+
+        this.load("AtomicEditor/editor/ui/colorchooser.tb.txt");
+
+        this.r_ils = <Atomic.UIInlineSelect>this.getWidget("redselect");
+        this.g_ils = <Atomic.UIInlineSelect>this.getWidget("greenselect");
+        this.b_ils = <Atomic.UIInlineSelect>this.getWidget("blueselect");
+        this.a_ils = <Atomic.UIInlineSelect>this.getWidget("alphaselect");
+        this.r_sld = <Atomic.UISlider>this.getWidget("redslider");
+        this.g_sld = <Atomic.UISlider>this.getWidget("greenslider");
+        this.b_sld = <Atomic.UISlider>this.getWidget("blueslider");
+        this.a_sld = <Atomic.UISlider>this.getWidget("alphaslider");
+        this.newcolor = <Atomic.UIColorWidget>this.getWidget("colornew" );
+        this.oldcolor = <Atomic.UIColorWidget>this.getWidget("colorold" );
+        this.infotext = <Atomic.UIEditField>this.getWidget("infotext" );
+        this.wheel = <Atomic.UIColorWheel>this.getWidget("colorwheel" );
+        this.lslide = <Atomic.UISlider>this.getWidget("lslider");
+
+        (<Atomic.UIButton>this.getWidget("ccancelbutton")).onClick = () => {
+            this.close();
+        };
+
+        (<Atomic.UIButton>this.getWidget("cokbutton")).onClick = () => {
+
+            this.parent_rils.setValue( this.rgbhsla[0] / 255 );
+            this.parent_gils.setValue( this.rgbhsla[1] / 255 );
+            this.parent_bils.setValue( this.rgbhsla[2] / 255 );
+            this.parent_ails.setValue( this.rgbhsla[6] / 255 );
+            this.close();
+        };
+
+        this.subscribeToEvent(this, "WidgetEvent", (data) => this.handleWidgetEvent(data));
+
+        this.resizeToFitContent();
+        this.center();
+        this.setFocus();
+
+        let rx = this.parent_rils.getValue() * 255;
+        if ( rx > 255 ) rx = 255;
+        let gx = this.parent_gils.getValue() * 255;
+        if ( gx > 255 ) gx = 255;
+        let bx = this.parent_bils.getValue() * 255;
+        if ( bx > 255 ) bx = 255;
+        let oldcolor = "#";
+        var rrr =  Math.round(rx).toString(16);
+        if (rrr.length < 2) oldcolor = oldcolor + "0";
+        oldcolor = oldcolor + rrr;
+        var ggg =  Math.round(gx).toString(16);
+        if (ggg.length < 2) oldcolor = oldcolor + "0";
+        oldcolor = oldcolor + ggg;
+        var bbb =  Math.round(bx).toString(16);
+        if (bbb.length < 2) oldcolor = oldcolor + "0";
+        oldcolor = oldcolor + bbb;
+        this.oldcolor.setColor( oldcolor );
+
+        Atomic.ui.blockChangedEvents = true;
+
+        this.oldcolor.setAlpha( this.parent_ails.getValue() * 255 );
+        this.a_sld.setValue(this.rgbhsla[6]);
+
+        Atomic.ui.blockChangedEvents = false;
+
+    }
+
+    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();
+        }
+
+    }
+
+    hue2rgb(p: number, q: number, t: number) { // part of rgb conversion
+        if (t < 0) t += 1;
+        if (t > 1) t -= 1;
+        if (t < 1 / 6) return p + (q - p) * 6 * t;
+        if (t < 1 / 2) return q;
+        if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
+        return p;
+    }
+
+    recalc_rgb() {
+        var rr, gg, bb;
+        let hh = this.rgbhsla[3];
+        let ss = this.rgbhsla[4];
+        let ll = this.rgbhsla[5];
+
+        if (ss == 0) {
+            rr = gg = bb = ll; // achromatic
+        } else {
+            var q = ll < 0.5 ? ll * (1 + ss) : ll + ss - ll * ss;
+            var p = 2 * ll - q;
+            rr = this.hue2rgb(p, q, hh + 1 / 3);
+            gg = this.hue2rgb(p, q, hh);
+            bb = this.hue2rgb(p, q, hh - 1 / 3);
+        }
+
+        this.rgbhsla[0] = rr * 255;
+        this.rgbhsla[1] = gg * 255;
+        this.rgbhsla[2] = bb * 255;
+    }
+
+    recalc_hsl() {
+        let rr = this.rgbhsla[0] / 255;
+        let gg = this.rgbhsla[1] / 255;
+        let bb = this.rgbhsla[2] / 255;
+
+        var max = Math.max(rr, gg, bb), min = Math.min(rr, gg, bb);
+        var hh, ss, ll = (max + min) / 2;
+
+        if (max == min) {
+            hh = ss = 0; // achromatic
+        } else {
+            var d = max - min;
+            ss = ll > 0.5 ? d / (2 - max - min) : d / (max + min);
+            switch (max) {
+                case rr: hh = (gg - bb) / d + (gg < bb ? 6 : 0); break;
+                case gg: hh = (bb - rr) / d + 2; break;
+                case bb: hh = (rr - gg) / d + 4; break;
+            }
+            hh /= 6;
+        }
+        this.rgbhsla[3] = hh;
+        this.rgbhsla[4] = ss;
+        this.rgbhsla[5] = ll;
+    }
+
+    update_rgbwidgets() {
+        Atomic.ui.blockChangedEvents = true;
+        this.r_ils.setValue(this.rgbhsla[0]);
+        this.g_ils.setValue(this.rgbhsla[1]);
+        this.b_ils.setValue(this.rgbhsla[2]);
+        this.r_sld.setValue(this.rgbhsla[0]);
+        this.g_sld.setValue(this.rgbhsla[1]);
+        this.b_sld.setValue(this.rgbhsla[2]);
+        Atomic.ui.blockChangedEvents = false;
+    }
+
+    update_hslwidgets() {
+        Atomic.ui.blockChangedEvents = true;
+        this.wheel.setHueSaturation (this.rgbhsla[3], this.rgbhsla[4]);
+        this.lslide.setValue(this.rgbhsla[5] * 128);
+        Atomic.ui.blockChangedEvents = false;
+   }
+
+    fixcolor() {
+        let mycolor = "#";  // create a new string
+
+        var rrr =  Math.round(this.rgbhsla[0]).toString(16);
+        if (rrr.length < 2) mycolor = mycolor + "0";
+        mycolor = mycolor + rrr;
+
+        var ggg =  Math.round(this.rgbhsla[1]).toString(16);
+        if (ggg.length < 2) mycolor = mycolor + "0";
+        mycolor = mycolor + ggg;
+
+        var bbb =  Math.round(this.rgbhsla[2]).toString(16);
+        if (bbb.length < 2) mycolor = mycolor + "0";
+        mycolor = mycolor + bbb;
+
+        this.newcolor.setColor( mycolor );
+        this.newcolor.setAlpha( this.rgbhsla[6] / 255 );
+        this.infotext.text = mycolor;
+    }
+
+}
+
+export = ColorChooser;

+ 81 - 0
Source/Atomic/UI/UIColorWheel.cpp

@@ -0,0 +1,81 @@
+//
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include <TurboBadger/tb_widgets.h>
+#include <TurboBadger/tb_atomic_widgets.h>
+
+#include <Atomic/IO/Log.h>
+#include <Atomic/Graphics/Texture.h>
+
+#include "UIEvents.h"
+#include "UI.h"
+#include "UIColorWheel.h"
+
+using namespace tb;
+
+namespace Atomic
+{
+
+UIColorWheel::UIColorWheel(Context* context, bool createWidget) : UIWidget(context, false)
+{
+    UI* ui = GetSubsystem<UI>();
+
+    if (createWidget)
+    {
+        widget_ = new TBColorWheel();
+        widget_->SetDelegate(this);
+        ui->WrapWidget(this, widget_);
+    }
+
+}
+
+UIColorWheel::~UIColorWheel()
+{
+}
+
+bool UIColorWheel::OnEvent(const tb::TBWidgetEvent &ev)
+{
+    return UIWidget::OnEvent(ev);
+}
+
+float UIColorWheel::GetHue()
+{
+    if (!widget_)
+        return 0.0;
+    return ((TBColorWheel*) widget_)->GetHue();
+}
+
+float UIColorWheel::GetSaturation()
+{
+    if (!widget_)
+        return 0.0;
+    return ((TBColorWheel*) widget_)->GetSaturation();
+}
+
+void UIColorWheel::SetHueSaturation ( float hue, float saturation )
+{
+     if (!widget_)
+        return;
+    ((TBColorWheel*) widget_)->SetHueSaturation ( hue, saturation );
+}
+
+}

+ 55 - 0
Source/Atomic/UI/UIColorWheel.h

@@ -0,0 +1,55 @@
+//
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+
+#include "UIWidget.h"
+
+
+namespace Atomic
+{
+
+
+class UIColorWheel : public UIWidget
+{
+    OBJECT(UIColorWheel)
+
+public:
+
+    UIColorWheel(Context* context, bool createWidget = true);
+    virtual ~UIColorWheel();
+
+    float GetHue();
+    float GetSaturation();
+    void SetHueSaturation ( float hue, float saturation );
+
+ 
+protected:
+
+    virtual bool OnEvent(const tb::TBWidgetEvent &ev);
+
+private:
+
+};
+
+}

+ 74 - 0
Source/Atomic/UI/UIColorWidget.cpp

@@ -0,0 +1,74 @@
+//
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include <TurboBadger/tb_widgets.h>
+#include <TurboBadger/tb_atomic_widgets.h>
+
+#include <Atomic/IO/Log.h>
+#include <Atomic/Graphics/Texture.h>
+
+#include "UIEvents.h"
+#include "UI.h"
+#include "UIColorWidget.h"
+
+using namespace tb;
+
+namespace Atomic
+{
+
+UIColorWidget::UIColorWidget(Context* context, bool createWidget) : UIWidget(context, false)
+{
+    UI* ui = GetSubsystem<UI>();
+
+    if (createWidget)
+    {
+        widget_ = new TBColorWidget();
+        widget_->SetDelegate(this);
+        ui->WrapWidget(this, widget_);
+    }
+
+}
+
+UIColorWidget::~UIColorWidget()
+{
+}
+
+bool UIColorWidget::OnEvent(const tb::TBWidgetEvent &ev)
+{
+    return UIWidget::OnEvent(ev);
+}
+
+void UIColorWidget::SetColor ( const String &name )
+{
+     if (!widget_)
+        return;
+    ((TBColorWidget*) widget_)->SetColor(name.CString());
+}
+
+void UIColorWidget::SetAlpha ( float value )
+{
+     if (!widget_)
+        return;
+    ((TBColorWidget*) widget_)->SetAlpha(value);
+}
+
+}

+ 54 - 0
Source/Atomic/UI/UIColorWidget.h

@@ -0,0 +1,54 @@
+//
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+
+#include "UIWidget.h"
+
+
+namespace Atomic
+{
+
+/// A widget that can render a Texture2D, so the image data
+/// doesn't need to be loaded 2x (once for Texture2D and once for say a UIImageWidget)
+class UIColorWidget : public UIWidget
+{
+    OBJECT(UIColorWidget)
+
+public:
+
+    UIColorWidget(Context* context, bool createWidget = true);
+    virtual ~UIColorWidget();
+
+    void SetColor ( const String &name );
+    void SetAlpha ( float value );
+
+protected:
+
+    virtual bool OnEvent(const tb::TBWidgetEvent &ev);
+
+private:
+
+};
+
+}

+ 74 - 0
Source/Atomic/UI/UISlider.cpp

@@ -0,0 +1,74 @@
+//
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include <TurboBadger/tb_widgets.h>
+#include <TurboBadger/tb_widgets_common.h>
+
+#include <Atomic/IO/Log.h>
+
+#include "UIEvents.h"
+#include "UI.h"
+#include "UILayout.h"
+#include "UISlider.h"
+
+using namespace tb;
+
+namespace Atomic
+{
+
+UISlider::UISlider(Context* context, bool createWidget) : UIWidget(context, false)
+{
+    if (createWidget)
+    {
+        widget_ = new TBSlider();
+        widget_->SetDelegate(this);
+        GetSubsystem<UI>()->WrapWidget(this, widget_);
+    }
+}
+
+UISlider::~UISlider()
+{
+
+}
+
+void UISlider::SetLimits(double minimum, double maximum)
+{
+    if (!widget_)
+        return;
+    ((TBSlider*) widget_)->SetLimits(minimum, maximum);
+
+}
+
+bool UISlider::OnEvent(const tb::TBWidgetEvent &ev)
+{
+    if (ev.type == EVENT_TYPE_CUSTOM && ev.ref_id == TBIDC("edit_complete"))
+    {
+        VariantMap eventData;
+        eventData[UIWidgetEditComplete::P_WIDGET] = this;
+        SendEvent(E_UIWIDGETEDITCOMPLETE, eventData);
+
+        return true;
+    }
+    return UIWidget::OnEvent(ev);
+}
+
+}

+ 50 - 0
Source/Atomic/UI/UISlider.h

@@ -0,0 +1,50 @@
+//
+// Copyright (c) 2014-2015, THUNDERBEAST GAMES LLC All rights reserved
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+#include "UIWidget.h"
+
+namespace Atomic
+{
+
+
+class UISlider : public UIWidget
+{
+    OBJECT(UISlider)
+
+public:
+
+    UISlider(Context* context, bool createWidget = true);
+    virtual ~UISlider();
+
+    void SetLimits(double minimum, double maximum);
+
+protected:
+
+    virtual bool OnEvent(const tb::TBWidgetEvent &ev);
+
+private:
+
+};
+
+}

+ 192 - 0
Source/ThirdParty/TurboBadger/tb_atomic_widgets.cpp

@@ -0,0 +1,192 @@
+// ================================================================================
+// ==      This file is a part of Turbo Badger. (C) 2011-2014, Emil Segerås      ==
+// ==                     See tb_core.h for more information.                    ==
+// ================================================================================
+//
+// Copyright (c) 2016, THUNDERBEAST GAMES LLC All rights reserved
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "tb_widgets_reader.h"
+#include "tb_widgets_common.h"
+#include "tb_node_tree.h"
+#include "tb_system.h"
+#include "tb_atomic_widgets.h"
+#include <math.h>
+
+namespace tb {
+
+// == TBColorWidget =======================================
+
+TBColorWidget::TBColorWidget() : color_(), alpha_ ( 1.0)
+{
+}
+
+void TBColorWidget::SetColor ( const char *name )
+{
+	if ( name )
+  	 color_.SetFromString(name, strlen(name));
+     
+    InvalidateSkinStates();
+    Invalidate();
+}
+
+void TBColorWidget::SetAlpha ( float value )
+{
+    if ( value < 0.0 || value > 1.0 ) 
+    {
+        alpha_ = 1.0;
+        return;
+    }
+    
+    alpha_ = value; 
+
+    InvalidateSkinStates();
+    Invalidate();
+}
+
+void TBColorWidget::OnPaint(const PaintProps &paint_props)
+{
+    TBRect local_rect = GetRect();
+    local_rect.x = 0;
+    local_rect.y = 0;
+    float old_opacity = g_renderer->GetOpacity();
+    g_renderer->SetOpacity(alpha_);
+    g_renderer->DrawRectFill(local_rect, color_);
+    g_renderer->SetOpacity(old_opacity);
+}
+
+void TBColorWidget::OnInflate(const INFLATE_INFO &info)
+{
+    if (const char *colr = info.node->GetValueString("color", nullptr))
+        SetColor(colr);
+    TBWidget::OnInflate(info);
+}
+
+TB_WIDGET_FACTORY(TBColorWidget, TBValue::TYPE_NULL, WIDGET_Z_TOP) {}
+
+
+// == TBColorWheel =======================================
+
+TBColorWheel::TBColorWheel() :
+    markerx_(128),
+    markery_(128),
+    markercolor_(),
+    hue_(0.0),
+    saturation_(0.0)
+{
+}
+
+void TBColorWheel::OnPaint(const PaintProps &paint_props)
+{
+    TBWidget::OnPaint(paint_props);  // draw the widget stuff
+
+    TBRect local_rect ( 0,0,4,4 ); // AND draw a marker where we clicked.
+    local_rect.x = markerx_ - 2;
+    local_rect.y = markery_ - 2;
+    g_renderer->DrawRect( local_rect, markercolor_);
+    local_rect.x -= 1;
+    local_rect.y -= 1;
+    local_rect.w += 2;
+    local_rect.h += 2;
+    g_renderer->DrawRect( local_rect, markercolor_);  // draw double box
+    
+}
+
+bool TBColorWheel::OnEvent(const TBWidgetEvent &ev)
+{
+    if (ev.target == this && ev.type == EVENT_TYPE_CLICK)
+    {
+         SetMarkerX ( ev.target_x );
+         SetMarkerY ( ev.target_y );
+         CalcHueSaturation( markerx_, markery_ );
+         TBWidgetEvent ev(EVENT_TYPE_CHANGED); 
+         InvokeEvent(ev);
+    }
+    return TBWidget::OnEvent(ev);
+}
+
+void TBColorWheel::SetHueSaturation ( float hue, float saturation )
+{
+
+    // suppose to set the marker position to match HS here
+
+    hue_ = hue * 360.0;
+    saturation_ = saturation * 128.0;
+    
+    Invalidate();
+}
+
+void TBColorWheel::CalcHueSaturation ( int rawx, int rawy )
+{
+    TBRect rect = GetRect(); 
+    int centerx = rect.w / 2;
+    int centery = rect.h / 2;
+
+    float X1 = rawx;
+    float Y1 = rawy;
+    float X2 = centerx;
+    float Y2 = centery; 
+    float angle = 0.0;
+    float xd = X2-X1;
+    float yd = Y2-Y1;
+    float dx = sqrt(xd * xd + yd * yd);
+
+    // angle in degrees
+    angle = atan2(Y2 - Y1, X2 - X1) * 180 / 3.14159265358979323846;
+    if (angle < 0) angle += 360.0;
+
+    // if the distance > 128, can we calculate the line point at 128 and set the marker there?
+
+    if( dx > 128.0 ) dx = 128.0;  // limit value
+    
+    saturation_ = dx;
+    hue_ = angle;
+}
+
+void TBColorWheel::SetMarkerX ( int value )
+{
+    markerx_ = value;
+}
+
+void TBColorWheel::SetMarkerY ( int value )
+{
+    markery_ = value;
+}
+
+void TBColorWheel::SetMarkerColor ( const char *name )
+{
+ 	if ( name )
+  	 markercolor_.SetFromString(name, strlen(name));
+     
+    Invalidate();
+}
+
+void TBColorWheel::OnInflate(const INFLATE_INFO &info)
+{
+    if (const char *colr = info.node->GetValueString("color", nullptr))
+        SetMarkerColor(colr);
+    TBWidget::OnInflate(info);
+}
+
+TB_WIDGET_FACTORY(TBColorWheel, TBValue::TYPE_FLOAT, WIDGET_Z_TOP) {}
+
+
+}; // namespace tb

+ 105 - 0
Source/ThirdParty/TurboBadger/tb_atomic_widgets.h

@@ -0,0 +1,105 @@
+// ================================================================================
+// ==      This file is a part of Turbo Badger. (C) 2011-2014, Emil Segerås      ==
+// ==                     See tb_core.h for more information.                    ==
+// ================================================================================
+//
+// Copyright (c) 2016, THUNDERBEAST GAMES LLC All rights reserved
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+#ifndef TB_ATOMIC_WIDGETS_H
+#define TB_ATOMIC_WIDGETS_H
+
+#include "tb_widgets.h"
+#include "tb_layout.h"
+#include "tb_msg.h"
+#include "tb_widgets_listener.h"
+#include "tb_widgets_common.h"
+
+namespace tb {
+
+// fruxo recommends : Subclass TBWidget and override OnPaint. From
+// there you can paint solid colors using g_tb_skin->PaintRectFill.
+class TBColorWidget : public TBWidget
+{
+public:
+    TBOBJECT_SUBCLASS(TBColorWidget, TBWidget);    // For safe typecasting
+
+    TBColorWidget();
+
+    virtual void SetColor ( const char * );
+    virtual void SetAlpha ( float );
+    virtual void OnInflate(const INFLATE_INFO &info);
+    virtual void OnPaint(const PaintProps &paint_props);
+
+private:
+
+	TBColor color_;
+    float alpha_;
+};
+
+class TBColorWheel : public TBWidget
+{
+public:
+    TBOBJECT_SUBCLASS(TBColorWheel, TBWidget);    // For safe typecasting
+
+    TBColorWheel();
+
+    virtual void OnInflate(const INFLATE_INFO &info);
+    virtual void OnPaint(const PaintProps &paint_props);
+    virtual bool OnEvent(const TBWidgetEvent &ev);
+
+    float GetHue() const { return hue_; }
+    float GetSaturation() const { return saturation_; }
+    void SetHueSaturation ( float hue, float saturation );
+    
+    void SetMarkerX ( int );
+    void SetMarkerY( int );
+    void SetMarkerColor ( const char * );
+    
+private:
+
+    void CalcHueSaturation ( int, int ); // maths.
+
+    int markerx_;
+    int markery_; // where we clicked, put a box there
+	TBColor markercolor_; // what color box, default = black
+    float hue_;   // varies with the angle
+    float saturation_; // varies with the radius.
+
+};
+
+class TBEventBlocker : public TBWidgetListener
+{
+
+public:
+
+    TBEventBlocker() : TBWidgetListener() { }
+    
+    /** Called when a event is about to be invoked on a widget. This make it possible
+        to intercept events before they are handled, and block it (by returning true --like here ).
+        Note, if returning true, other global listeners will still also be notified. */
+    virtual bool OnWidgetInvokeEvent(TBWidget *widget, const TBWidgetEvent &ev) { return true; } 
+    
+};
+
+
+}; // namespace tb
+
+#endif // TB_ATOMIC_WIDGETS_H