From 46192c370926c05e6ca6788b5291adfcd5f4db66 Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Thu, 23 Jan 2025 10:18:18 +0000 Subject: [PATCH 1/9] Eye dropper functionality Adds eye dropper functionality adds eye dropper button image supplied by jeff adds a few missing asset files (due to in asset browser scan and add all loose files) --- Engine/source/gui/controls/guiColorPicker.cpp | 198 ++++++++++++------ Engine/source/gui/controls/guiColorPicker.h | 23 +- .../game/tools/gui/colorPicker.ed.gui | 60 +++--- .../add-simgroup-btn_ctrl_i_image.asset.taml | 3 + .../add-simgroup-btn_i_image.asset.taml | 3 + .../gui/images/camera-btn_i_image.asset.taml | 3 + .../gui/images/clear-icon_i_image.asset.taml | 3 + .../gui/images/delete_i_image.asset.taml | 3 + .../dropdown-button-arrow_d_image.asset.taml | 3 + .../dropdown-button-arrow_h_image.asset.taml | 3 + .../dropdown-button-arrow_i_image.asset.taml | 3 + .../dropdown-button-arrow_n_image.asset.taml | 3 + .../game/tools/gui/images/eyedropper_d.png | Bin 0 -> 1123 bytes .../gui/images/eyedropper_d_image.asset.taml | 3 + .../game/tools/gui/images/eyedropper_h.png | Bin 0 -> 1064 bytes .../gui/images/eyedropper_h_image.asset.taml | 3 + .../game/tools/gui/images/eyedropper_i.png | Bin 0 -> 1083 bytes .../gui/images/eyedropper_i_image.asset.taml | 3 + .../game/tools/gui/images/eyedropper_n.png | Bin 0 -> 1097 bytes .../gui/images/eyedropper_n_image.asset.taml | 3 + .../gui/images/folder_d_image.asset.taml | 3 + .../gui/images/folder_h_image.asset.taml | 3 + .../gui/images/folder_i_image.asset.taml | 3 + .../gui/images/folder_n_image.asset.taml | 3 + .../images/images_menuGrid_d_image.asset.taml | 3 + .../images/images_menuGrid_h_image.asset.taml | 3 + .../images/images_menuGrid_image.asset.taml | 3 + .../images/images_menuGrid_n_image.asset.taml | 3 + .../gui/images/layers-btn_i_image.asset.taml | 3 + .../tools/gui/images/lock_i_image.asset.taml | 3 + .../images/new-folder-btn_i_image.asset.taml | 3 + .../tools/gui/images/new_i_image.asset.taml | 3 + .../gui/images/numericslider_image.asset.taml | 3 + .../gui/images/open-file_i_image.asset.taml | 3 + .../gui/images/reset-icon_i_image.asset.taml | 3 + .../images/selector-button_image.asset.taml | 3 + .../gui/images/tab-border_image.asset.taml | 3 + .../images/textEdit_black_image.asset.taml | 3 + .../gui/images/textEdit_blue_image.asset.taml | 3 + .../gui/images/textEdit_cyan_image.asset.taml | 3 + .../images/textEdit_green_image.asset.taml | 3 + .../images/textEdit_magenta_image.asset.taml | 3 + .../gui/images/textEdit_red_image.asset.taml | 3 + .../images/textEdit_white_image.asset.taml | 3 + .../images/textEdit_yellow_image.asset.taml | 3 + .../images/uv-editor-btn_i_image.asset.taml | 3 + 46 files changed, 292 insertions(+), 106 deletions(-) create mode 100644 Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_ctrl_i_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_i_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/camera-btn_i_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/clear-icon_i_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/delete_i_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow_d_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow_h_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow_i_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow_n_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/eyedropper_d.png create mode 100644 Templates/BaseGame/game/tools/gui/images/eyedropper_d_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/eyedropper_h.png create mode 100644 Templates/BaseGame/game/tools/gui/images/eyedropper_h_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/eyedropper_i.png create mode 100644 Templates/BaseGame/game/tools/gui/images/eyedropper_i_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/eyedropper_n.png create mode 100644 Templates/BaseGame/game/tools/gui/images/eyedropper_n_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/folder_d_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/folder_h_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/folder_i_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/folder_n_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/images_menuGrid_d_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/images_menuGrid_h_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/images_menuGrid_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/images_menuGrid_n_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/layers-btn_i_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/lock_i_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/new-folder-btn_i_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/new_i_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/numericslider_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/open-file_i_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/reset-icon_i_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/selector-button_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/tab-border_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/textEdit_black_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/textEdit_blue_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/textEdit_cyan_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/textEdit_green_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/textEdit_magenta_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/textEdit_red_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/textEdit_white_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/textEdit_yellow_image.asset.taml create mode 100644 Templates/BaseGame/game/tools/gui/images/uv-editor-btn_i_image.asset.taml diff --git a/Engine/source/gui/controls/guiColorPicker.cpp b/Engine/source/gui/controls/guiColorPicker.cpp index 7ca985a20..d313d3412 100644 --- a/Engine/source/gui/controls/guiColorPicker.cpp +++ b/Engine/source/gui/controls/guiColorPicker.cpp @@ -29,6 +29,7 @@ #include "gui/controls/guiColorPicker.h" #include "gfx/primBuilder.h" #include "gfx/gfxDrawUtil.h" +#include "postFx/postEffectManager.h" IMPLEMENT_CONOBJECT(GuiColorPickerCtrl); @@ -47,15 +48,23 @@ GuiColorPickerCtrl::GuiColorPickerCtrl() mActive = true; mSelectorGap = 1; mActionOnMove = false; + mDropperActive = false; mShowReticle = true; mSelectedHue = 0; mSelectedAlpha = 255; mSelectedSaturation = 100; mSelectedBrightness = 100; + eyeDropperPos = Point2I::Zero; + eyeDropperCap = NULL; } GuiColorPickerCtrl::~GuiColorPickerCtrl() { + if (eyeDropperCap != NULL) + { + delete eyeDropperCap; + eyeDropperCap = NULL; + } } ImplementEnumType( GuiColorPickMode, @@ -314,6 +323,32 @@ void GuiColorPickerCtrl::renderAlphaSelector(RectI& bounds) GFX->getDrawUtil()->drawRectFill(selectorRect, currentColor, 2.0f, ColorI::WHITE); } +void GuiColorPickerCtrl::renderEyeDropper() +{ + if (eyeDropperCap != NULL) + { + GFX->getDrawUtil()->drawBitmap(eyeHandle, getRoot()->getPosition()); + + Point2I resolution = getRoot()->getExtent(); + Point2I magnifierSize(100, 100); + Point2I magnifierPosition = eyeDropperPos + Point2I(20, 20); + + // Adjust position to ensure magnifier stays on screen + if (magnifierPosition.x + magnifierSize.x > resolution.x) + magnifierPosition.x = eyeDropperPos.x - magnifierSize.x - 20; + if (magnifierPosition.y + magnifierSize.y > resolution.y) + magnifierPosition.y = eyeDropperPos.y - magnifierSize.y - 20; + + RectI magnifierBounds(magnifierPosition, magnifierSize); + + ColorI currentColor; + currentColor.set(ColorI::Hsb(mSelectedHue, mSelectedSaturation, mSelectedBrightness)); + currentColor.alpha = mSelectedAlpha; + + GFX->getDrawUtil()->drawRectFill(magnifierBounds, currentColor, 2.0f, ColorI::BLACK); + } +} + void GuiColorPickerCtrl::onRender(Point2I offset, const RectI& updateRect) { if (mStateBlock.isNull()) @@ -356,6 +391,15 @@ void GuiColorPickerCtrl::onRender(Point2I offset, const RectI& updateRect) if (mShowReticle) renderAlphaSelector(boundsRect); break; } + case GuiColorPickerCtrl::pDropperBackground: + { + if (mDropperActive) + { + // Render the magnified view of our currently selected color. + renderEyeDropper(); + } + break; + } default: break; } @@ -364,72 +408,31 @@ void GuiColorPickerCtrl::onRender(Point2I offset, const RectI& updateRect) renderChildControls(offset, updateRect); } -Point2I GuiColorPickerCtrl::findColor(const LinearColorF & color, const Point2I& offset, const Point2I& resolution, GBitmap& bmp) -{ - Point2I ext = getExtent(); - Point2I closestPos(-1, -1); - - /* Debugging - char filename[256]; - dSprintf( filename, 256, "%s.%s", "colorPickerTest", "png" ); - - // Open up the file on disk. - FileStream fs; - if ( !fs.open( filename, Torque::FS::File::Write ) ) - Con::errorf( "GuiObjectView::saveAsImage() - Failed to open output file '%s'!", filename ); - else - { - // Write it and close. - bmp.writeBitmap( "png", fs ); - - fs.close(); - } - */ - - ColorI tmp; - U32 buf_x; - U32 buf_y; - LinearColorF curColor; - F32 val(10000.0f); - F32 closestVal(10000.0f); - bool closestSet = false; - - for (S32 x = 0; x < ext.x; x++) - { - for (S32 y = 0; y < ext.y; y++) - { - buf_x = offset.x + x; - buf_y = (resolution.y - (offset.y + y)); - buf_y = resolution.y - buf_y; - - //Get the color at that position - bmp.getColor(buf_x, buf_y, tmp); - curColor = (LinearColorF)tmp; - - //Evaluate how close the color is to our desired color - val = mFabs(color.red - curColor.red) + mFabs(color.green - curColor.green) + mFabs(color.blue - curColor.blue); - - if (!closestSet) - { - closestVal = val; - closestPos.set(x, y); - closestSet = true; - } - else if (val < closestVal) - { - closestVal = val; - closestPos.set(x, y); - } - } - } - - return closestPos; -} - void GuiColorPickerCtrl::onMouseDown(const GuiEvent &event) { if (!mActive) return; + + // we need to do this first. + if (mDisplayMode == GuiColorPickerCtrl::pDropperBackground) { + if (mDropperActive) + { + mDropperActive = false; + + //getRoot()->pushObjectToBack(this); + + onAction(); + mouseUnlock(); + + if (eyeDropperCap != NULL) + { + delete eyeDropperCap; + eyeDropperCap = NULL; + } + } + + return; + } mouseLock(this); @@ -574,6 +577,29 @@ void GuiColorPickerCtrl::onMouseDragged(const GuiEvent &event) void GuiColorPickerCtrl::onMouseMove(const GuiEvent &event) { + if (mDisplayMode != pDropperBackground) + return; + + if (!mDropperActive) + return; + + // should not need globalToLocal as we are capturing the whole screen. + eyeDropperPos = globalToLocalCoord(event.mousePoint); + + if (eyeDropperCap != NULL) + { + // Sample the pixel color at the mouse position. Mouse position should translate directly. + ColorI sampledColor; + eyeDropperCap->getColor(eyeDropperPos.x, eyeDropperPos.y, sampledColor); + + // Convert the sampled color to HSB + ColorI::Hsb hsb = sampledColor.getHSB(); + mSelectedHue = hsb.hue; + mSelectedSaturation = hsb.sat; + mSelectedBrightness = hsb.brightness; + mSelectedAlpha = sampledColor.alpha; + } + } void GuiColorPickerCtrl::onMouseEnter(const GuiEvent &event) @@ -587,6 +613,15 @@ void GuiColorPickerCtrl::onMouseLeave(const GuiEvent &) mMouseOver = false; } +void GuiColorPickerCtrl::onMouseUp(const GuiEvent&) +{ + //if we released the mouse within this control, perform the action + if (mActive && mMouseDown) + mMouseDown = false; + + mouseUnlock(); +} + void GuiColorPickerCtrl::setSelectedHue(const F64& hueValue) { if (hueValue < 0) @@ -656,13 +691,34 @@ void GuiColorPickerCtrl::setSelectedAlpha(const F64& alphaValue) mSelectedAlpha = alphaValue; } -void GuiColorPickerCtrl::onMouseUp(const GuiEvent &) +void GuiColorPickerCtrl::activateEyeDropper() { - //if we released the mouse within this control, perform the action - if (mActive && mMouseDown) - mMouseDown = false; + // Make sure we are a pDropperBackground + if (mDisplayMode == GuiColorPickerCtrl::pDropperBackground) + { + mouseLock(this); // take over! - mouseUnlock(); + setFirstResponder(); // we need this to be first responder regardless. + + //getRoot()->bringObjectToFront(this); + + mDropperActive = true; + + // Set up our resolution. + Point2I resolution = getRoot()->getExtent(); + + // Texture handle to resolve the target to. + eyeHandle.set(resolution.x, resolution.y, GFXFormatR8G8B8A8_SRGB, &GFXRenderTargetSRGBProfile, avar("%s() - bb (line %d)", __FUNCTION__, __LINE__)); + + // Get our active render target (should be backbuffer). + eyeHandle = PFXMGR->getBackBufferTex(); + + if (eyeHandle.isValid()) + { + eyeDropperCap = new GBitmap(eyeHandle.getWidth(), eyeHandle.getHeight(), false, GFXFormatR8G8B8A8); + eyeHandle.copyToBmp(eyeDropperCap); + } + } } /// @@ -673,6 +729,14 @@ DefineEngineMethod(GuiColorPickerCtrl, executeUpdate, void, (), , "Execute the o object->onAction(); } +/// +/// This command should only be used with guiColorPicker in pDropperBackground mode. +/// +DefineEngineMethod(GuiColorPickerCtrl, activateEyeDropper, void, (), , "Activate the dropper mode.") +{ + object->activateEyeDropper(); +} + DefineEngineMethod(GuiColorPickerCtrl, setSelectedHue, void, (F64 hueValue), , "Sets the selected hue value should be 0-360.") { object->setSelectedHue(hueValue); diff --git a/Engine/source/gui/controls/guiColorPicker.h b/Engine/source/gui/controls/guiColorPicker.h index 48639520a..58a8b8302 100644 --- a/Engine/source/gui/controls/guiColorPicker.h +++ b/Engine/source/gui/controls/guiColorPicker.h @@ -108,23 +108,27 @@ class GuiColorPickerCtrl : public GuiControl /// The bounds of the ctrl. void renderAlphaSelector(RectI& bounds); + void renderEyeDropper(); + /// @name Core Variables /// @{ - PickMode mDisplayMode; ///< Current color display mode of the selector + PickMode mDisplayMode; ///< Current color display mode of the selector SelectorMode mSelectorMode; ///< Current color display mode of the selector F64 mSelectedHue; F64 mSelectedSaturation; F64 mSelectedBrightness; F64 mSelectedAlpha; + Point2I eyeDropperPos; + GBitmap* eyeDropperCap; + GFXTexHandle eyeHandle; - bool mMouseOver; ///< Mouse is over? - bool mMouseDown; ///< Mouse button down? - bool mActionOnMove; ///< Perform onAction() when position has changed? - bool mShowReticle; ///< Show reticle on render + bool mDropperActive; ///< Is the eye dropper active? + bool mMouseOver; ///< Mouse is over? + bool mMouseDown; ///< Mouse button down? + bool mActionOnMove; ///< Perform onAction() when position has changed? + bool mShowReticle; ///< Show reticle on render - Point2I findColor(const LinearColorF & color, const Point2I& offset, const Point2I& resolution, GBitmap& bmp); - - S32 mSelectorGap; ///< The half-way "gap" between the selector pos and where the selector is allowed to draw. + S32 mSelectorGap; ///< The half-way "gap" between the selector pos and where the selector is allowed to draw. GFXStateBlockRef mStateBlock; /// @} @@ -181,6 +185,9 @@ class GuiColorPickerCtrl : public GuiControl /// Alpha value, 0 - 255. void setSelectedAlpha(const F64& alphaValue); F64 getSelectedAlpha() { return mSelectedAlpha; } + + void activateEyeDropper(); + }; typedef GuiColorPickerCtrl::PickMode GuiColorPickMode; diff --git a/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui b/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui index 4c92f0ec9..3c6d60901 100644 --- a/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui +++ b/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui @@ -1,36 +1,25 @@ //--- OBJECT WRITE BEGIN --- $guiContent = new GuiColorPickerCtrl(ColorPickerDlg,EditorGuiGroup) { - displayMode = "Dropper"; // this makes the background visible - actionOnMove = "1"; - position = "0 0"; - extent = "1024 768"; - minExtent = "8 2"; - horizSizing = "right"; - vertSizing = "bottom"; - profile = "ToolsGuiDefaultProfile"; - visible = "1"; - active = "1"; - Clickable = "1"; - AffectChildren = "1"; - tooltipProfile = "GuiToolTipProfile"; - hovertime = "1000"; - isContainer = "1"; - canSave = "1"; - canSaveDynamicFields = "0"; + displayMode = "Dropper"; + extent = "1024 768"; + profile = "GuiDefaultProfile"; + command = "%selHue = ColorPickerDlg.getSelectedHue();\n%selSat = ColorPickerDlg.getSelectedSaturation();\n%selBright = ColorPickerDlg.getSelectedBrightness();\n%selAlpha = ColorPickerDlg.getSelectedAlpha();\n\nColorHueRange.setSelectedHue(%selHue);\nColorHueRange.executeUpdate();\n\nColorBlendRange.setSelectedBrightness(%selBright);\nColorBlendRange.setSelectedSaturation(%selSat);\nColorBlendRange.executeUpdate();\n\nColorAlphaRange.setSelectedAlpha(%selAlpha);\nColorAlphaRange.executeUpdate();\n\nColorEyeDropperButton.setStateOn(false);"; + tooltipProfile = "GuiToolTipProfile"; + isContainer = "1"; new GuiWindowCtrl() { - text = " "; - resizeWidth = "0"; - resizeHeight = "0"; - canMinimize = "0"; - canMaximize = "0"; - closeCommand = "DoColorPickerCancelCallback(); ColorPickerDlg.getRoot().popDialog(ColorPickerDlg);"; - position = "33 33"; - extent = "271 574"; - horizSizing = "windowRelative"; - vertSizing = "windowRelative"; - profile = "ToolsGuiWindowProfile"; - tooltipProfile = "ToolsGuiToolTipProfile"; + text = " "; + resizeWidth = "0"; + resizeHeight = "0"; + canMinimize = "0"; + canMaximize = "0"; + closeCommand = "DoColorPickerCancelCallback(); ColorPickerDlg.getRoot().popDialog(ColorPickerDlg);"; + position = "33 33"; + extent = "271 574"; + horizSizing = "windowRelative"; + vertSizing = "windowRelative"; + profile = "ToolsGuiWindowProfile"; + tooltipProfile = "ToolsGuiToolTipProfile"; new GuiStackControl() { padding = "5"; @@ -268,16 +257,25 @@ $guiContent = new GuiColorPickerCtrl(ColorPickerDlg,EditorGuiGroup) { text = "Apply"; position = "211 1"; extent = "52 20"; - command = "DoColorPickerCallback();"; profile = "ToolsGuiButtonProfile"; + command = "DoColorPickerCallback();"; tooltipProfile = "GuiToolTipProfile"; }; new GuiButtonCtrl() { text = "Cancel"; position = "211 24"; extent = "52 20"; - command = "DoColorPickerCancelCallback();"; profile = "ToolsGuiButtonProfile"; + command = "DoColorPickerCancelCallback();"; + tooltipProfile = "GuiToolTipProfile"; + }; + new GuiBitmapButtonCtrl(ColorEyeDropperButton) { + BitmapAsset = "ToolsModule:eyedropper_n_image"; + buttonType = "ToggleButton"; + position = "223 56"; + extent = "25 25"; + profile = "ToolsGuiCheckBoxProfile"; + command = "ColorPickerDlg.activateEyeDropper();"; tooltipProfile = "GuiToolTipProfile"; }; }; diff --git a/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_ctrl_i_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_ctrl_i_image.asset.taml new file mode 100644 index 000000000..ad5abe6ce --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_ctrl_i_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_i_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_i_image.asset.taml new file mode 100644 index 000000000..652dbaa97 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/add-simgroup-btn_i_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/camera-btn_i_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/camera-btn_i_image.asset.taml new file mode 100644 index 000000000..b256d1f27 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/camera-btn_i_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/clear-icon_i_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/clear-icon_i_image.asset.taml new file mode 100644 index 000000000..bf9066933 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/clear-icon_i_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/delete_i_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/delete_i_image.asset.taml new file mode 100644 index 000000000..0af4b8434 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/delete_i_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow_d_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow_d_image.asset.taml new file mode 100644 index 000000000..50cf4e2ef --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow_d_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow_h_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow_h_image.asset.taml new file mode 100644 index 000000000..f352d6fc0 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow_h_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow_i_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow_i_image.asset.taml new file mode 100644 index 000000000..dfe09e6e3 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow_i_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow_n_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow_n_image.asset.taml new file mode 100644 index 000000000..eeb0c947b --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/dropdown-button-arrow_n_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/eyedropper_d.png b/Templates/BaseGame/game/tools/gui/images/eyedropper_d.png new file mode 100644 index 0000000000000000000000000000000000000000..adeb5b79e0f4e17579fd03f78b8c93ef07c459bc GIT binary patch literal 1123 zcmV-p1f2VcP)EX>4Tx04R}tkv&MmP!xqvQ>7vm2aAe0WT;Md(ISqeibb$c+6t{Yn7s54nlvOS zE{=k0!NH%!s)LKOt`4q(Aov5~E;uQ=NQw6)g%&Yhc)XAE?m4`7A0RZVOf`FAfT~$W zIuRFh`BgFS3Ll0sf*_(2GxcOT7x~Fccy9m$n?)$R_l!D0spGX{Ix?vG-5YKK} zI_G`j5GzXx@j3C7K^G)`lrQ95 zRyc2QR;zW^z9)ZSu%NAExK3*v2`nLr6hz3Vqk<|dL}=GYF_EV8xQBnt@u$coldA$o zjs?`9LUR1zfAD*@W^rcPO$x?=-WS{cm;eI1K&xTf-^aGyIsyF8z?IhV*P6iGC+Urj z7Cr(7w}Ff6jwbH`mpj1dlP(#OBl&3w#Uk*2M&FbNhHioWHFs|9bDTZ^S(?@I4RCM> zOqM8n-Q(ST-E;f5r#-(P()n`D+^se800006VoOIv0BZoL0A5Yo=RW`d010qNS#tmY zE+YT{E+YYWr9XB6000McNliru=>ZlOFcBFNV(kC`02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00JRNL_t(o!|m2PXjD-U2H-E71dI_>e4|2$5y6NkW-GzM zDrg}n2$DiUEsl+#2);lNUyX&;0TIzgun-|#Kr4$VMhQZ|G@@vfAVCFDHzpgKQ-mcC zvwL?No$lUy?)?AE{4;a-*R3vVharRpti$5;Y6S0MjH6SXZ^#(D5&Lik%Ts`ZIE~(_ zWgvu5hlMzZtC*L3Phb?Uu{*{%RQhi&qu`ry3|G)p64*GFV&zmnW<_8LIum$lhMN+B z^_giPgiwza7>+THV+}UXP|^{+%~FJ`aULH+2;InI!8B)orP932lE5#=>-t>dQgz>+37#^Z5ZhLpwI6PZKHSy*PzC zGl5q+h>F;N?UTTNq8~TW6Jz{6o0Ce~umva3n817R0*i1qk(<>jX~R8eO9Je{ku(i= z;8G$Y^9&^L4s@je9wDTeFo?U@i>FoDh9QL31k!;|ID{uL#))#WnVTc{d>l{UW4Mmq za>3_BAg$VyY3bDAKJNXE(zD9ImL#-X>i=u_TIm*>YZrXM`!rsT&LhN| p0000EWmrjOO-%qQ00008000000002eQ diff --git a/Templates/BaseGame/game/tools/gui/images/eyedropper_h.png b/Templates/BaseGame/game/tools/gui/images/eyedropper_h.png new file mode 100644 index 0000000000000000000000000000000000000000..e6f20028169b2fe8ec5ebae6aacbd2114a77a4d5 GIT binary patch literal 1064 zcmV+@1lRkCP)EX>4Tx04R}tkv&MmP!xqvQ>7vm2aAe0WT;Md(ISqeibb$c+6t{Yn7s54nlvOS zE{=k0!NH%!s)LKOt`4q(Aov5~E;uQ=NQw6)g%&Yhc)XAE?m4`7A0RZVOf`FAfT~$W zIuRFh`BgFS3Ll0sf*_(2GxcOT7x~Fccy9m$n?)$R_l!D0spGX{Ix?vG-5YKK} zI_G`j5GzXx@j3C7K^G)`lrQ95 zRyc2QR;zW^z9)ZSu%NAExK3*v2`nLr6hz3Vqk<|dL}=GYF_EV8xQBnt@u$coldA$o zjs?`9LUR1zfAD*@W^rcPO$x?=-WS{cm;eI1K&xTf-^aGyIsyF8z?IhV*P6iGC+Urj z7Cr(7w}Ff6jwbH`mpj1dlP(#OBl&3w#Uk*2M&FbNhHioWHFs|9bDTZ^S(?@I4RCM> zOqM8n-Q(ST-E;f5r#-(P()n`D+^se800006VoOIv0BZoL0A5Yo=RW`d010qNS#tmY zE+YT{E+YYWr9XB6000McNliru=>ZlOE+TS+JR|@B02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00HJnL_t(o!{yh_i%($`2k`GTFB&XnjD@@l&%O8i zea`uw=bW3&cdOd{L3AcrpQNw2#*@6Ps_JX)yFnNB;{o2_EpA|E-M|%kaSRif^2??$ ziThYtCxIn6iBEpFsp1>OmR9dBXcLG2Bzuzdw9r^jl4VIYw2c5dumT;$wJOQr9HJgi z@}kv3=YQ^aWs>0}qqvl0Ymy~@cy=<$nI!kxne#1pitl)ghg#bYoW;UA%IzRt;a$0A z1AoLYdg`qC-MBVO^%J;`edwyQ^g3_|UuTuvZ5(KO*jo@-k4H1Wui|F$jbO0u-54Qu-;TRQY*(=wRax)GE_ByLU>$DZGoE8;8oY^aw+QD7_(vSARp~9t z?o`S7Brc$@vB?En@v`Lo1_s&@`hV>O?~}Yvaw5s|s;V>@fv(a6*39UF_0EJvV4KSA zqpGUDH9E0k2cF>xwlxjD7?)=pwWr$|`oAG?q$qycMzFTsICG6;6SFijkYsa{1imDh zS!Rl_u@o%D#gc|eoJVhCzh>o>>rb*b$yky*Nj@}s_{TF0000 diff --git a/Templates/BaseGame/game/tools/gui/images/eyedropper_i.png b/Templates/BaseGame/game/tools/gui/images/eyedropper_i.png new file mode 100644 index 0000000000000000000000000000000000000000..c48e15d7f7e8fafd3b48df017e6bf4b032c45784 GIT binary patch literal 1083 zcmV-B1jPG^P)EX>4Tx04R}tkv&MmP!xqvQ>7vm2aAe0WT;Md(ISqeibb$c+6t{Yn7s54nlvOS zE{=k0!NH%!s)LKOt`4q(Aov5~E;uQ=NQw6)g%&Yhc)XAE?m4`7A0RZVOf`FAfT~$W zIuRFh`BgFS3Ll0sf*_(2GxcOT7x~Fccy9m$n?)$R_l!D0spGX{Ix?vG-5YKK} zI_G`j5GzXx@j3C7K^G)`lrQ95 zRyc2QR;zW^z9)ZSu%NAExK3*v2`nLr6hz3Vqk<|dL}=GYF_EV8xQBnt@u$coldA$o zjs?`9LUR1zfAD*@W^rcPO$x?=-WS{cm;eI1K&xTf-^aGyIsyF8z?IhV*P6iGC+Urj z7Cr(7w}Ff6jwbH`mpj1dlP(#OBl&3w#Uk*2M&FbNhHioWHFs|9bDTZ^S(?@I4RCM> zOqM8n-Q(ST-E;f5r#-(P()n`D+^se800006VoOIv0BZoL0A5Yo=RW`d010qNS#tmY zE+YT{E+YYWr9XB6000McNliru=>ZlOFepYB>g50c02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00H?)L_t(o!|m4FYEw}V2H-ETt+lm{r%DkOMFsH$7Pbi9 z`8NBB*5iocg-X;Sf(P`XT0w)gVh2~HoiQr?nj60abXsijG%(Co5ymR3Qd-A)p65TJ|2KvefhpV$;jLmmrL?;J zG4lSoS7+5d-hKqvA_6VED4KGm6NpiJ16N|}J>K=A^s*vwJjQJ$@;jeWY7RQZ_Nswq z diff --git a/Templates/BaseGame/game/tools/gui/images/eyedropper_n.png b/Templates/BaseGame/game/tools/gui/images/eyedropper_n.png new file mode 100644 index 0000000000000000000000000000000000000000..4bc1ed2198c4237362ffb8480972a3076432b333 GIT binary patch literal 1097 zcmV-P1h)H$P)EX>4Tx04R}tkv&MmP!xqvQ>7vm2aAe0WT;Md(ISqeibb$c+6t{Yn7s54nlvOS zE{=k0!NH%!s)LKOt`4q(Aov5~E;uQ=NQw6)g%&Yhc)XAE?m4`7A0RZVOf`FAfT~$W zIuRFh`BgFS3Ll0sf*_(2GxcOT7x~Fccy9m$n?)$R_l!D0spGX{Ix?vG-5YKK} zI_G`j5GzXx@j3C7K^G)`lrQ95 zRyc2QR;zW^z9)ZSu%NAExK3*v2`nLr6hz3Vqk<|dL}=GYF_EV8xQBnt@u$coldA$o zjs?`9LUR1zfAD*@W^rcPO$x?=-WS{cm;eI1K&xTf-^aGyIsyF8z?IhV*P6iGC+Urj z7Cr(7w}Ff6jwbH`mpj1dlP(#OBl&3w#Uk*2M&FbNhHioWHFs|9bDTZ^S(?@I4RCM> zOqM8n-Q(ST-E;f5r#-(P()n`D+^se800006VoOIv0BZoL0A5Yo=RW`d010qNS#tmY zE+YT{E+YYWr9XB6000McNliru=>ZlOFCuH04P^iT02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00IX|L_t(o!{yh_OH@%92Jqh*H8HJB%f7J)B*+MgiXbQm zp<46-{RjO??OO!xqOF0osy5L^$Y_)H0aAn|DG54y+PuOrj5f~PnT=<6?mhQB&-?K_ z=Ule?NJVd$b1q>&dgIX|ex;PkwbpkQ4BmlrxPjgA_y?Y0x@8&2IVbesGVVoS2^p*S zj)y6w`RZ>=1qHtYS8*3zRe`Oc4|{5TSQLRioDT5n40px*p~48{oJ%?9{%APp$I(qn zx`??Vo3J0ZFrRat#Bp?Qu(phGd@Yi|E}X(3E<~McWi#U?UT-AB)P&qF;dV5j3f->* zFXK5TQc5d@8&Qxrfjbzf04`$&FYrF4w7S_o%@|R}0i3LuuizVAVd{V2&B|~PW9SI* z5BP$exQT=HY|`1N3~@F*e+^T39Bw!gW$9@NfdC(lChUmFpI{-S^e5*$huO$ROENHk z`#2QlGLHF_QihP*r+POlZ87>CxE>i;!vv<+!5bN+Ey`{T*FwJU@V1^#FDe7aa3#QJ z!eo}3J;k=#1Ap-wPw}&v)HmdOIp^V=^FYNZ*xEZ`)ctTwXPd2eBPAHdgSb{b!snt1 zls1XJJ1liy+-63LOnp5nxQH_qr8OEiz zkzxF7^kNhX;eJbPHJ@!U{s9L+qGRTg)vo{m01jnXNoGw=04e|g00;m8000000Mb*F P00000NkvXXu0mjfiuL17 literal 0 HcmV?d00001 diff --git a/Templates/BaseGame/game/tools/gui/images/eyedropper_n_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/eyedropper_n_image.asset.taml new file mode 100644 index 000000000..89a658bfa --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/eyedropper_n_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/folder_d_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/folder_d_image.asset.taml new file mode 100644 index 000000000..19f226dec --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/folder_d_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/folder_h_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/folder_h_image.asset.taml new file mode 100644 index 000000000..2b3f8f34b --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/folder_h_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/folder_i_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/folder_i_image.asset.taml new file mode 100644 index 000000000..04d8c37c1 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/folder_i_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/folder_n_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/folder_n_image.asset.taml new file mode 100644 index 000000000..4fcd53625 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/folder_n_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/images_menuGrid_d_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/images_menuGrid_d_image.asset.taml new file mode 100644 index 000000000..b743dfda7 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/images_menuGrid_d_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/images_menuGrid_h_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/images_menuGrid_h_image.asset.taml new file mode 100644 index 000000000..6205526f1 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/images_menuGrid_h_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/images_menuGrid_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/images_menuGrid_image.asset.taml new file mode 100644 index 000000000..779ddd4ee --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/images_menuGrid_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/images_menuGrid_n_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/images_menuGrid_n_image.asset.taml new file mode 100644 index 000000000..a56f2bdf5 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/images_menuGrid_n_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/layers-btn_i_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/layers-btn_i_image.asset.taml new file mode 100644 index 000000000..c795223c1 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/layers-btn_i_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/lock_i_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/lock_i_image.asset.taml new file mode 100644 index 000000000..d0b0ec133 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/lock_i_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/new-folder-btn_i_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/new-folder-btn_i_image.asset.taml new file mode 100644 index 000000000..d3dd1b751 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/new-folder-btn_i_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/new_i_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/new_i_image.asset.taml new file mode 100644 index 000000000..6e1adc880 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/new_i_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/numericslider_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/numericslider_image.asset.taml new file mode 100644 index 000000000..b869224ef --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/numericslider_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/open-file_i_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/open-file_i_image.asset.taml new file mode 100644 index 000000000..954425721 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/open-file_i_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/reset-icon_i_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/reset-icon_i_image.asset.taml new file mode 100644 index 000000000..e7f5929f4 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/reset-icon_i_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/selector-button_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/selector-button_image.asset.taml new file mode 100644 index 000000000..bf61a6c0f --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/selector-button_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/tab-border_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/tab-border_image.asset.taml new file mode 100644 index 000000000..13e8e4439 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/tab-border_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/textEdit_black_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/textEdit_black_image.asset.taml new file mode 100644 index 000000000..e98e0d81a --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/textEdit_black_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/textEdit_blue_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/textEdit_blue_image.asset.taml new file mode 100644 index 000000000..f3f3a8cb2 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/textEdit_blue_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/textEdit_cyan_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/textEdit_cyan_image.asset.taml new file mode 100644 index 000000000..695ce779c --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/textEdit_cyan_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/textEdit_green_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/textEdit_green_image.asset.taml new file mode 100644 index 000000000..8748f435d --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/textEdit_green_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/textEdit_magenta_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/textEdit_magenta_image.asset.taml new file mode 100644 index 000000000..c1e9b1168 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/textEdit_magenta_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/textEdit_red_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/textEdit_red_image.asset.taml new file mode 100644 index 000000000..068a48c26 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/textEdit_red_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/textEdit_white_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/textEdit_white_image.asset.taml new file mode 100644 index 000000000..7b50f7bea --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/textEdit_white_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/textEdit_yellow_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/textEdit_yellow_image.asset.taml new file mode 100644 index 000000000..eec442900 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/textEdit_yellow_image.asset.taml @@ -0,0 +1,3 @@ + diff --git a/Templates/BaseGame/game/tools/gui/images/uv-editor-btn_i_image.asset.taml b/Templates/BaseGame/game/tools/gui/images/uv-editor-btn_i_image.asset.taml new file mode 100644 index 000000000..385b79fa3 --- /dev/null +++ b/Templates/BaseGame/game/tools/gui/images/uv-editor-btn_i_image.asset.taml @@ -0,0 +1,3 @@ + From 48ca98ca84c682e9c22a192fe19c016f7d82b570 Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Thu, 23 Jan 2025 14:46:05 +0000 Subject: [PATCH 2/9] color palette saving for now saves palette colours as their hex value. This will miss out on the alpha value. --- Engine/source/core/color.h | 1 + .../game/tools/gui/colorPicker.ed.gui | 109 ++++++++++++++++-- 2 files changed, 99 insertions(+), 11 deletions(-) diff --git a/Engine/source/core/color.h b/Engine/source/core/color.h index 2b6ade809..c4e1ffe13 100644 --- a/Engine/source/core/color.h +++ b/Engine/source/core/color.h @@ -550,6 +550,7 @@ inline void ColorI::set(const String& hex) red = (U8)(convertFromHex(redString)); green = (U8)(convertFromHex(greenString)); blue = (U8)(convertFromHex(blueString)); + alpha = 255; } inline S32 ColorI::convertFromHex(const String& hex) const diff --git a/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui b/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui index 3c6d60901..236262deb 100644 --- a/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui +++ b/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui @@ -26,7 +26,7 @@ $guiContent = new GuiColorPickerCtrl(ColorPickerDlg,EditorGuiGroup) { changeChildSizeToFit = "0"; changeChildPosition = "0"; position = "0 24"; - extent = "271 481"; + extent = "271 491"; profile = "GuiDefaultProfile"; tooltipProfile = "GuiToolTipProfile"; @@ -283,20 +283,26 @@ $guiContent = new GuiColorPickerCtrl(ColorPickerDlg,EditorGuiGroup) { }; new GuiRolloutCtrl() { caption = ":: Color Palette"; + margin = "5 5 5 5"; position = "0 445"; - extent = "271 36"; + extent = "271 46"; profile = "GuiRolloutProfile"; tooltipProfile = "GuiToolTipProfile"; - new GuiStackControl() { - stackingType = "Dynamic"; - padding = "5"; - changeChildSizeToFit = "0"; - position = "0 17"; - extent = "271 16"; - profile = "GuiDefaultProfile"; - tooltipProfile = "GuiToolTipProfile"; - }; + new GuiDynamicCtrlArrayControl(ColorPaletteStack) { + colCount = "12"; + colSize = "12"; + rowSize = "12"; + rowCount = "3"; + rowSpacing = "1"; + colSpacing = "1"; + dynamicSize = "1"; + padding = "3 3 3 3"; + position = "0 17"; + extent = "271 47"; + profile = "GuiDefaultProfile"; + tooltipProfile = "GuiToolTipProfile"; + }; }; }; }; @@ -342,6 +348,87 @@ function GetColorF( %currentColor, %callback, %root, %updateCallback, %cancelCal %root.pushDialog(ColorPickerDlg); } +function ColorPaletteStack::onWake(%this) +{ + if($Pref::ColorPicker::ColorPalette $= "") + { + $Pref::ColorPicker::ColorPalette = "#FFFFFF #FF0000 #00FF00 #0000FF"; + } + + %colorCount = getWordCount($Pref::ColorPicker::ColorPalette); + + if(%colorCount > 63) + %colorCount = 63; + + for(%i=0; %i < %colorCount; %i++) + { + %hex = getWord($Pref::ColorPicker::ColorPalette, %i); + %rgb = ColorHEXToRGB(%hex); + %rgb = ColorIntToFloat(%rgb); + + %colorBox = new GuiSwatchButtonCtrl() { + extent = "16 16"; + color = %rgb; + profile = "GuiDefaultProfile"; + colorHex = %hex; + useMouseEvents = "1"; + class = "ColorPaletteSwatch"; + }; + + ColorPaletteStack.Add(%colorBox); + } + + %button = new GuiButtonCtrl() { + text = "+"; + extent = "16 16"; + profile = "ToolsGuiButtonProfile"; + tooltipProfile = "GuiToolTipProfile"; + command = "ColorPaletteStack.addCurrentColorToStack();"; + }; + + ColorPaletteStack.Add(%button); +} + +function ColorPaletteStack::addCurrentColorToStack(%this) +{ + %hex = HexTextEditor.getValue(); + //Make sure we have 6 characters + while(strlen(%hex) < 6) + { + %hex = "0" @ %hex; + } + %hex = strupr(%hex); + + $Pref::ColorPicker::ColorPalette = "#" @ %hex SPC $Pref::ColorPicker::ColorPalette; + ColorPaletteStack.clear(); + ColorPaletteStack.onWake(); +} + +function ColorPaletteStack::onSleep(%this) +{ + ColorPaletteStack.clear(); +} + +function ColorPaletteSwatch::onMouseDown(%this) +{ + //Update all the other color fields + %rgb = ColorHEXToRGB(%this.colorHex); + %hsb = ColorRGBToHSB(%rgb); + + // these automatically update our ColorNewSelected which + // updates all text fields including these. + ColorHueRange.setSelectedHue(getWord(%hsb, 0)); + ColorHueRange.executeUpdate(); + + ColorBlendRange.setSelectedSaturation(getWord(%hsb, 1)); + ColorBlendRange.setSelectedBrightness(getWord(%hsb, 2)); + ColorBlendRange.executeUpdate(); + + // for now just set full alpha until we save out alpha as well + ColorAlphaRange.setSelectedAlpha(255); + ColorAlphaRange.executeUpdate(); +} + function ColorPickerRGBClass::onValidate(%this) { %red = RedTextEdit.getValue(); From 704e304eef8cc1076827d2a3e674b9ec746be49e Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Thu, 23 Jan 2025 19:06:35 +0000 Subject: [PATCH 3/9] display correct values Few fixes to display float values if the inspector field asks for floats Split Hsb out from colorI now linearColorF can return HSB from its own color without having to go through the colorI conversion, hopefully gets rid of rounding errors etc since we are only doing the calc once. --- Engine/source/console/consoleFunctions.cpp | 18 +- Engine/source/core/color.h | 158 ++++++++++++++---- Engine/source/gui/controls/guiColorPicker.cpp | 37 ++-- .../game/tools/gui/colorPicker.ed.gui | 12 +- 4 files changed, 170 insertions(+), 55 deletions(-) diff --git a/Engine/source/console/consoleFunctions.cpp b/Engine/source/console/consoleFunctions.cpp index a2555c99f..dbcf28963 100644 --- a/Engine/source/console/consoleFunctions.cpp +++ b/Engine/source/console/consoleFunctions.cpp @@ -1104,7 +1104,21 @@ DefineEngineFunction(ColorRGBToHSB, const char*, (ColorI color), , "@endtsexample\n" "@ingroup Strings") { - ColorI::Hsb hsb(color.getHSB()); + Hsb hsb(color.getHSB()); + String s(String::ToString(hsb.hue) + " " + String::ToString(hsb.sat) + " " + String::ToString(hsb.brightness)); + return Con::getReturnBuffer(s); +} + +DefineEngineFunction(ColorLinearRGBToHSB, const char*, (LinearColorF color), , + "Convert from a integer RGB (red, green, blue) color to HSB (hue, saturation, brightness). HSB is also know as HSL or HSV as well, with the last letter standing for lightness or value.\n" + "@param color Integer color value to be converted in the form \"R G B A\", where R is red, G is green, B is blue, and A is alpha. It excepts an alpha, but keep in mind this will not be converted.\n" + "@return HSB color value, alpha isn't handled/converted so it is only the RGB value\n\n" + "@tsexample\n" + "ColorRBGToHSB( \"0 0 255 128\" ) // Returns \"240 100 100\".\n" + "@endtsexample\n" + "@ingroup Strings") +{ + Hsb hsb(color.getHSB()); String s(String::ToString(hsb.hue) + " " + String::ToString(hsb.sat) + " " + String::ToString(hsb.brightness)); return Con::getReturnBuffer(s); } @@ -1133,7 +1147,7 @@ DefineEngineFunction(ColorHSBToRGB, ColorI, (Point3I hsb), , "@ingroup Strings") { ColorI color; - color.set(ColorI::Hsb(hsb.x, hsb.y, hsb.z)); + color.set(Hsb(hsb.x, hsb.y, hsb.z)); return color; } diff --git a/Engine/source/core/color.h b/Engine/source/core/color.h index c4e1ffe13..b9da6872e 100644 --- a/Engine/source/core/color.h +++ b/Engine/source/core/color.h @@ -34,9 +34,24 @@ #include "console/engineAPI.h" #endif +#ifdef TORQUE_USE_LEGACY_GAMMA const F32 gGamma = 2.2f; const F32 gOneOverGamma = 1.f / 2.2f; +#else +const F32 gGamma = 2.4f; +const F32 gOneOverGamma = 1.f / 2.4f; const F32 gOneOver255 = 1.f / 255.f; +#endif + +struct Hsb +{ + Hsb() :hue(0), sat(0), brightness(0) {}; + Hsb(F64 h, F64 s, F64 b) :hue(h), sat(s), brightness(b) {}; + + F64 hue; ///Hue + F64 sat; ///Saturation + F64 brightness; //Brightness/Value/Lightness +}; class ColorI; @@ -55,9 +70,14 @@ public: LinearColorF(const F32 in_r, const F32 in_g, const F32 in_b, const F32 in_a = 1.0f); LinearColorF(const ColorI &color); LinearColorF(const char* pStockColorName); + LinearColorF(const Hsb& color); + + F32 srgbToLinearChannel(const F32 chan_col); + F32 linearChannelToSrgb(const F32 chan_col); void set( const F32 in_r, const F32 in_g, const F32 in_b, const F32 in_a = 1.0f ); void set( const char* pStockColorName ); + void set(const Hsb& color); static const LinearColorF& StockColor( const char* pStockColorName ); StringTableEntry StockColor( void ); @@ -88,6 +108,7 @@ public: U32 getARGBPack() const; U32 getRGBAPack() const; U32 getABGRPack() const; + Hsb getHSB() const; void interpolate(const LinearColorF& in_rC1, const LinearColorF& in_rC2, @@ -126,16 +147,6 @@ public: U8 blue; U8 alpha; - struct Hsb - { - Hsb() :hue(0), sat(0), brightness(0){}; - Hsb(F64 h, F64 s, F64 b) :hue(h), sat(s), brightness(b){}; - - F64 hue; ///Hue - F64 sat; ///Saturation - F64 brightness; //Brightness/Value/Lightness - }; - public: ColorI() : red(0), green(0), blue(0), alpha(0) {} ColorI(const ColorI& in_rCopy); @@ -247,6 +258,27 @@ public: static void destroy( void ); }; +inline F32 LinearColorF::srgbToLinearChannel(const F32 chan_col) +{ + if (chan_col < 0.0405f) { + return chan_col / 12.92f; + } + else { + return mPow((chan_col + 0.055f) / 1.055f, gGamma); + } +} + +inline F32 LinearColorF::linearChannelToSrgb(const F32 chan_col) +{ + if (chan_col <= 0.0031308f) { + return chan_col * 12.92f; + } + else { + return 1.055f * mPow(chan_col, gOneOverGamma) - 0.055f; + } +} + + //------------------------------------------------------------------------------ //-------------------------------------- INLINES (LinearColorF) // @@ -441,6 +473,72 @@ inline F32 LinearColorF::luminance() return red * 0.3f + green * 0.59f + blue * 0.11f; } +inline LinearColorF::LinearColorF(const Hsb& color) +{ + set(color); +} + +inline void LinearColorF::set(const Hsb& color) +{ + F64 c = (color.brightness / 100.0) * (color.sat / 100.0); + F64 x = c * (1.0 - fabs(fmod(color.hue / 60.0, 2.0) - 1.0)); + F64 m = (color.brightness / 100.0) - c; + + F64 r = 0.0, g = 0.0, b = 0.0; + if (color.hue < 60.0) { + r = c; g = x; b = 0.0; + } + else if (color.hue < 120.0) { + r = x; g = c; b = 0.0; + } + else if (color.hue < 180.0) { + r = 0.0; g = c; b = x; + } + else if (color.hue < 240.0) { + r = 0.0; g = x; b = c; + } + else if (color.hue < 300.0) { + r = x; g = 0.0; b = c; + } + else { + r = c; g = 0.0; b = x; + } + + red = static_cast(r + m); + green = static_cast(g + m); + blue = static_cast(b + m); + alpha = 1.0f; // Default alpha to 1.0 +} + +inline Hsb LinearColorF::getHSB() const +{ + F32 maxVal = mMax( red, mMax(green, blue)); + F32 minVal = mMin(red, mMin(green, blue)); + F32 delta = maxVal - minVal; + + Hsb hsb; + hsb.brightness = maxVal * 100.0; // Convert to percentage + hsb.sat = (maxVal > 0.0f) ? (delta / maxVal) * 100.0 : 0.0; + + if (delta > 0.0f) { + if (red == maxVal) + hsb.hue = 60.0 * mFmod(((green - blue) / delta), 6.0); + else if (green == maxVal) + hsb.hue = 60.0 * (((blue - red) / delta) + 2.0); + else + hsb.hue = 60.0 * (((red - green) / delta) + 4.0); + + if (hsb.hue < 0.0) + hsb.hue += 360.0; + } + else { + hsb.hue = 0.0; + } + + return hsb; +} + + //------------------------------------------------------------------------------ //-------------------------------------- INLINES (ColorI) // @@ -719,7 +817,7 @@ inline U16 ColorI::get4444() const U16(U16(blue >> 4) << 0)); } -inline ColorI::Hsb ColorI::getHSB() const +inline Hsb ColorI::getHSB() const { // Normalize RGB values to [0, 1] F64 rPercent = (F64)red / 255.0; @@ -740,22 +838,22 @@ inline ColorI::Hsb ColorI::getHSB() const S = delta / maxColor; // Saturation // Compute hue - if (fabs(maxColor - rPercent) < 1e-6) + if (mFabsD(maxColor - rPercent) < 1e-6) { H = 60.0 * ((gPercent - bPercent) / delta); } - else if (fabs(maxColor - gPercent) < 1e-6) + else if (mFabsD(maxColor - gPercent) < 1e-6) { H = 60.0 * (((bPercent - rPercent) / delta) + 2.0); } - else if (fabs(maxColor - bPercent) < 1e-6) + else if (mFabsD(maxColor - bPercent) < 1e-6) { H = 60.0 * (((rPercent - gPercent) / delta) + 4.0); } } // Prepare the output HSB struct - ColorI::Hsb val; + Hsb val; val.hue = H; // Round to nearest integer val.sat = S * 100.0; // Convert to percentage val.brightness = B * 100.0; // Convert to percentage @@ -782,9 +880,9 @@ inline String ColorI::getHex() const inline LinearColorF::LinearColorF( const ColorI &color) { - red = sSrgbToLinear[color.red], - green = sSrgbToLinear[color.green], - blue = sSrgbToLinear[color.blue], + red = srgbToLinearChannel(color.red * gOneOver255), + green = srgbToLinearChannel(color.green * gOneOver255), + blue = srgbToLinearChannel(color.blue * gOneOver255), alpha = F32(color.alpha * gOneOver255); } @@ -799,14 +897,14 @@ inline ColorI LinearColorF::toColorI(const bool keepAsLinear) else { #ifdef TORQUE_USE_LEGACY_GAMMA - float r = mPow(red, gOneOverGamma); - float g = mPow(green, gOneOverGamma); - float b = mPow(blue, gOneOverGamma); + F32 r = mPow(red, gOneOverGamma); + F32 g = mPow(green, gOneOverGamma); + F32 b = mPow(blue, gOneOverGamma); return ColorI(U8(r * 255.0f + 0.5), U8(g * 255.0f + 0.5), U8(b * 255.0f + 0.5), U8(alpha * 255.0f + 0.5)); #else - float r = red < 0.0031308f ? 12.92f * red : 1.055f * mPow(red, 1.0f / 2.4f) - 0.055f; - float g = green < 0.0031308f ? 12.92f * green : 1.055f * mPow(green, 1.0f / 2.4f) - 0.055f; - float b = blue < 0.0031308f ? 12.92f * blue : 1.055f * mPow(blue, 1.0f / 2.4f) - 0.055f; + F32 r = linearChannelToSrgb(red); + F32 g = linearChannelToSrgb(green); + F32 b = linearChannelToSrgb(blue); return ColorI(U8(r * 255.0f + 0.5), U8(g * 255.0f + 0.5), U8(b * 255.0f + 0.5), U8(alpha * 255.0f + 0.5f)); #endif } @@ -823,14 +921,14 @@ inline ColorI LinearColorF::toColorI(const bool keepAsLinear) else { #ifdef TORQUE_USE_LEGACY_GAMMA - float r = mPow(red, gOneOverGamma); - float g = mPow(green, gOneOverGamma); - float b = mPow(blue, gOneOverGamma); + F32 r = mPow(red, gOneOverGamma); + F32 g = mPow(green, gOneOverGamma); + F32 b = mPow(blue, gOneOverGamma); return ColorI(U8(r * 255.0f + 0.5), U8(g * 255.0f + 0.5), U8(b * 255.0f + 0.5), U8(alpha * 255.0f + 0.5)); #else - float r = red < 0.0031308f ? 12.92f * red : 1.055f * mPow(red, 1.0f / 2.4f) - 0.055f; - float g = green < 0.0031308f ? 12.92f * green : 1.055f * mPow(green, 1.0f / 2.4f) - 0.055f; - float b = blue < 0.0031308f ? 12.92f * blue : 1.055f * mPow(blue, 1.0f / 2.4f) - 0.055f; + F32 r = linearChannelToSrgb(red); + F32 g = linearChannelToSrgb(green); + F32 b = linearChannelToSrgb(blue); return ColorI(U8(r * 255.0f + 0.5f), U8(g * 255.0f + 0.5f), U8(b * 255.0f + 0.5f), U8(alpha * 255.0f + 0.5f)); #endif } diff --git a/Engine/source/gui/controls/guiColorPicker.cpp b/Engine/source/gui/controls/guiColorPicker.cpp index d313d3412..1bf3a935a 100644 --- a/Engine/source/gui/controls/guiColorPicker.cpp +++ b/Engine/source/gui/controls/guiColorPicker.cpp @@ -103,7 +103,7 @@ void GuiColorPickerCtrl::initPersistFields() void GuiColorPickerCtrl::renderBlendRange(RectI& bounds) { ColorI currentColor; - currentColor.set(ColorI::Hsb(mSelectedHue, 100, 100)); + currentColor.set(Hsb(mSelectedHue, 100, 100)); GFX->getDrawUtil()->drawRectFill(bounds, currentColor, 0.0f, ColorI(0,0,0,0), true); } @@ -123,7 +123,7 @@ void GuiColorPickerCtrl::renderBlendSelector(RectI& bounds) selectorRect.set(Point2I(selectorPos.x - mSelectorGap, selectorPos.y - mSelectorGap), Point2I(mSelectorGap * 2, mSelectorGap * 2)); ColorI currentColor; - currentColor.set(ColorI::Hsb(mSelectedHue, mSelectedSaturation, mSelectedBrightness)); + currentColor.set(Hsb(mSelectedHue, mSelectedSaturation, mSelectedBrightness)); GFX->getDrawUtil()->drawRectFill(selectorRect, currentColor, 2.0f, ColorI::WHITE); } @@ -145,8 +145,8 @@ void GuiColorPickerCtrl::renderHueGradient(RectI& bounds, U32 numColours) U32 nextHue = static_cast((F32(i + 1) / F32(numColours)) * 360.0f); ColorI currentColor, nextColor; - currentColor.set(ColorI::Hsb(currentHue, 100, 100)); - nextColor.set(ColorI::Hsb(nextHue, 100, 100)); + currentColor.set(Hsb(currentHue, 100, 100)); + nextColor.set(Hsb(nextHue, 100, 100)); switch (mSelectorMode) { @@ -226,7 +226,7 @@ void GuiColorPickerCtrl::renderHueSelector(RectI& bounds) } ColorI currentColor; - currentColor.set(ColorI::Hsb(mSelectedHue, 100, 100)); + currentColor.set(Hsb(mSelectedHue, 100, 100)); GFX->getDrawUtil()->drawRectFill(selectorRect, currentColor, 2.0f, ColorI::WHITE); } @@ -241,7 +241,7 @@ void GuiColorPickerCtrl::renderAlphaGradient(RectI& bounds) S32 b = bounds.point.y + bounds.extent.y; ColorI currentColor; - currentColor.set(ColorI::Hsb(mSelectedHue, 100, 100)); + currentColor.set(Hsb(mSelectedHue, 100, 100)); ColorI alphaCol = ColorI::BLACK; alphaCol.alpha = 0; @@ -317,7 +317,7 @@ void GuiColorPickerCtrl::renderAlphaSelector(RectI& bounds) } ColorI currentColor; - currentColor.set(ColorI::Hsb(mSelectedHue, 100, 100)); + currentColor.set(Hsb(mSelectedHue, 100, 100)); currentColor.alpha = mSelectedAlpha; GFX->getDrawUtil()->drawRectFill(selectorRect, currentColor, 2.0f, ColorI::WHITE); @@ -342,7 +342,7 @@ void GuiColorPickerCtrl::renderEyeDropper() RectI magnifierBounds(magnifierPosition, magnifierSize); ColorI currentColor; - currentColor.set(ColorI::Hsb(mSelectedHue, mSelectedSaturation, mSelectedBrightness)); + currentColor.set(Hsb(mSelectedHue, mSelectedSaturation, mSelectedBrightness)); currentColor.alpha = mSelectedAlpha; GFX->getDrawUtil()->drawRectFill(magnifierBounds, currentColor, 2.0f, ColorI::BLACK); @@ -368,7 +368,7 @@ void GuiColorPickerCtrl::onRender(Point2I offset, const RectI& updateRect) case GuiColorPickerCtrl::pPalette: { ColorI currentColor; - currentColor.set(ColorI::Hsb(mSelectedHue, mSelectedSaturation, mSelectedBrightness)); + currentColor.set(Hsb(mSelectedHue, mSelectedSaturation, mSelectedBrightness)); currentColor.alpha = mSelectedAlpha; GFX->getDrawUtil()->drawRectFill(boundsRect, currentColor); break; @@ -593,7 +593,7 @@ void GuiColorPickerCtrl::onMouseMove(const GuiEvent &event) eyeDropperCap->getColor(eyeDropperPos.x, eyeDropperPos.y, sampledColor); // Convert the sampled color to HSB - ColorI::Hsb hsb = sampledColor.getHSB(); + Hsb hsb = sampledColor.getHSB(); mSelectedHue = hsb.hue; mSelectedSaturation = hsb.sat; mSelectedBrightness = hsb.brightness; @@ -779,7 +779,7 @@ DefineEngineMethod(GuiColorPickerCtrl, getSelectedAlpha, F64, (), , "Gets the cu DefineEngineMethod(GuiColorPickerCtrl, setSelectedColorI, void, (ColorI col), , "Sets the current selected hsb from a colorI value.") { - ColorI::Hsb hsb(col.getHSB()); + Hsb hsb(col.getHSB()); object->setSelectedHue(hsb.hue); object->setSelectedSaturation(hsb.sat); object->setSelectedBrightness(hsb.brightness); @@ -789,26 +789,25 @@ DefineEngineMethod(GuiColorPickerCtrl, setSelectedColorI, void, (ColorI col), , DefineEngineMethod(GuiColorPickerCtrl, getSelectedColorI, ColorI, (), , "Gets the current selected hsb as a colorI value.") { ColorI col; - col.set(ColorI::Hsb(object->getSelectedHue(), object->getSelectedSaturation(), object->getSelectedBrightness())); + col.set(Hsb(object->getSelectedHue(), object->getSelectedSaturation(), object->getSelectedBrightness())); col.alpha = object->getSelectedAlpha(); return col; } DefineEngineMethod(GuiColorPickerCtrl, setSelectedLinearColor, void, (LinearColorF colF), , "Sets the current selected hsb froma a LinearColorF value.") { - ColorI col = colF.toColorI(); - ColorI::Hsb hsb(col.getHSB()); + Hsb hsb = colF.getHSB(); object->setSelectedHue(hsb.hue); object->setSelectedSaturation(hsb.sat); object->setSelectedBrightness(hsb.brightness); - object->setSelectedAlpha(col.alpha); + object->setSelectedAlpha(colF.alpha * 255.0); } DefineEngineMethod(GuiColorPickerCtrl, getSelectedLinearColor, LinearColorF, (), , "Gets the current selected hsb as a LinearColorF value.") { - ColorI col; - col.set(ColorI::Hsb(object->getSelectedHue(), object->getSelectedSaturation(), object->getSelectedBrightness())); - col.alpha = object->getSelectedAlpha(); - return LinearColorF(col); + LinearColorF col; + col.set(Hsb(object->getSelectedHue(), object->getSelectedSaturation(), object->getSelectedBrightness())); + col.alpha = (F32)object->getSelectedAlpha() / 255.0f; + return col; } diff --git a/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui b/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui index 236262deb..e796eb46c 100644 --- a/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui +++ b/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui @@ -109,7 +109,7 @@ $guiContent = new GuiColorPickerCtrl(ColorPickerDlg,EditorGuiGroup) { position = "213 3"; extent = "50 25"; profile = "GuiDefaultProfile"; - command = "%selHue = ColorNewSelected.getSelectedHue();\n%selSat = ColorNewSelected.getSelectedSaturation();\n%selBright = ColorNewSelected.getSelectedBrightness();\n\nHueTextEditor.setText(%selHue);\nSatTextEditor.setText(%selSat);\nBrightTextEditor.setText(%selBright);\n\n%color = ColorNewSelected.getSelectedColorI();\nRedTextEdit.setText(getWord(%color, 0));\nGreenTextEdit.setText(getWord(%color, 1));\nBlueTextEdit.setText(getWord(%color, 2));\nAlphaTextEdit.setText(getWord(%color, 3));\n\n%hex = ColorRGBToHEX(%color);\nHexTextEditor.setText(%hex);"; + command = "%selHue = ColorNewSelected.getSelectedHue();\n%selSat = ColorNewSelected.getSelectedSaturation();\n%selBright = ColorNewSelected.getSelectedBrightness();\n\nHueTextEditor.setText(%selHue);\nSatTextEditor.setText(%selSat);\nBrightTextEditor.setText(%selBright);\n\n%color = $ColorCallbackType == 1 ? ColorNewSelected.getSelectedColorI() : ColorNewSelected.getSelectedLinearColor();\nRedTextEdit.setText(getWord(%color, 0));\nGreenTextEdit.setText(getWord(%color, 1));\nBlueTextEdit.setText(getWord(%color, 2));\nAlphaTextEdit.setText(getWord(%color, 3));\n\n%hex = ColorRGBToHEX(ColorNewSelected.getSelectedColorI());\nHexTextEditor.setText(%hex);"; tooltipProfile = "GuiToolTipProfile"; }; new GuiColorPickerCtrl(ColorOld) { @@ -437,8 +437,12 @@ function ColorPickerRGBClass::onValidate(%this) %alpha = AlphaTextEdit.getValue(); //Update all the other color fields - %hsb = ColorRGBToHSB(%red SPC %green SPC %blue); - + if( $ColorCallbackType == 1) + %hsb = ColorRGBToHSB(%red SPC %green SPC %blue); + else + { + %hsb = ColorLinearRGBToHSB(%red SPC %green SPC %blue); + } // these automatically update our ColorNewSelected which // updates all text fields including these. ColorHueRange.setSelectedHue(getWord(%hsb, 0)); @@ -448,7 +452,7 @@ function ColorPickerRGBClass::onValidate(%this) ColorBlendRange.setSelectedBrightness(getWord(%hsb, 2)); ColorBlendRange.executeUpdate(); - ColorAlphaRange.setSelectedAlpha(%alpha); + ColorAlphaRange.setSelectedAlpha(%alpha * 255.0); ColorAlphaRange.executeUpdate(); } From d06a28041d0cd732bde2322dc9d8b1d9653afca8 Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Thu, 23 Jan 2025 19:22:50 +0000 Subject: [PATCH 4/9] Update colorPicker.ed.gui --- Templates/BaseGame/game/tools/gui/colorPicker.ed.gui | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui b/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui index e796eb46c..082c19b92 100644 --- a/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui +++ b/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui @@ -442,6 +442,7 @@ function ColorPickerRGBClass::onValidate(%this) else { %hsb = ColorLinearRGBToHSB(%red SPC %green SPC %blue); + %alpha *= 255.0 } // these automatically update our ColorNewSelected which // updates all text fields including these. @@ -452,7 +453,7 @@ function ColorPickerRGBClass::onValidate(%this) ColorBlendRange.setSelectedBrightness(getWord(%hsb, 2)); ColorBlendRange.executeUpdate(); - ColorAlphaRange.setSelectedAlpha(%alpha * 255.0); + ColorAlphaRange.setSelectedAlpha(%alpha); ColorAlphaRange.executeUpdate(); } From 7ffb27dab33bd68e7781ffcb96b172ffdc9bf8bc Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Thu, 23 Jan 2025 19:24:11 +0000 Subject: [PATCH 5/9] Update colorPicker.ed.gui --- Templates/BaseGame/game/tools/gui/colorPicker.ed.gui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui b/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui index 082c19b92..af0743a1f 100644 --- a/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui +++ b/Templates/BaseGame/game/tools/gui/colorPicker.ed.gui @@ -442,7 +442,7 @@ function ColorPickerRGBClass::onValidate(%this) else { %hsb = ColorLinearRGBToHSB(%red SPC %green SPC %blue); - %alpha *= 255.0 + %alpha *= 255.0; } // these automatically update our ColorNewSelected which // updates all text fields including these. From 93352f5754654e67dece682f0c697aadd2cfae03 Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Thu, 23 Jan 2025 19:37:15 +0000 Subject: [PATCH 6/9] linear to hsb and back again requires srgb calcs --- Engine/source/core/color.h | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/Engine/source/core/color.h b/Engine/source/core/color.h index b9da6872e..3f69a39e8 100644 --- a/Engine/source/core/color.h +++ b/Engine/source/core/color.h @@ -108,7 +108,7 @@ public: U32 getARGBPack() const; U32 getRGBAPack() const; U32 getABGRPack() const; - Hsb getHSB() const; + Hsb getHSB(); void interpolate(const LinearColorF& in_rC1, const LinearColorF& in_rC2, @@ -504,16 +504,24 @@ inline void LinearColorF::set(const Hsb& color) r = c; g = 0.0; b = x; } - red = static_cast(r + m); - green = static_cast(g + m); - blue = static_cast(b + m); + r += m; + g += m; + b += m; + + red = static_cast(srgbToLinearChannel(r)); + green = static_cast(srgbToLinearChannel(g)); + blue = static_cast(srgbToLinearChannel(b)); alpha = 1.0f; // Default alpha to 1.0 } -inline Hsb LinearColorF::getHSB() const +inline Hsb LinearColorF::getHSB() { - F32 maxVal = mMax( red, mMax(green, blue)); - F32 minVal = mMin(red, mMin(green, blue)); + F32 r = linearChannelToSrgb(red); + F32 g = linearChannelToSrgb(green); + F32 b = linearChannelToSrgb(blue); + + F32 maxVal = mMax(r, mMax(g, b)); + F32 minVal = mMin(r, mMin(g, b)); F32 delta = maxVal - minVal; Hsb hsb; @@ -521,12 +529,12 @@ inline Hsb LinearColorF::getHSB() const hsb.sat = (maxVal > 0.0f) ? (delta / maxVal) * 100.0 : 0.0; if (delta > 0.0f) { - if (red == maxVal) - hsb.hue = 60.0 * mFmod(((green - blue) / delta), 6.0); - else if (green == maxVal) - hsb.hue = 60.0 * (((blue - red) / delta) + 2.0); + if (r == maxVal) + hsb.hue = 60.0 * mFmod(((g - b) / delta), 6.0); + else if (g == maxVal) + hsb.hue = 60.0 * (((b - r) / delta) + 2.0); else - hsb.hue = 60.0 * (((red - green) / delta) + 4.0); + hsb.hue = 60.0 * (((r - g) / delta) + 4.0); if (hsb.hue < 0.0) hsb.hue += 360.0; From 055ca0ae00f11cb793ba0a694ffa089d26d17700 Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Thu, 23 Jan 2025 20:23:47 +0000 Subject: [PATCH 7/9] use screenshot for eye dropper instead of using backbuffer image, use the screenshot so it captures everything --- Engine/source/gfx/D3D11/screenshotD3D11.h | 2 +- Engine/source/gfx/gl/screenshotGL.h | 2 +- Engine/source/gfx/screenshot.h | 7 +++---- Engine/source/gui/controls/guiColorPicker.cpp | 14 ++++---------- 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/Engine/source/gfx/D3D11/screenshotD3D11.h b/Engine/source/gfx/D3D11/screenshotD3D11.h index ce890a473..8822ae933 100644 --- a/Engine/source/gfx/D3D11/screenshotD3D11.h +++ b/Engine/source/gfx/D3D11/screenshotD3D11.h @@ -29,7 +29,7 @@ //************************************************************************** class ScreenShotD3D11 : public ScreenShot { -protected: +public: GBitmap* _captureBackBuffer() override; diff --git a/Engine/source/gfx/gl/screenshotGL.h b/Engine/source/gfx/gl/screenshotGL.h index 442d8bb0f..9fce67b90 100644 --- a/Engine/source/gfx/gl/screenshotGL.h +++ b/Engine/source/gfx/gl/screenshotGL.h @@ -29,7 +29,7 @@ //************************************************************************** class ScreenShotGL : public ScreenShot { -protected: +public: GBitmap* _captureBackBuffer() override; diff --git a/Engine/source/gfx/screenshot.h b/Engine/source/gfx/screenshot.h index 9de224f06..f8b059fae 100644 --- a/Engine/source/gfx/screenshot.h +++ b/Engine/source/gfx/screenshot.h @@ -40,10 +40,6 @@ class Frustum; class ScreenShot { - /// This is overloaded to copy the current GFX - /// backbuffer to a new bitmap. - virtual GBitmap* _captureBackBuffer() { return NULL; } - /// This is set to toggle the capture. bool mPending; @@ -76,6 +72,9 @@ public: ScreenShot(); virtual ~ScreenShot() { } + /// This is overloaded to copy the current GFX + /// backbuffer to a new bitmap. + virtual GBitmap* _captureBackBuffer() { return NULL; } /// Used to start the screenshot capture. void setPending( const char *filename, bool writeJPG, S32 tiles, F32 overlap ); diff --git a/Engine/source/gui/controls/guiColorPicker.cpp b/Engine/source/gui/controls/guiColorPicker.cpp index 1bf3a935a..f3bf4d628 100644 --- a/Engine/source/gui/controls/guiColorPicker.cpp +++ b/Engine/source/gui/controls/guiColorPicker.cpp @@ -30,6 +30,7 @@ #include "gfx/primBuilder.h" #include "gfx/gfxDrawUtil.h" #include "postFx/postEffectManager.h" +#include "gfx/screenshot.h" IMPLEMENT_CONOBJECT(GuiColorPickerCtrl); @@ -707,17 +708,10 @@ void GuiColorPickerCtrl::activateEyeDropper() // Set up our resolution. Point2I resolution = getRoot()->getExtent(); + eyeDropperCap = gScreenShot->_captureBackBuffer(); + // Texture handle to resolve the target to. - eyeHandle.set(resolution.x, resolution.y, GFXFormatR8G8B8A8_SRGB, &GFXRenderTargetSRGBProfile, avar("%s() - bb (line %d)", __FUNCTION__, __LINE__)); - - // Get our active render target (should be backbuffer). - eyeHandle = PFXMGR->getBackBufferTex(); - - if (eyeHandle.isValid()) - { - eyeDropperCap = new GBitmap(eyeHandle.getWidth(), eyeHandle.getHeight(), false, GFXFormatR8G8B8A8); - eyeHandle.copyToBmp(eyeDropperCap); - } + eyeHandle.set(eyeDropperCap, &GFXStaticTextureSRGBProfile, false, avar("%s() - bb (line %d)", __FUNCTION__, __LINE__)); } } From a91ddfffa1ed9433ac26a4e84aac48c582895c18 Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Fri, 24 Jan 2025 08:44:57 +0000 Subject: [PATCH 8/9] fixes for linux According to doc and man pages we should not be using %Lg for a double as %Lg relates to a long double, F64 in torque is just a double so. This also produces better results when going from colorF to the colorPicker dialogue --- Engine/source/console/consoleTypes.cpp | 2 +- Engine/source/core/util/str.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Engine/source/console/consoleTypes.cpp b/Engine/source/console/consoleTypes.cpp index fb9d2049b..429e0ec26 100644 --- a/Engine/source/console/consoleTypes.cpp +++ b/Engine/source/console/consoleTypes.cpp @@ -419,7 +419,7 @@ ConsoleGetType(TypeF64) { static const U32 bufSize = 256; char* returnBuffer = Con::getReturnBuffer(bufSize); - dSprintf(returnBuffer, bufSize, "%Lg", *((F64*)dptr)); + dSprintf(returnBuffer, bufSize, "%g", *((F64*)dptr)); return returnBuffer; } ConsoleSetType(TypeF64) diff --git a/Engine/source/core/util/str.h b/Engine/source/core/util/str.h index 8da5b10bb..827ba0c1f 100644 --- a/Engine/source/core/util/str.h +++ b/Engine/source/core/util/str.h @@ -186,7 +186,7 @@ public: static inline String ToString( U32 v ) { return ToString( "%u", v ); } static inline String ToString( S32 v ) { return ToString( "%d", v ); } static inline String ToString( F32 v ) { return ToString( "%g", v ); } - static inline String ToString( F64 v ) { return ToString( "%Lg", v ); } + static inline String ToString( F64 v ) { return ToString( "%g", v ); } inline operator const char* () { return c_str(); } static String SpanToString(const char* start, const char* end); From 44a6ceab2d9c7ea4412bb23ffa7a13186c316265 Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Mon, 27 Jan 2025 08:04:55 +0000 Subject: [PATCH 9/9] code review Revert Hsb to using integers Clamp drag values --- Engine/source/core/color.h | 8 ++--- Engine/source/gui/controls/guiColorPicker.cpp | 33 +++++++++---------- Engine/source/gui/controls/guiColorPicker.h | 24 +++++++------- 3 files changed, 31 insertions(+), 34 deletions(-) diff --git a/Engine/source/core/color.h b/Engine/source/core/color.h index 3f69a39e8..c3592dec3 100644 --- a/Engine/source/core/color.h +++ b/Engine/source/core/color.h @@ -46,11 +46,11 @@ const F32 gOneOver255 = 1.f / 255.f; struct Hsb { Hsb() :hue(0), sat(0), brightness(0) {}; - Hsb(F64 h, F64 s, F64 b) :hue(h), sat(s), brightness(b) {}; + Hsb(U32 h, U32 s, U32 b) :hue(h), sat(s), brightness(b) {}; - F64 hue; ///Hue - F64 sat; ///Saturation - F64 brightness; //Brightness/Value/Lightness + U32 hue; ///Hue + U32 sat; ///Saturation + U32 brightness; //Brightness/Value/Lightness }; class ColorI; diff --git a/Engine/source/gui/controls/guiColorPicker.cpp b/Engine/source/gui/controls/guiColorPicker.cpp index f3bf4d628..4ec8bdafb 100644 --- a/Engine/source/gui/controls/guiColorPicker.cpp +++ b/Engine/source/gui/controls/guiColorPicker.cpp @@ -514,14 +514,15 @@ void GuiColorPickerCtrl::onMouseDragged(const GuiEvent &event) Point2I ext = getExtent(); Point2I mousePoint = globalToLocalCoord(event.mousePoint); + F32 relX = mClampF(F32(mousePoint.x) / F32(ext.x), 0.0, 1.0); + F32 relY = mClampF(F32(mousePoint.y) / F32(ext.y), 0.0, 1.0); switch (mDisplayMode) { case GuiColorPickerCtrl::pPalette: return; case GuiColorPickerCtrl::pBlendRange: { - F32 relX = F32(mousePoint.x) / F32(ext.x); - F32 relY = 1.0f - F32(mousePoint.y) / F32(ext.y); + relY = 1.0f - relY; setSelectedSaturation(relX * 100.0); setSelectedBrightness(relY * 100.0); break; @@ -532,13 +533,11 @@ void GuiColorPickerCtrl::onMouseDragged(const GuiEvent &event) { case GuiColorPickerCtrl::sHorizontal: { - F32 relX = F32(mousePoint.x) / F32(ext.x); setSelectedHue(relX * 360.0); break; } case GuiColorPickerCtrl::sVertical: { - F32 relY = F32(mousePoint.y) / F32(ext.y); setSelectedHue(relY * 360.0); break; } @@ -553,13 +552,11 @@ void GuiColorPickerCtrl::onMouseDragged(const GuiEvent &event) { case GuiColorPickerCtrl::sHorizontal: { - F32 relX = F32(mousePoint.x) / F32(ext.x); setSelectedAlpha(relX * 255.0); break; } case GuiColorPickerCtrl::sVertical: { - F32 relY = F32(mousePoint.y) / F32(ext.y); setSelectedAlpha(relY * 255.0); break; } @@ -623,7 +620,7 @@ void GuiColorPickerCtrl::onMouseUp(const GuiEvent&) mouseUnlock(); } -void GuiColorPickerCtrl::setSelectedHue(const F64& hueValue) +void GuiColorPickerCtrl::setSelectedHue(const U32& hueValue) { if (hueValue < 0) { @@ -641,7 +638,7 @@ void GuiColorPickerCtrl::setSelectedHue(const F64& hueValue) } -void GuiColorPickerCtrl::setSelectedBrightness(const F64& brightValue) +void GuiColorPickerCtrl::setSelectedBrightness(const U32& brightValue) { if (brightValue < 0) { @@ -658,7 +655,7 @@ void GuiColorPickerCtrl::setSelectedBrightness(const F64& brightValue) mSelectedBrightness = brightValue; } -void GuiColorPickerCtrl::setSelectedSaturation(const F64& satValue) +void GuiColorPickerCtrl::setSelectedSaturation(const U32& satValue) { if (satValue < 0) { @@ -675,7 +672,7 @@ void GuiColorPickerCtrl::setSelectedSaturation(const F64& satValue) mSelectedSaturation = satValue; } -void GuiColorPickerCtrl::setSelectedAlpha(const F64& alphaValue) +void GuiColorPickerCtrl::setSelectedAlpha(const U32& alphaValue) { if (alphaValue < 0) { @@ -731,42 +728,42 @@ DefineEngineMethod(GuiColorPickerCtrl, activateEyeDropper, void, (), , "Activate object->activateEyeDropper(); } -DefineEngineMethod(GuiColorPickerCtrl, setSelectedHue, void, (F64 hueValue), , "Sets the selected hue value should be 0-360.") +DefineEngineMethod(GuiColorPickerCtrl, setSelectedHue, void, (S32 hueValue), , "Sets the selected hue value should be 0-360.") { object->setSelectedHue(hueValue); } -DefineEngineMethod(GuiColorPickerCtrl, getSelectedHue, F64, (), , "Gets the current selected hue value.") +DefineEngineMethod(GuiColorPickerCtrl, getSelectedHue, S32, (), , "Gets the current selected hue value.") { return object->getSelectedHue(); } -DefineEngineMethod(GuiColorPickerCtrl, setSelectedBrightness, void, (F64 brightness), , "Sets the selected brightness value should be 0-100.") +DefineEngineMethod(GuiColorPickerCtrl, setSelectedBrightness, void, (S32 brightness), , "Sets the selected brightness value should be 0-100.") { object->setSelectedBrightness(brightness); } -DefineEngineMethod(GuiColorPickerCtrl, getSelectedBrightness, F64, (), , "Gets the current selected brightness.") +DefineEngineMethod(GuiColorPickerCtrl, getSelectedBrightness, S32, (), , "Gets the current selected brightness.") { return object->getSelectedBrightness(); } -DefineEngineMethod(GuiColorPickerCtrl, setSelectedSaturation, void, (F64 saturation), , "Sets the selected saturation value should be 0-100.") +DefineEngineMethod(GuiColorPickerCtrl, setSelectedSaturation, void, (S32 saturation), , "Sets the selected saturation value should be 0-100.") { object->setSelectedSaturation(saturation); } -DefineEngineMethod(GuiColorPickerCtrl, getSelectedSaturation, F64, (), , "Gets the current selected saturation value.") +DefineEngineMethod(GuiColorPickerCtrl, getSelectedSaturation, S32, (), , "Gets the current selected saturation value.") { return object->getSelectedSaturation(); } -DefineEngineMethod(GuiColorPickerCtrl, setSelectedAlpha, void, (F64 alpha), , "Sets the selected alpha value should be 0-255.") +DefineEngineMethod(GuiColorPickerCtrl, setSelectedAlpha, void, (S32 alpha), , "Sets the selected alpha value should be 0-255.") { object->setSelectedAlpha(alpha); } -DefineEngineMethod(GuiColorPickerCtrl, getSelectedAlpha, F64, (), , "Gets the current selected alpha value.") +DefineEngineMethod(GuiColorPickerCtrl, getSelectedAlpha, S32, (), , "Gets the current selected alpha value.") { return object->getSelectedAlpha(); } diff --git a/Engine/source/gui/controls/guiColorPicker.h b/Engine/source/gui/controls/guiColorPicker.h index 58a8b8302..181065030 100644 --- a/Engine/source/gui/controls/guiColorPicker.h +++ b/Engine/source/gui/controls/guiColorPicker.h @@ -114,10 +114,10 @@ class GuiColorPickerCtrl : public GuiControl /// @{ PickMode mDisplayMode; ///< Current color display mode of the selector SelectorMode mSelectorMode; ///< Current color display mode of the selector - F64 mSelectedHue; - F64 mSelectedSaturation; - F64 mSelectedBrightness; - F64 mSelectedAlpha; + U32 mSelectedHue; + U32 mSelectedSaturation; + U32 mSelectedBrightness; + U32 mSelectedAlpha; Point2I eyeDropperPos; GBitmap* eyeDropperCap; GFXTexHandle eyeHandle; @@ -162,29 +162,29 @@ class GuiColorPickerCtrl : public GuiControl /// Set the selected hue. /// /// Hue value, 0 - 360. - void setSelectedHue(const F64& hueValue); - F64 getSelectedHue() { return mSelectedHue; } + void setSelectedHue(const U32& hueValue); + U32 getSelectedHue() { return mSelectedHue; } /// /// Set the selected brightness. /// /// Brightness value, 0 - 100. - void setSelectedBrightness(const F64& brightValue); - F64 getSelectedBrightness() { return mSelectedBrightness; } + void setSelectedBrightness(const U32& brightValue); + U32 getSelectedBrightness() { return mSelectedBrightness; } /// /// Set the selected saturation. /// /// Saturation value, 0 - 100. - void setSelectedSaturation(const F64& satValue); - F64 getSelectedSaturation() { return mSelectedSaturation; } + void setSelectedSaturation(const U32& satValue); + U32 getSelectedSaturation() { return mSelectedSaturation; } /// /// Set the selected alpha. /// /// Alpha value, 0 - 255. - void setSelectedAlpha(const F64& alphaValue); - F64 getSelectedAlpha() { return mSelectedAlpha; } + void setSelectedAlpha(const U32& alphaValue); + U32 getSelectedAlpha() { return mSelectedAlpha; } void activateEyeDropper();