From 981d463f9cb0333d5a040c6ce81ed585107532a1 Mon Sep 17 00:00:00 2001 From: justburner Date: Oct 22 2022 21:39:25 +0000 Subject: Misc. updates to style editor brush pages --- diff --git a/stuff/config/qss/Blue/Blue.qss b/stuff/config/qss/Blue/Blue.qss index 26d1c49..247677d 100644 --- a/stuff/config/qss/Blue/Blue.qss +++ b/stuff/config/qss/Blue/Blue.qss @@ -1543,6 +1543,13 @@ QStatusBar #StatusBarLabel { #HexagonalColorWheel { qproperty-BGColor: #414345; } +#StyleChooserPage { + qproperty-CommonChipBoxColor: #000000; + qproperty-PinnedChipBoxColor: #a0a0a0; + qproperty-SolidChipBoxColor: #e41000; + qproperty-SelectedChipBoxColor: #ffffff; + qproperty-SelectedChipBox2Color: #c7ca32; +} /* -------------------------------------------------------------------------- */ /* Horizontal QSlider */ #colorSlider::groove:horizontal { diff --git a/stuff/config/qss/Dark/Dark.qss b/stuff/config/qss/Dark/Dark.qss index 391cd43..013d210 100644 --- a/stuff/config/qss/Dark/Dark.qss +++ b/stuff/config/qss/Dark/Dark.qss @@ -1543,6 +1543,13 @@ QStatusBar #StatusBarLabel { #HexagonalColorWheel { qproperty-BGColor: #303030; } +#StyleChooserPage { + qproperty-CommonChipBoxColor: #000000; + qproperty-PinnedChipBoxColor: #a0a0a0; + qproperty-SolidChipBoxColor: #e41000; + qproperty-SelectedChipBoxColor: #ffffff; + qproperty-SelectedChipBox2Color: #c7ca32; +} /* -------------------------------------------------------------------------- */ /* Horizontal QSlider */ #colorSlider::groove:horizontal { diff --git a/stuff/config/qss/Default/Default.qss b/stuff/config/qss/Default/Default.qss index b2b6403..22e6ba0 100644 --- a/stuff/config/qss/Default/Default.qss +++ b/stuff/config/qss/Default/Default.qss @@ -1543,6 +1543,13 @@ QStatusBar #StatusBarLabel { #HexagonalColorWheel { qproperty-BGColor: #484848; } +#StyleChooserPage { + qproperty-CommonChipBoxColor: #000000; + qproperty-PinnedChipBoxColor: #a0a0a0; + qproperty-SolidChipBoxColor: #e41000; + qproperty-SelectedChipBoxColor: #ffffff; + qproperty-SelectedChipBox2Color: #c7ca32; +} /* -------------------------------------------------------------------------- */ /* Horizontal QSlider */ #colorSlider::groove:horizontal { diff --git a/stuff/config/qss/Default/less/Default.less b/stuff/config/qss/Default/less/Default.less index 1349bef..94f8b92 100644 --- a/stuff/config/qss/Default/less/Default.less +++ b/stuff/config/qss/Default/less/Default.less @@ -119,6 +119,13 @@ @palette-CurrentCellColor: fade(@hl-bg-color, 50); @palette-ListNumpadShortcutBorderColor: rgb(175, 175, 175); +// StyleChooserPage Chips +@palette-CommonChipBoxColor: black; +@palette-PinnedChipBoxColor: rgb(160, 160, 160); +@palette-SolidChipBoxColor: rgb(228, 16, 0); +@palette-SelectedChipBoxColor: white; +@palette-SelectedChipBox2Color: rgb(199, 202, 50); + // ----------------------------------------------------------------------------- // Button // ----------------------------------------------------------------------------- diff --git a/stuff/config/qss/Default/less/layouts/palette.less b/stuff/config/qss/Default/less/layouts/palette.less index cd4346c..906063c 100644 --- a/stuff/config/qss/Default/less/layouts/palette.less +++ b/stuff/config/qss/Default/less/layouts/palette.less @@ -18,6 +18,14 @@ qproperty-BGColor: @bg; } +#StyleChooserPage { + qproperty-CommonChipBoxColor: @palette-CommonChipBoxColor; + qproperty-PinnedChipBoxColor: @palette-PinnedChipBorderColor; + qproperty-SolidChipBoxColor: @palette-SolidChipBorderColor; + qproperty-SelectedChipBoxColor: @palette-SelectedChipBorderColor; + qproperty-SelectedChipBox2Color: @palette-SelectedChipBorder2Color; +} + /* -------------------------------------------------------------------------- */ /* Horizontal QSlider */ diff --git a/stuff/config/qss/Default/less/themes/Light.less b/stuff/config/qss/Default/less/themes/Light.less index 2caafa6..3f4ccdd 100644 --- a/stuff/config/qss/Default/less/themes/Light.less +++ b/stuff/config/qss/Default/less/themes/Light.less @@ -126,6 +126,12 @@ // List view @palette-ListNumpadShortcutBorderColor: rgb(105, 105, 105); +// StyleChooserPage Chips +@palette-CommonChipBoxColor: rgb(192, 192, 192); +@palette-PinnedChipBoxColor: rgb(96, 112, 128); +@palette-SolidChipBoxColor: rgb(228, 144, 128); +@palette-SelectedChipBoxColor: black; + // ----------------------------------------------------------------------------- // File Browser / Trees // ----------------------------------------------------------------------------- diff --git a/stuff/config/qss/Default/less/themes/Neutral.less b/stuff/config/qss/Default/less/themes/Neutral.less index f7a9431..472bf48 100644 --- a/stuff/config/qss/Default/less/themes/Neutral.less +++ b/stuff/config/qss/Default/less/themes/Neutral.less @@ -63,6 +63,9 @@ // All views (except list) @palette-NumpadShortcutBorderColor: rgb(190, 190, 190); +// StyleChooserPage Chips +@palette-PinnedChipBoxColor: rgb(64, 80, 96); + // ----------------------------------------------------------------------------- // File Browser / Trees // ----------------------------------------------------------------------------- diff --git a/stuff/config/qss/Light/Light.qss b/stuff/config/qss/Light/Light.qss index 97ff663..f8ba995 100644 --- a/stuff/config/qss/Light/Light.qss +++ b/stuff/config/qss/Light/Light.qss @@ -1543,6 +1543,13 @@ QStatusBar #StatusBarLabel { #HexagonalColorWheel { qproperty-BGColor: #DBDBDB; } +#StyleChooserPage { + qproperty-CommonChipBoxColor: #c0c0c0; + qproperty-PinnedChipBoxColor: #6080a0; + qproperty-SolidChipBoxColor: #e49080; + qproperty-SelectedChipBoxColor: #000000; + qproperty-SelectedChipBox2Color: #c7ca32; +}} /* -------------------------------------------------------------------------- */ /* Horizontal QSlider */ #colorSlider::groove:horizontal { diff --git a/stuff/config/qss/Neutral/Neutral.qss b/stuff/config/qss/Neutral/Neutral.qss index 49d1094..abdd84e 100644 --- a/stuff/config/qss/Neutral/Neutral.qss +++ b/stuff/config/qss/Neutral/Neutral.qss @@ -1543,6 +1543,13 @@ QStatusBar #StatusBarLabel { #HexagonalColorWheel { qproperty-BGColor: #808080; } +#StyleChooserPage { + qproperty-CommonChipBoxColor: #000000; + qproperty-PinnedChipBoxColor: #405060; + qproperty-SolidChipBoxColor: #e41000; + qproperty-SelectedChipBoxColor: #ffffff; + qproperty-SelectedChipBox2Color: #c7ca32; +} /* -------------------------------------------------------------------------- */ /* Horizontal QSlider */ #colorSlider::groove:horizontal { diff --git a/stuff/library/textures/Denim2_s.bmp b/stuff/library/textures/Denim2_s.bmp index b1813aa..6cfd577 100644 Binary files a/stuff/library/textures/Denim2_s.bmp and b/stuff/library/textures/Denim2_s.bmp differ diff --git a/stuff/library/textures/Knit_s.bmp b/stuff/library/textures/Knit_s.bmp index d7f9b7e..97fa5ba 100644 Binary files a/stuff/library/textures/Knit_s.bmp and b/stuff/library/textures/Knit_s.bmp differ diff --git a/stuff/library/textures/papercrump.bmp b/stuff/library/textures/papercrump.bmp index 7b6f039..7f22a3e 100644 Binary files a/stuff/library/textures/papercrump.bmp and b/stuff/library/textures/papercrump.bmp differ diff --git a/stuff/library/textures/snakeskin.bmp b/stuff/library/textures/snakeskin.bmp index edb5dfa..65321c7 100644 Binary files a/stuff/library/textures/snakeskin.bmp and b/stuff/library/textures/snakeskin.bmp differ diff --git a/stuff/library/textures/snakeskinred.bmp b/stuff/library/textures/snakeskinred.bmp index d2cc8f6..eff6ec7 100644 Binary files a/stuff/library/textures/snakeskinred.bmp and b/stuff/library/textures/snakeskinred.bmp differ diff --git a/stuff/library/textures/snow.bmp b/stuff/library/textures/snow.bmp index 0602c5f..204665e 100644 Binary files a/stuff/library/textures/snow.bmp and b/stuff/library/textures/snow.bmp differ diff --git a/stuff/library/textures/wornleather.bmp b/stuff/library/textures/wornleather.bmp index 044f5c0..8ad5a5e 100644 Binary files a/stuff/library/textures/wornleather.bmp and b/stuff/library/textures/wornleather.bmp differ diff --git a/toonz/sources/colorfx/rasterstyles.h b/toonz/sources/colorfx/rasterstyles.h index 797fd35..febe382 100644 --- a/toonz/sources/colorfx/rasterstyles.h +++ b/toonz/sources/colorfx/rasterstyles.h @@ -57,6 +57,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TAirbrushRasterStyle", "Airbrush"); } + std::string getBrushIdName() const override { return "AirbrushRasterStyle"; } int getParamCount() const override { return 1; } TColorStyle::ParamType getParamType(int index) const override { @@ -121,6 +122,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TBlendRasterStyle", "Blend"); } + std::string getBrushIdName() const override { return "BlendRasterStyle"; } void makeIcon(const TDimension &d) override; @@ -150,6 +152,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TNoColorRasterStyle", "Markup"); } + std::string getBrushIdName() const override { return "NoColorRasterStyle"; } bool hasMainColor() { return false; } // TPixel32 getMainColor() const {return m_color;} diff --git a/toonz/sources/colorfx/regionstyles.h b/toonz/sources/colorfx/regionstyles.h index a9e8882..fe59156 100644 --- a/toonz/sources/colorfx/regionstyles.h +++ b/toonz/sources/colorfx/regionstyles.h @@ -72,6 +72,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("MovingSolidColor", "Offset"); } + std::string getBrushIdName() const override { return "MovingSolidColor"; } void drawRegion(const TColorFunction *cf, const bool antiAliasing, TRegionOutline &boundary) const override; @@ -119,6 +120,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("ShadowStyle", "Hatched Shading"); } + std::string getBrushIdName() const override { return "ShadowStyle"; } void drawRegion(const TColorFunction *cf, const bool antiAliasing, TRegionOutline &boundary) const override; @@ -168,6 +170,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("ShadowStyle2", "Plain Shadow"); } + std::string getBrushIdName() const override { return "ShadowStyle2"; } void drawRegion(const TColorFunction *cf, const bool antiAliasing, TRegionOutline &boundary) const override; @@ -229,6 +232,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TRubberFillStyle", "Blob"); } + std::string getBrushIdName() const override { return "RubberFillStyle"; } void drawRegion(const TColorFunction *cf, const bool antiAliasing, TRegionOutline &boundary) const override; @@ -283,6 +287,7 @@ void setMainColor(const TPixel32 &color){ m_shadowColor=color; } return QCoreApplication::translate("TPointShadowFillStyle", "Sponge Shading"); } + std::string getBrushIdName() const override { return "PointShadowFillStyle"; } void drawRegion(const TColorFunction *cf, const bool antiAliasing, TRegionOutline &boundary) const override; @@ -345,6 +350,7 @@ void setMainColor(const TPixel32 &color){ m_pointColor=color; } QString getDescription() const override { return QCoreApplication::translate("TDottedFillStyle", "Polka Dots"); } + std::string getBrushIdName() const override { return "DottedFillStyle"; } protected: void loadData(TInputStreamInterface &is) override; @@ -398,6 +404,7 @@ void setMainColor(const TPixel32 &color){ m_pointColor=color; } QString getDescription() const override { return QCoreApplication::translate("TCheckedFillStyle", "Square"); } + std::string getBrushIdName() const override { return "CheckedFillStyle"; } private: void getHThickline(const TPointD &lc, const double lx, TPointD &p0, @@ -459,6 +466,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("ArtisticSolidColor", "Irregular"); } + std::string getBrushIdName() const override { return "ArtisticSolidColor"; } void drawRegion(const TColorFunction *cf, const bool antiAliasing, TRegionOutline &boundary) const override; @@ -507,6 +515,8 @@ void setMainColor(const TPixel32 &color){ m_color0=color; } QString getDescription() const override { return QCoreApplication::translate("TChalkFillStyle", "Chalk"); } + std::string getBrushIdName() const override { return "ChalkFillStyle"; } + void loadData(int oldId, TInputStreamInterface &) override; void getObsoleteTagIds(std::vector &ids) const override { ids.push_back(1133); @@ -558,6 +568,7 @@ void setMainColor(const TPixel32 &color){ m_pointColor=color; } QString getDescription() const override { return QCoreApplication::translate("TChessFillStyle", "Chessboard"); } + std::string getBrushIdName() const override { return "ChessFillStyle"; } protected: void loadData(TInputStreamInterface &is) override; @@ -609,6 +620,7 @@ void setMainColor(const TPixel32 &color){ m_pointColor=color; } QString getDescription() const override { return QCoreApplication::translate("TStripeFillStyle", "Banded"); } + std::string getBrushIdName() const override { return "StripeFillStyle"; } protected: void loadData(TInputStreamInterface &is) override; @@ -664,6 +676,7 @@ void setMainColor(const TPixel32 &color){ m_pointColor=color; } QString getDescription() const override { return QCoreApplication::translate("TLinGradFillStyle", "Linear Gradient"); } + std::string getBrushIdName() const override { return "LinGradFillStyle"; } protected: void loadData(TInputStreamInterface &is) override; @@ -717,6 +730,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TRadGradFillStyle", "Radial Gradient"); } + std::string getBrushIdName() const override { return "RadGradFillStyle"; } protected: void loadData(TInputStreamInterface &is) override; @@ -765,6 +779,9 @@ void setMainColor(const TPixel32 &color){ m_pointColor=color; } QString getDescription() const override { return QCoreApplication::translate("TCircleStripeFillStyle", "Concentric"); } + std::string getBrushIdName() const override { + return "CircleStripeFillStyle"; + } protected: void loadData(TInputStreamInterface &is) override; @@ -821,6 +838,7 @@ void setMainColor(const TPixel32 &color){ m_pointColor[0]=color; } QString getDescription() const override { return QCoreApplication::translate("TMosaicFillStyle", "Stained Glass"); } + std::string getBrushIdName() const override { return "MosaicFillStyle"; } protected: void loadData(TInputStreamInterface &is) override; @@ -871,6 +889,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TPatchFillStyle", "Beehive"); } + std::string getBrushIdName() const override { return "PatchFillStyle"; } private: void preaprePos(const TRectD &box, std::vector &v, int &lX, int &lY, diff --git a/toonz/sources/colorfx/strokestyles.h b/toonz/sources/colorfx/strokestyles.h index 6337f47..6658a45 100644 --- a/toonz/sources/colorfx/strokestyles.h +++ b/toonz/sources/colorfx/strokestyles.h @@ -90,6 +90,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TFurStrokeStyle", "Herringbone"); } + std::string getBrushIdName() const override { return "FurStrokeStyle"; } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -132,6 +133,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TChainStrokeStyle", "Chain"); } + std::string getBrushIdName() const override { return "ChainStrokeStyle"; } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -163,6 +165,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TSprayStrokeStyle", "Circlets"); } + std::string getBrushIdName() const override { return "SprayStrokeStyle"; } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -205,6 +208,9 @@ public: QString getDescription() const override { return QCoreApplication::translate("TGraphicPenStrokeStyle", "Dashes"); } + std::string getBrushIdName() const override { + return "GraphicPenStrokeStyle"; + } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -253,6 +259,9 @@ public: QString getDescription() const override { return QCoreApplication::translate("TDottedLineStrokeStyle", "Vanishing"); } + std::string getBrushIdName() const override { + return "DottedLineStrokeStyle"; + } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -298,6 +307,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TRopeStrokeStyle", "Rope"); } + std::string getBrushIdName() const override { return "RopeStrokeStyle"; } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -341,6 +351,9 @@ public: QString getDescription() const override { return QCoreApplication::translate("TCrystallizeStrokeStyle", "Tulle"); } + std::string getBrushIdName() const override { + return "CrystallizeStrokeStyle"; + } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -384,6 +397,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TBraidStrokeStyle", "Plait"); } + std::string getBrushIdName() const override { return "BraidStrokeStyle"; } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_colors[0]; } @@ -432,6 +446,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TSketchStrokeStyle", "Fuzz"); } + std::string getBrushIdName() const override { return "SketchStrokeStyle"; } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -474,6 +489,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TBubbleStrokeStyle", "Bubbles"); } + std::string getBrushIdName() const override { return "BubbleStrokeStyle"; } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color0; } @@ -529,6 +545,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TTissueStrokeStyle", "Gauze"); } + std::string getBrushIdName() const override { return "TissueStrokeStyle"; } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -576,6 +593,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TBiColorStrokeStyle", "Shade"); } + std::string getBrushIdName() const override { return "BiColorStrokeStyle"; } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color0; } @@ -628,6 +646,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TNormal2StrokeStyle", "Bump"); } + std::string getBrushIdName() const override { return "Normal2StrokeStyle"; } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -671,6 +690,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TChalkStrokeStyle2", "Chalk"); } + std::string getBrushIdName() const override { return "ChalkStrokeStyle2"; } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -724,6 +744,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TBlendStrokeStyle2", "Fade"); } + std::string getBrushIdName() const override { return "BlendStrokeStyle2"; } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -774,6 +795,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TTwirlStrokeStyle", "Ribbon"); } + std::string getBrushIdName() const override { return "TwirlStrokeStyle"; } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -826,6 +848,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TSawToothStrokeStyle", "Jagged"); } + std::string getBrushIdName() const override { return "SawToothStrokeStyle"; } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -871,6 +894,9 @@ public: QString getDescription() const override { return QCoreApplication::translate("TMultiLineStrokeStyle2", "Gouache"); } + std::string getBrushIdName() const override { + return "MultiLineStrokeStyle2"; + } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color0; } @@ -941,6 +967,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TZigzagStrokeStyle", "Zigzag"); } + std::string getBrushIdName() const override { return "ZigzagStrokeStyle"; } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -989,6 +1016,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TSinStrokeStyle", "Wave"); } + std::string getBrushIdName() const override { return "SinStrokeStyle"; } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -1028,6 +1056,7 @@ public: QString getDescription() const override { return QCoreApplication::translate("TFriezeStrokeStyle2", "Curl"); } + std::string getBrushIdName() const override { return "FriezeStrokeStyle2"; } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -1089,6 +1118,9 @@ public: QString getDescription() const override { return QCoreApplication::translate("TDualColorStrokeStyle2", "Striped"); } + std::string getBrushIdName() const override { + return "DualColorStrokeStyle2"; + } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color0; } @@ -1151,6 +1183,9 @@ public: QString getDescription() const override { return QCoreApplication::translate("TLongBlendStrokeStyle2", "Watercolor"); } + std::string getBrushIdName() const override { + return "LongBlendStrokeStyle2"; + } bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color0; } @@ -1240,6 +1275,7 @@ public: return QCoreApplication::translate("OutlineViewerStyle", "OutlineViewer(OnlyDebug)"); } + std::string getBrushIdName() const override { return "OutlineViewerStyle"; } int getTagId() const override { return 99; }; }; @@ -1303,6 +1339,8 @@ public: QString getDescription() const override { return QCoreApplication::translate("TMatrioskaStrokeStyle", "Toothpaste"); } + std::string getBrushIdName() const override { return "MatrioskaStrokeStyle"; } + int getTagId() const override { return 141; }; }; diff --git a/toonz/sources/common/tvrender/tcolorstyles.cpp b/toonz/sources/common/tvrender/tcolorstyles.cpp index 9a8cfee..a0c2588 100644 --- a/toonz/sources/common/tvrender/tcolorstyles.cpp +++ b/toonz/sources/common/tvrender/tcolorstyles.cpp @@ -50,6 +50,7 @@ TColorStyle::TColorStyle() , m_icon(0) , m_validIcon(false) , m_isEditedFromOriginal(false) + , m_hash(0) , m_pickedPosition() {} //------------------------------------------------------------------- @@ -67,6 +68,7 @@ TColorStyle::TColorStyle(const TColorStyle &other) , m_enabled(other.m_enabled) , m_validIcon(false) , m_isEditedFromOriginal(other.m_isEditedFromOriginal) + , m_hash(other.m_hash) , m_pickedPosition(other.m_pickedPosition) {} //------------------------------------------------------------------- @@ -80,6 +82,7 @@ TColorStyle &TColorStyle::operator=(const TColorStyle &other) { m_enabled = other.m_enabled; m_validIcon = false; m_isEditedFromOriginal = other.m_isEditedFromOriginal; + m_hash = other.m_hash; m_pickedPosition = other.m_pickedPosition; return *this; @@ -138,6 +141,13 @@ bool TColorStyle::operator==(const TColorStyle &cs) const { //------------------------------------------------------------------- +QString TColorStyle::getDescription() const { + assert(false); + return QString(""); +} + +//------------------------------------------------------------------- + QString TColorStyle::getParamNames(int index) const { assert(false); return QString(""); @@ -422,6 +432,23 @@ public: return it->second.m_style->clone(); } + TColorStyle *create(std::string brushIdName) { + int index = brushIdName.find(':'); + std::string brushIdCategory = + (index != -1) ? brushIdName.substr(0, index) : brushIdName; + + for (auto &table : m_table) { + std::string name = table.second.m_style->getBrushIdName(); + int index = name.find(':'); + if (index != -1 && brushIdCategory == name.substr(0, index)) { + return table.second.m_style->clone(brushIdName); + } else if (index == -1 && brushIdCategory == name) { + return table.second.m_style->clone(brushIdName); + } + } + return nullptr; + } + void getAllTags(std::vector &tags) { tags.clear(); tags.reserve(m_table.size()); @@ -572,6 +599,56 @@ TColorStyle *TColorStyle::create(int tagId) { //------------------------------------------------------------------- +TColorStyle *TColorStyle::create(std::string brushIdName) { + return ColorStyleList::instance()->create(brushIdName); +} + +//------------------------------------------------------------------- + void TColorStyle::getAllTags(std::vector &tags) { ColorStyleList::instance()->getAllTags(tags); } + +//------------------------------------------------------------------- + +std::string TColorStyle::getBrushIdName() const { + assert(false); + return "InvalidStyle"; +} + +//------------------------------------------------------------------- + +std::size_t TColorStyle::generateHash(std::string brushIdName) { + std::hash hasher; + std::size_t v_hash = hasher(brushIdName); + return v_hash; +} + +//------------------------------------------------------------------- + +std::size_t TColorStyle::getBrushIdHash() { + if (m_hash) return m_hash; + + std::hash hasher; + std::string brushId = getBrushIdName(); + m_hash = hasher(brushId); + return m_hash; +} + +//------------------------------------------------------------------- + +std::string TColorStyle::getBrushIdNameClass(std::string brushIdName) { + int index = brushIdName.find(':'); + if (index >= 0) return brushIdName.substr(0, index); + return brushIdName; +} + +//------------------------------------------------------------------- + +std::string TColorStyle::getBrushIdNameParam(std::string brushIdName) { + int index = brushIdName.find(':'); + if (index < 0) return ""; + return brushIdName.substr(index + 1); +} + +//------------------------------------------------------------------- diff --git a/toonz/sources/common/tvrender/tsimplecolorstyles.cpp b/toonz/sources/common/tvrender/tsimplecolorstyles.cpp index 349a8bf..2c68ad9 100644 --- a/toonz/sources/common/tvrender/tsimplecolorstyles.cpp +++ b/toonz/sources/common/tvrender/tsimplecolorstyles.cpp @@ -132,9 +132,9 @@ public: next_stage(x, y, z); else { if (stage == 2) next_stage(x, y, z); - double l = fabs(ax + bx) > 1e-9 - ? -(ay - by) / (ax + bx) - : fabs(ay + by) > 1e-9 ? (ax - bx) / (ay + by) : 0.0; + double l = fabs(ax + bx) > 1e-9 ? -(ay - by) / (ax + bx) + : fabs(ay + by) > 1e-9 ? (ax - bx) / (ay + by) + : 0.0; if (fabs(l) > maxl || fabs(l) < 1.0 || l > 0.0) { vertices.resize(vertices.size() + 12); double *p = &vertices.back() - 11; @@ -723,6 +723,19 @@ QString TSolidColorStyle::getDescription() const { return "SolidColorStyle"; } //----------------------------------------------------------------------------- +std::string TSolidColorStyle::getBrushIdName() const { + return "SolidColorStyle"; +} + +//----------------------------------------------------------------------------- + +std::size_t TSolidColorStyle::staticBrushIdHash() { + static std::size_t bidHash = TColorStyle::generateHash("SolidColorStyle"); + return bidHash; +} + +//----------------------------------------------------------------------------- + int TSolidColorStyle::getTagId() const { return 3; } //----------------------------------------------------------------------------- @@ -888,6 +901,12 @@ QString TCenterLineStrokeStyle::getDescription() const { //----------------------------------------------------------------------------- +std::string TCenterLineStrokeStyle::getBrushIdName() const { + return "CenterLineStrokeStyle"; +} + +//----------------------------------------------------------------------------- + int TCenterLineStrokeStyle::getTagId() const { return 2; } //----------------------------------------------------------------------------- @@ -969,6 +988,29 @@ TColorStyle *TRasterImagePatternStrokeStyle::clone() const { //----------------------------------------------------------------------------- +TColorStyle *TRasterImagePatternStrokeStyle::clone( + std::string brushIdName) const { + TRasterImagePatternStrokeStyle *style = + new TRasterImagePatternStrokeStyle(*this); + std::string patternName = getBrushIdNameParam(brushIdName); + if (patternName != "") style->loadLevel(patternName); + return style; +} + +//----------------------------------------------------------------------------- + +QString TRasterImagePatternStrokeStyle::getDescription() const { + return "TRasterImagePatternStrokeStyle"; +} + +//----------------------------------------------------------------------------- + +std::string TRasterImagePatternStrokeStyle::getBrushIdName() const { + return "RasterImagePatternStrokeStyle:" + m_name; +} + +//----------------------------------------------------------------------------- + void TRasterImagePatternStrokeStyle::makeIcon(const TDimension &size) { if (!m_level) loadLevel(m_name); m_icon = TRaster32P(); @@ -1366,6 +1408,29 @@ TColorStyle *TVectorImagePatternStrokeStyle::clone() const { //----------------------------------------------------------------------------- +TColorStyle *TVectorImagePatternStrokeStyle::clone( + std::string brushIdName) const { + TVectorImagePatternStrokeStyle *style = + new TVectorImagePatternStrokeStyle(*this); + std::string patternName = getBrushIdNameParam(brushIdName); + if (patternName != "") style->loadLevel(patternName); + return style; +} + +//----------------------------------------------------------------------------- + +QString TVectorImagePatternStrokeStyle::getDescription() const { + return "TVectorImagePatternStrokeStyle"; +} + +//----------------------------------------------------------------------------- + +std::string TVectorImagePatternStrokeStyle::getBrushIdName() const { + return "VectorImagePatternStrokeStyle:" + m_name; +} + +//----------------------------------------------------------------------------- + void TVectorImagePatternStrokeStyle::makeIcon(const TDimension &size) { TLevel::Iterator frameIt = m_level->begin(); if (frameIt == m_level->end()) { diff --git a/toonz/sources/common/tvrender/tvectorbrushstyle.cpp b/toonz/sources/common/tvrender/tvectorbrushstyle.cpp index bd1d44a..9f58e92 100644 --- a/toonz/sources/common/tvrender/tvectorbrushstyle.cpp +++ b/toonz/sources/common/tvrender/tvectorbrushstyle.cpp @@ -229,10 +229,26 @@ TColorStyle *TVectorBrushStyle::clone() const { //----------------------------------------------------------------- +TColorStyle *TVectorBrushStyle::clone(std::string brushIdName) const { + std::string patternName = getBrushIdNameParam(brushIdName); + TVectorBrushStyle *theClone = new TVectorBrushStyle(patternName); + theClone->assignNames(this); + theClone->setFlags(getFlags()); + return theClone; +} + +//----------------------------------------------------------------- + QString TVectorBrushStyle::getDescription() const { return "VectorBrushStyle"; } //----------------------------------------------------------------- +std::string TVectorBrushStyle::getBrushIdName() const { + return "VectorBrushStyle:" + m_brushName; +} + +//----------------------------------------------------------------------------- + TStrokeProp *TVectorBrushStyle::makeStrokeProp(const TStroke *stroke) { return new VectorBrushProp(stroke, this); } @@ -346,7 +362,7 @@ TPixel32 TVectorBrushStyle::getColorParamValue(int index) const { TPalette *pal = m_brush->getPalette(); assert(pal); - int styleId = getColorStyleId(index); + int styleId = getColorStyleId(index); if (styleId < 0) styleId = 1; return pal->getStyle(styleId)->getMainColor(); @@ -358,7 +374,7 @@ void TVectorBrushStyle::setColorParamValue(int index, const TPixel32 &color) { TPalette *pal = m_brush->getPalette(); assert(pal); - int styleId = getColorStyleId(index); + int styleId = getColorStyleId(index); if (styleId < 0) styleId = 1; return pal->getStyle(styleId)->setMainColor(color); diff --git a/toonz/sources/include/tcolorstyles.h b/toonz/sources/include/tcolorstyles.h index 40a298f..f30f46b 100644 --- a/toonz/sources/include/tcolorstyles.h +++ b/toonz/sources/include/tcolorstyles.h @@ -133,6 +133,8 @@ private: m_pickedPosition; // picked position from color model by using style // picker tool with "organize palette" option. + std::size_t m_hash; //!< Hash value for quick comparison. + protected: TRaster32P m_icon; //!< Icon shown on TPalette viewers. bool m_validIcon; //!< Icon's validity status. @@ -147,6 +149,7 @@ public: virtual ~TColorStyle(); virtual TColorStyle *clone() const = 0; //!< Polymorphic clone of the style. + virtual TColorStyle *clone(std::string brushIdName) const { return clone(); } virtual TColorStyle ©( const TColorStyle &other) //!< Polymorphic copy of the style. { @@ -363,10 +366,21 @@ For example for a stroke style we have "Constant", "Chain", "Rope", "Tulle", etc... */ virtual QString getDescription() - const = 0; //!< Return a brief description of the style. + const; //!< Return a brief description of the style. virtual QString getParamNames(int index) const; //!< Return the string that identifies the \a index-th parameter. + virtual std::string getBrushIdName() + const; //!< Return a name identifying the brush. + + static std::size_t generateHash(std::string brushIdName); + std::size_t getBrushIdHash(); //!< Hash for quick comparison (cached). + + static std::string getBrushIdNameClass( + std::string brushIdName); //!< Get class inside brush id name + static std::string getBrushIdNameParam( + std::string brushIdName); //!< Get parameter inside brush id name + // I/O-related functions virtual int getTagId() @@ -375,15 +389,15 @@ etc... void save(TOutputStreamInterface &) const; //!< Calls the local //! implementation of saveData() - //! passing it also the name and - //! the tagId of the style. + //! passing it also the name and the tagId of the style. + static TColorStyle *load(TInputStreamInterface &); //!< Loads the style from //! disk. Calls the local - //! implementation of - //! loadData(). + //! implementation of loadData(). static TColorStyle *create( int tagId); //!< Creates a new style with identifier equal to \a tagId. + static TColorStyle *create(std::string brushIdName); static void declare( TColorStyle *style); //!< Puts the style in the table of actual styles. diff --git a/toonz/sources/include/toonz/imagestyles.h b/toonz/sources/include/toonz/imagestyles.h index fc4c913..9e84125 100644 --- a/toonz/sources/include/toonz/imagestyles.h +++ b/toonz/sources/include/toonz/imagestyles.h @@ -132,7 +132,11 @@ public: void setColorParamValue(int index, const TPixel32 &color) override; TColorStyle *clone() const override; + TColorStyle *clone(std::string brushIdName) const override; + QString getDescription() const override; + std::string getBrushIdName() const override; + static std::string staticBrushIdName(std::wstring texturePath); bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_averageColor; } diff --git a/toonz/sources/include/toonz/mypaintbrushstyle.h b/toonz/sources/include/toonz/mypaintbrushstyle.h index 05a3998..64357ca 100644 --- a/toonz/sources/include/toonz/mypaintbrushstyle.h +++ b/toonz/sources/include/toonz/mypaintbrushstyle.h @@ -44,6 +44,7 @@ public: ~TMyPaintBrushStyle(); TColorStyle *clone() const override { return new TMyPaintBrushStyle(*this); } + TColorStyle *clone(std::string brushIdName) const override; TColorStyle ©(const TColorStyle &other) override; @@ -70,6 +71,7 @@ public: int getTagId() const override { return 4001; } QString getDescription() const override; + std::string getBrushIdName() const override; void setBaseValue(MyPaintBrushSetting id, bool enable, float value); void resetBaseValues(); diff --git a/toonz/sources/include/toonz/stylemanager.h b/toonz/sources/include/toonz/stylemanager.h index 5c655d7..bc8a27e 100644 --- a/toonz/sources/include/toonz/stylemanager.h +++ b/toonz/sources/include/toonz/stylemanager.h @@ -6,9 +6,15 @@ #include "tfilepath.h" #include "tthread.h" +#include "traster.h" +#include "toonz/mypaintbrushstyle.h" + #include +#include #include +#include #include +#include #undef DVAPI #undef DVVAR @@ -20,63 +26,202 @@ #define DVVAR DV_IMPORT_VAR #endif -//------------------------------------------------------------------------- +//******************************************************************************** +// FavoritesManager declaration +//******************************************************************************** + +class DVAPI FavoritesManager : public QObject { + Q_OBJECT + + TFilePath m_fpPinsToTop; + QVector m_pinsToTop; + bool m_xxPinsToTop; // dirty pins-to-top + + FavoritesManager(); + +public: + static FavoritesManager *instance(); + + bool loadPinsToTop(); + void savePinsToTop(); -// Forward declarations -class QImage; + const QVector &getAllPinsToTop() const { return m_pinsToTop; } -//------------------------------------------------------------------------- + bool getPinToTop(std::string idname) const; + void setPinToTop(std::string idname, bool state); + void togglePinToTop(std::string idname); + + void emitPinsToTopChange() { emit pinsToTopChanged(); } + +signals: + void pinsToTopChanged(); +}; //******************************************************************************** -// CustomStyleManager declaration +// BaseStyleManager declaration //******************************************************************************** -class DVAPI CustomStyleManager final : public QObject { +class DVAPI BaseStyleManager : public QObject { Q_OBJECT public: - struct DVAPI PatternData { - QImage *m_image; - std::string m_patternName; - bool m_isVector; - - PatternData() : m_image(0), m_patternName(""), m_isVector(false) {} + struct DVAPI ChipData { + QString name; // chip name + QString desc; // chip description + QImage image; // preview image + int tagId; // tagID + bool isVector; // is a vector? + TRasterP raster; // raster data + std::string idname; // brush id name + std::size_t hash; // hash for fast compare with current style + + bool markPinToTop; // Pin To Top + bool markFavorite; // Favorite + + ChipData(QString name = "", QString description = "", + QImage image = QImage(), int tagId = 0, bool isVector = false, + TRasterP raster = TRasterP(), std::string idname = "", + std::size_t hash = 0) + : name(name) + , desc(description) + , image(image) + , tagId(tagId) + , isVector(isVector) + , raster(raster) + , idname(idname) + , hash(hash) + , markPinToTop(false) + , markFavorite(false) {} }; - class StyleLoaderTask; - friend class CustomStyleManager::StyleLoaderTask; - -private: - QList m_patterns; +protected: TFilePath m_rootPath; TFilePath m_stylesFolder; QString m_filters; QSize m_chipSize; + bool m_loaded; - TThread::Executor m_executor; - bool m_started; + QVector m_chips; + + bool m_isIndexed; + QList m_indexes; + QString m_searchText; + + static TFilePath s_rootPath; + static ChipData s_emptyChipData; public: - CustomStyleManager(const TFilePath &stylesFolder, QString filters = QString(), - QSize chipSize = QSize(30, 30)); + BaseStyleManager(const TFilePath &stylesFolder, QString filters = QString(), + QSize chipSize = QSize(25, 25)); const TFilePath &stylesFolder() const { return m_stylesFolder; } QSize getChipSize() const { return m_chipSize; } - - int getPatternCount(); - PatternData getPattern(int index); + QString getFilters() const { return m_filters; } + + int countData() const { + return m_isIndexed ? m_indexes.count() : m_chips.count(); + } + int getIndex(int index) const { + return m_isIndexed ? m_indexes[index] : index; + } + const ChipData &getData(int index) const; + + void applyFilter(); + void applyFilter(const QString text) { + m_searchText = text; + applyFilter(); + } + QString getSearchText() const { return m_searchText; } + + bool isLoaded() { return m_loaded; } + virtual void loadItems() = 0; static TFilePath getRootPath(); static void setRootPath(const TFilePath &rootPath); +}; + +//******************************************************************************** +// CustomStyleManager declaration +//******************************************************************************** + +class DVAPI CustomStyleManager final : public BaseStyleManager { + Q_OBJECT + + TThread::Executor m_executor; + bool m_started; + + std::string m_rasterIdName; + std::string m_vectorIdName; + +public: + CustomStyleManager(std::string rasterIdName, std::string vectorIdName, + const TFilePath &stylesFolder, QString filters = QString(), + QSize chipSize = QSize(25, 25)); - void loadItems(); + void loadItems() override; + + class StyleLoaderTask; + friend class CustomStyleManager::StyleLoaderTask; private: - void addPattern(const TFilePath &path); + QImage makeIcon(const TFilePath &path, const QSize &qChipSize, + std::shared_ptr offsurf); -signals: + ChipData createPattern(const TFilePath &path, + std::shared_ptr offsurf); +signals: void patternAdded(); }; +//******************************************************************************** +// TextureStyleManager declaration +//******************************************************************************** + +class DVAPI TextureStyleManager final : public BaseStyleManager { + Q_OBJECT + +public: + TextureStyleManager(const TFilePath &stylesFolder, + QSize chipSize = QSize(25, 25)); + + void loadItems() override; + +private: + void loadTexture(const TFilePath &fp); +}; + +//******************************************************************************** +// MyPaintBrushStyleManager declaration +//******************************************************************************** + +class DVAPI MyPaintBrushStyleManager final : public BaseStyleManager { + Q_OBJECT + + std::vector m_brushes; + +public: + MyPaintBrushStyleManager(QSize chipSize = QSize(25, 25)); + + TMyPaintBrushStyle &getBrush(int index) { + assert(0 <= index && index < countData()); + return m_brushes[getIndex(index)]; + } + + void loadItems() override; +}; + +//******************************************************************************** +// SpecialStyleManager declaration +//******************************************************************************** + +class DVAPI SpecialStyleManager final : public BaseStyleManager { + Q_OBJECT + +public: + SpecialStyleManager(QSize chipSize = QSize(25, 25)); + + void loadItems() override; +}; + #endif // STYLEMANAGER_H diff --git a/toonz/sources/include/toonzqt/styleeditor.h b/toonz/sources/include/toonzqt/styleeditor.h index ba9afc9..cbcdc3f 100644 --- a/toonz/sources/include/toonzqt/styleeditor.h +++ b/toonz/sources/include/toonzqt/styleeditor.h @@ -14,6 +14,7 @@ #include "toonz/tpalettehandle.h" #include "toonz/txshlevelhandle.h" #include "toonz/txshlevel.h" +#include "toonz/stylemanager.h" // TnzQt includes #include "toonzqt/checkbox.h" @@ -529,24 +530,84 @@ protected: int m_chipPerRow; static TFilePath m_rootPath; + volatile bool m_pinsToTopDirty; + BaseStyleManager *m_manager; + StyleEditor *m_styleEditor; + QAction *m_pinToTopAct; + QAction *m_setPinsToTopAct; + QAction *m_clrPinsToTopAct; + + enum ChipType { + COMMONCHIP = 0, // Common chip + PINNEDCHIP = 1, // Pin-to-top chip + SOLIDCHIP = 2 // Solid/Nobrush chip + }; + + QColor m_commonChipBoxColor; + QColor m_pinnedChipBoxColor; + QColor m_solidChipBoxColor; + QColor m_selectedChipBoxColor; + QColor m_selectedChipBox2Color; + + Q_PROPERTY(QColor CommonChipBoxColor READ getCommonChipBoxColor WRITE + setCommonChipBoxColor) + Q_PROPERTY(QColor PinnedChipBoxColor READ getPinnedChipBoxColor WRITE + setPinnedChipBoxColor) + Q_PROPERTY(QColor SolidChipBoxColor READ getSolidChipBoxColor WRITE + setSolidChipBoxColor) + Q_PROPERTY(QColor SelectedChipBoxColor READ getSelectedChipBoxColor WRITE + setSelectedChipBoxColor) + Q_PROPERTY(QColor SelectedChipBox2Color READ getSelectedChipBox2Color WRITE + setSelectedChipBox2Color) + + QColor getCommonChipBoxColor() const { return m_commonChipBoxColor; } + QColor getPinnedChipBoxColor() const { return m_pinnedChipBoxColor; } + QColor getSolidChipBoxColor() const { return m_solidChipBoxColor; } + QColor getSelectedChipBoxColor() const { return m_selectedChipBoxColor; } + QColor getSelectedChipBox2Color() const { return m_selectedChipBox2Color; } + + void setSolidChipBoxColor(const QColor &color) { + m_solidChipBoxColor = color; + } + void setPinnedChipBoxColor(const QColor &color) { + m_pinnedChipBoxColor = color; + } + void setCommonChipBoxColor(const QColor &color) { + m_commonChipBoxColor = color; + } + void setSelectedChipBoxColor(const QColor &color) { + m_selectedChipBoxColor = color; + } + void setSelectedChipBox2Color(const QColor &color) { + m_selectedChipBox2Color = color; + } + public: - StyleChooserPage(QWidget *parent = 0); + StyleChooserPage(StyleEditor *styleEditor, QWidget *parent = 0); + void setChipSize(QSize chipSize); QSize getChipSize() const { return m_chipSize; } + void applyFilter(); + void applyFilter(const QString text); + virtual bool loadIfNeeded() = 0; virtual int getChipCount() const = 0; - virtual void drawChip(QPainter &p, QRect rect, int index) = 0; + virtual int drawChip(QPainter &p, QRect rect, int index) = 0; virtual void onSelect(int index) {} + virtual bool isSameStyle(const TColorStyleP style, int index) = 0; + + virtual QString getChipDescription(int index) = 0; + //! \see StyleEditor::setRootPath() // TOGLIERE static void setRootPath(const TFilePath &rootPath); static TFilePath getRootPath() { return m_rootPath; } protected: - int m_currentIndex; + // int m_currentIndex; int posToIndex(const QPoint &pos) const; @@ -554,14 +615,193 @@ protected: void resizeEvent(QResizeEvent *) override { computeSize(); } void mousePressEvent(QMouseEvent *event) override; - void mouseMoveEvent(QMouseEvent *event) override {} + void mouseMoveEvent(QMouseEvent *event) override; void mouseReleaseEvent(QMouseEvent *event) override; -protected slots: + void contextMenuEvent(QContextMenuEvent *event) override; + + bool event(QEvent *e) override; + +public slots: + void patternAdded(); void computeSize(); + void togglePinToTop(); + void doSetPinsToTop(); + void doClrPinsToTop(); + void doPinsToTopChange(); + signals: void styleSelected(const TColorStyle &style); }; +//***************************************************************************** +// CustomStyleChooser definition +//***************************************************************************** + +class CustomStyleChooserPage final : public StyleChooserPage { +public: + CustomStyleChooserPage(StyleEditor *styleEditor, QWidget *parent = 0) + : StyleChooserPage(styleEditor, parent) { + static const QString filters( + "*.pli *.tif *.png *.tga *.tiff *.sgi *.rgb *.pct *.pic *.exr"); + static CustomStyleManager theManager( + "RasterImagePatternStrokeStyle:", "VectorImagePatternStrokeStyle:", + TFilePath("custom styles"), filters, m_chipSize); + m_manager = &theManager; + } + + void showEvent(QShowEvent *) override { + connect(m_manager, SIGNAL(patternAdded()), this, SLOT(patternAdded())); + m_manager->loadItems(); + } + void hideEvent(QHideEvent *) override { + disconnect(m_manager, SIGNAL(patternAdded()), this, SLOT(patternAdded())); + } + bool loadIfNeeded() override { return false; } // serve? + /* +if(!m_loaded) {loadItems(); m_loaded=true;return true;} +else return false; +} + */ + + int getChipCount() const override { return m_manager->countData(); } + + int drawChip(QPainter &p, QRect rect, int index) override; + void onSelect(int index) override; + bool isSameStyle(const TColorStyleP style, int index) override; + + QString getChipDescription(int index) override; +}; + +//***************************************************************************** +// VectorBrushStyleChooser definition +//***************************************************************************** + +class VectorBrushStyleChooserPage final : public StyleChooserPage { +public: + VectorBrushStyleChooserPage(StyleEditor *styleEditor, QWidget *parent = 0) + : StyleChooserPage(styleEditor, parent) { + m_chipSize = QSize(60, 25); + static CustomStyleManager theManager( + "InvalidStyle", "VectorBrushStyle:", TFilePath("vector brushes"), + "*.pli", m_chipSize); + m_manager = &theManager; + } + + void showEvent(QShowEvent *) override { + bool ret = + connect(m_manager, SIGNAL(patternAdded()), this, SLOT(patternAdded())); + if (!ret) throw "!"; + m_manager->loadItems(); + } + void hideEvent(QHideEvent *) override { + disconnect(m_manager, SIGNAL(patternAdded()), this, SLOT(patternAdded())); + } + bool loadIfNeeded() override { return false; } + + int getChipCount() const override { return m_manager->countData() + 1; } + + int drawChip(QPainter &p, QRect rect, int index) override; + void onSelect(int index) override; + bool isSameStyle(const TColorStyleP style, int index) override; + + QString getChipDescription(int index) override; +}; + +//***************************************************************************** +// TextureStyleChooser definition +//***************************************************************************** + +class TextureStyleChooserPage final : public StyleChooserPage { +public: + TextureStyleChooserPage(StyleEditor *styleEditor, QWidget *parent = 0) + : StyleChooserPage(styleEditor, parent) { + m_chipSize = QSize(25, 25); + static TextureStyleManager theManager(TFilePath("textures"), m_chipSize); + m_manager = &theManager; + } + + bool loadIfNeeded() override { + if (!m_manager->isLoaded()) { + m_manager->loadItems(); + return true; + } else + return false; + } + + int getChipCount() const override { return m_manager->countData() + 1; } + + int drawChip(QPainter &p, QRect rect, int index) override; + void onSelect(int index) override; + bool isSameStyle(const TColorStyleP style, int index) override; + + QString getChipDescription(int index) override; +}; + +//***************************************************************************** +// MyPaintBrushStyleChooserPage definition +//***************************************************************************** + +class MyPaintBrushStyleChooserPage final : public StyleChooserPage { + MyPaintBrushStyleManager *m_mypManager; + +public: + MyPaintBrushStyleChooserPage(StyleEditor *styleEditor, QWidget *parent = 0) + : StyleChooserPage(styleEditor, parent) { + m_chipSize = QSize(64, 64); + static MyPaintBrushStyleManager theManager(m_chipSize); + m_manager = &theManager; + m_mypManager = &theManager; + } + + bool loadIfNeeded() override { + if (!m_manager->isLoaded()) { + m_manager->loadItems(); + return true; + } else + return false; + } + + TMyPaintBrushStyle &getBrush(int index) { + return m_mypManager->getBrush(index); + } + int getChipCount() const override { return m_manager->countData() + 1; } + + int drawChip(QPainter &p, QRect rect, int index) override; + void onSelect(int index) override; + bool isSameStyle(const TColorStyleP style, int index) override; + + QString getChipDescription(int index) override; +}; + +//***************************************************************************** +// SpecialStyleChooser definition +//***************************************************************************** + +class SpecialStyleChooserPage final : public StyleChooserPage { +public: + SpecialStyleChooserPage(StyleEditor *styleEditor, QWidget *parent = 0, + const TFilePath &rootDir = TFilePath()) + : StyleChooserPage(styleEditor, parent) { + static SpecialStyleManager theManager(m_chipSize); + m_manager = &theManager; + } + + bool loadIfNeeded() override { + if (!m_manager->isLoaded()) { + m_manager->loadItems(); + return true; + } else + return false; + } + int getChipCount() const override { return m_manager->countData() + 1; } + + int drawChip(QPainter &p, QRect rect, int index) override; + void onSelect(int index) override; + bool isSameStyle(const TColorStyleP style, int index) override; + + QString getChipDescription(int index) override; +}; + //============================================================================= /*! @@ -654,20 +894,33 @@ class DVAPI StyleEditor final : public QWidget, public SaveLoadQSettings { PlainColorPage *m_plainColorPage; StyleChooserPage *m_textureStylePage; - StyleEditorPage *m_specialStylePage; + StyleChooserPage *m_specialStylePage; StyleChooserPage *m_customStylePage; StyleChooserPage *m_vectorBrushesStylePage; StyleChooserPage *m_mypaintBrushesStylePage; SettingsPage *m_settingsPage; - QScrollArea *m_vectorArea; + QScrollArea *m_textureArea; + QScrollArea *m_vectorsArea; + QScrollArea *m_mypaintArea; QAction *m_wheelAction; QAction *m_hsvAction; QAction *m_alphaAction; QAction *m_rgbAction; QAction *m_hexAction; + QAction *m_searchAction; QActionGroup *m_sliderAppearanceAG; QAction *m_hexEditorAction; + QFrame *m_textureSearchFrame; + QFrame *m_vectorsSearchFrame; + QFrame *m_mypaintSearchFrame; + QLineEdit *m_textureSearchText; + QLineEdit *m_vectorsSearchText; + QLineEdit *m_mypaintSearchText; + QPushButton *m_textureSearchClear; + QPushButton *m_vectorsSearchClear; + QPushButton *m_mypaintSearchClear; + TColorStyleP m_oldStyle; //!< A copy of current style \a before the last change. TColorStyleP m_editedStyle; //!< The currently edited style. Please observe @@ -692,6 +945,7 @@ public: TPalette *getPalette() { return m_paletteHandle->getPalette(); } int getStyleIndex() { return m_paletteHandle->getStyleIndex(); } + const TColorStyleP getEditedStyle() const { return m_editedStyle; } /*! rootPath generally is STUFFDIR/Library. Contains directories 'textures' and @@ -733,6 +987,8 @@ protected: void enable(bool enabled, bool enabledOnlyFirstTab = false, bool enabledFirstAndLastTab = false); + void updateStylePages(); + protected: void showEvent(QShowEvent *) override; void hideEvent(QHideEvent *) override; @@ -771,6 +1027,8 @@ protected slots: void onHexChanged(); void onHexEditor(); + void onSearchVisible(bool on); + void onSpecialButtonToggled(bool on); void onCustomButtonToggled(bool on); void onVectorBrushButtonToggled(bool on); @@ -778,9 +1036,20 @@ protected slots: void onSliderAppearanceSelected(QAction *); void onPopupMenuAboutToShow(); + void onTextureSearch(const QString &); + void onTextureClearSearch(); + + void onVectorsSearch(const QString &); + void onVectorsClearSearch(); + + void onMyPaintSearch(const QString &); + void onMyPaintClearSearch(); + private: QFrame *createBottomWidget(); + QFrame *createTexturePage(); QFrame *createVectorPage(); + QFrame *createMyPaintPage(); void updateTabBar(); void copyEditedStyleToPalette(bool isDragging); diff --git a/toonz/sources/include/tsimplecolorstyles.h b/toonz/sources/include/tsimplecolorstyles.h index a337f10..4eb6145 100644 --- a/toonz/sources/include/tsimplecolorstyles.h +++ b/toonz/sources/include/tsimplecolorstyles.h @@ -156,6 +156,8 @@ public: TColorStyle *clone() const override; QString getDescription() const override; + std::string getBrushIdName() const override; + static std::size_t staticBrushIdHash(); bool hasMainColor() const override { return true; } TPixel32 getMainColor() const override { return m_color; } @@ -203,6 +205,7 @@ public: TColorStyle *clone() const override; QString getDescription() const override; + std::string getBrushIdName() const override; TPixel32 getColor() const { return m_color; } USHORT getStipple() const { return m_stipple; } @@ -266,10 +269,10 @@ public: void invalidate(){}; TColorStyle *clone() const override; + TColorStyle *clone(std::string brushIdName) const override; - QString getDescription() const override { - return "TRasterImagePatternStrokeStyle"; - } + QString getDescription() const override; + std::string getBrushIdName() const override; bool hasMainColor() const override { return false; } TPixel32 getMainColor() const override { return TPixel32::Black; } @@ -342,10 +345,10 @@ public: void invalidate(){}; TColorStyle *clone() const override; + TColorStyle *clone(std::string brushIdName) const override; - QString getDescription() const override { - return "TVectorImagePatternStrokeStyle"; - } + QString getDescription() const override; + std::string getBrushIdName() const override; bool hasMainColor() const override { return false; } TPixel32 getMainColor() const override { return TPixel32::Black; } diff --git a/toonz/sources/include/tvectorbrushstyle.h b/toonz/sources/include/tvectorbrushstyle.h index e6664f6..9c7cb9a 100644 --- a/toonz/sources/include/tvectorbrushstyle.h +++ b/toonz/sources/include/tvectorbrushstyle.h @@ -36,7 +36,10 @@ public: ~TVectorBrushStyle(); TColorStyle *clone() const override; + TColorStyle *clone(std::string brushIdName) const override; + QString getDescription() const override; + std::string getBrushIdName() const override; static TFilePath getRootDir() { return m_rootDir; } static void setRootDir(const TFilePath &path) { diff --git a/toonz/sources/toonz/Resources/no_texturestyle.png b/toonz/sources/toonz/Resources/no_texturestyle.png new file mode 100644 index 0000000..964ed69 Binary files /dev/null and b/toonz/sources/toonz/Resources/no_texturestyle.png differ diff --git a/toonz/sources/toonz/toonz.qrc b/toonz/sources/toonz/toonz.qrc index 57e7d66..7d085c2 100644 --- a/toonz/sources/toonz/toonz.qrc +++ b/toonz/sources/toonz/toonz.qrc @@ -586,6 +586,7 @@ Resources/no_specialstyle.png Resources/no_vectorbrush.png Resources/no_mypaintbrush.png + Resources/no_texturestyle.png Resources/palette_header.svg Resources/paletteicon.svg Resources/pan.png diff --git a/toonz/sources/toonzlib/imagestyles.cpp b/toonz/sources/toonzlib/imagestyles.cpp index d4d93ab..61f5766 100644 --- a/toonz/sources/toonzlib/imagestyles.cpp +++ b/toonz/sources/toonzlib/imagestyles.cpp @@ -112,10 +112,34 @@ TColorStyle *TTextureStyle::clone() const { return new TTextureStyle(*this); } //----------------------------------------------------------------------------- +TColorStyle *TTextureStyle::clone(std::string brushIdName) const { + TTextureStyle *style = new TTextureStyle(*this); + + std::string name = getBrushIdNameParam(brushIdName); + style->m_texturePath = TFilePath(name); + style->setAverageColor(); + return style; +} + +//----------------------------------------------------------------------------- + QString TTextureStyle::getDescription() const { return "TextureStyle"; } //----------------------------------------------------------------------------- +std::string TTextureStyle::getBrushIdName() const { + std::wstring ws = m_texturePath.getWideString(); + const std::string s(ws.begin(), ws.end()); + return "TextureStyle:" + s; +} + +//----------------------------------------------------------------------------- + +std::string TTextureStyle::staticBrushIdName(std::wstring texturePath) { + const std::string s(texturePath.begin(), texturePath.end()); + return "TextureStyle:" + s; +} + //----------------------------------------------------------------------------- int TTextureStyle::getTagId() const { return 4; } //----------------------------------------------------------------------------- diff --git a/toonz/sources/toonzlib/mypaintbrushstyle.cpp b/toonz/sources/toonzlib/mypaintbrushstyle.cpp index a23a084..b942383 100644 --- a/toonz/sources/toonzlib/mypaintbrushstyle.cpp +++ b/toonz/sources/toonzlib/mypaintbrushstyle.cpp @@ -47,6 +47,14 @@ TMyPaintBrushStyle::~TMyPaintBrushStyle() {} //----------------------------------------------------------------------------- +TColorStyle *TMyPaintBrushStyle::clone(std::string brushIdName) const { + TMyPaintBrushStyle *style = new TMyPaintBrushStyle(*this); + style->loadBrush(TFilePath(getBrushIdNameParam(brushIdName))); + return style; +} + +//----------------------------------------------------------------------------- + TColorStyle &TMyPaintBrushStyle::copy(const TColorStyle &other) { const TMyPaintBrushStyle *otherBrushStyle = dynamic_cast(&other); @@ -70,6 +78,14 @@ QString TMyPaintBrushStyle::getDescription() const { //----------------------------------------------------------------------------- +std::string TMyPaintBrushStyle::getBrushIdName() const { + std::wstring ws = m_path.getWideString(); + const std::string s(ws.begin(), ws.end()); + return "MyPaintBrushStyle:" + s; +} + +//----------------------------------------------------------------------------- + std::string TMyPaintBrushStyle::getBrushType() { return "myb"; } //----------------------------------------------------------------------------- diff --git a/toonz/sources/toonzlib/stylemanager.cpp b/toonz/sources/toonzlib/stylemanager.cpp index 7da5737..57a4833 100644 --- a/toonz/sources/toonzlib/stylemanager.cpp +++ b/toonz/sources/toonzlib/stylemanager.cpp @@ -9,6 +9,15 @@ #include "tvectorrenderdata.h" #include "tsystem.h" #include "tvectorgl.h" +#include "tcolorstyles.h" + +// TnzCore includes +#include "tfiletype.h" +#include "tvectorbrushstyle.h" + +// TnzLib includes +#include "toonz/imagestyles.h" +#include "toonz/toonzfolders.h" // Qt includes #include @@ -21,16 +30,14 @@ #include "toonz/stylemanager.h" +#include + //******************************************************************************** // Local namespace stuff //******************************************************************************** namespace { -TFilePath rootPath; - -//----------------------------------------------------------------------------- - void convertRaster32ToImage(TRaster32P ras, QImage *image) { int lx = ras->getLx(); int ly = ras->getLy(); @@ -46,16 +53,195 @@ void convertRaster32ToImage(TRaster32P ras, QImage *image) { ras->unlock(); } +//----------------------------------------------------------------------------- + +QImage rasterToQImage(const TRasterP &ras, bool premultiplied = true, + bool mirrored = true) { + if (TRaster32P ras32 = ras) { + QImage image(ras->getRawData(), ras->getLx(), ras->getLy(), + premultiplied ? QImage::Format_ARGB32_Premultiplied + : QImage::Format_ARGB32); + if (mirrored) return image.mirrored(); + return image; + } else if (TRasterGR8P ras8 = ras) { + QImage image(ras->getRawData(), ras->getLx(), ras->getLy(), ras->getWrap(), + QImage::Format_Indexed8); + static QVector colorTable; + if (colorTable.size() == 0) { + int i; + for (i = 0; i < 256; i++) colorTable.append(QColor(i, i, i).rgb()); + } + image.setColorTable(colorTable); + if (mirrored) return image.mirrored(); + return image; + } + return QImage(); +} + } // namespace //******************************************************************************** +// FavoritesManager implementation +//******************************************************************************** + +FavoritesManager::FavoritesManager() { + m_fpPinsToTop = ToonzFolder::getMyModuleDir() + "pintotopbrushes.txt"; + m_xxPinsToTop = false; + loadPinsToTop(); +} + +//----------------------------------------------------------------------------- + +FavoritesManager *FavoritesManager::instance() { + static FavoritesManager _instance; + return &_instance; +} + +//----------------------------------------------------------------------------- + +bool FavoritesManager::loadPinsToTop() { + if (!TFileStatus(m_fpPinsToTop).doesExist()) return false; + + TIStream is(m_fpPinsToTop); + if (!is) throw TException("Can't read XML"); + std::string tagName; + + if (!is.matchTag(tagName) || tagName != "PinsToTop") return false; + + m_pinsToTop.clear(); + while (!is.matchEndTag()) { + if (!is.matchTag(tagName)) throw TException("Expected tag"); + if (tagName == "BrushIdName") { + std::string brushname; + is >> brushname; + m_pinsToTop.push_back(brushname); + if (!is.matchEndTag()) throw TException("Expected end tag"); + } + } + m_xxPinsToTop = false; + + return true; +} + +//----------------------------------------------------------------------------- + +void FavoritesManager::savePinsToTop() { + if (!m_xxPinsToTop) return; + + TOStream os(m_fpPinsToTop); + if (!os) throw TException("Can't write XML"); + + os.openChild("PinsToTop"); + for (auto &idname : m_pinsToTop) { + os.openChild("BrushIdName", {}); + os << idname; + os.closeChild(); + } + os.closeChild(); +} + +//----------------------------------------------------------------------------- + +bool FavoritesManager::getPinToTop(std::string idname) const { + return m_pinsToTop.contains(idname); +} + +//----------------------------------------------------------------------------- + +void FavoritesManager::setPinToTop(std::string idname, bool state) { + int index = m_pinsToTop.indexOf(idname); + if (state && index == -1) { + m_xxPinsToTop = true; + m_pinsToTop.append(idname); + } else if (!state && index != -1) { + m_xxPinsToTop = true; + m_pinsToTop.removeAll(idname); + } +} + +//----------------------------------------------------------------------------- + +void FavoritesManager::togglePinToTop(std::string idname) { + int index = m_pinsToTop.indexOf(idname); + if (index != -1) + m_pinsToTop.removeAt(index); + else + m_pinsToTop.append(idname); + m_xxPinsToTop = true; +} + +//******************************************************************************** +// BaseStyleManager implementation +//******************************************************************************** + +TFilePath BaseStyleManager::s_rootPath; +BaseStyleManager::ChipData BaseStyleManager::s_emptyChipData; + +BaseStyleManager::BaseStyleManager(const TFilePath &stylesFolder, + QString filters, QSize chipSize) + : m_stylesFolder(stylesFolder) + , m_filters(filters) + , m_chipSize(chipSize) + , m_loaded(false) + , m_isIndexed(false) {} + +//----------------------------------------------------------------------------- + +const BaseStyleManager::ChipData &BaseStyleManager::getData(int index) const { + if (m_isIndexed) { + return (index < 0 || index >= m_indexes.count()) + ? s_emptyChipData + : m_chips[m_indexes[index]]; + } else { + return (index < 0 || index >= m_chips.count()) ? s_emptyChipData + : m_chips[index]; + } +} + +//----------------------------------------------------------------------------- + +void BaseStyleManager::applyFilter() { + FavoritesManager *favMan = FavoritesManager::instance(); + QList indexes; + + m_indexes.clear(); + int len = m_chips.count(); + for (int i = 0; i < len; i++) { + auto &chip = m_chips[i]; + if (chip.desc.indexOf(m_searchText, 0, Qt::CaseInsensitive) >= 0) { + if (favMan->getPinToTop(chip.idname)) { + chip.markPinToTop = true; + m_indexes.append(i); + } else { + chip.markPinToTop = false; + indexes.append(i); + } + } + } + + bool hasPinsToTop = m_indexes.count() > 0; + m_indexes.append(indexes); + m_isIndexed = (m_indexes.count() != len) || hasPinsToTop; +} + +//----------------------------------------------------------------------------- + +TFilePath BaseStyleManager::getRootPath() { return s_rootPath; } + +//----------------------------------------------------------------------------- + +void BaseStyleManager::setRootPath(const TFilePath &rootPath) { + s_rootPath = rootPath; +} + +//******************************************************************************** // StyleLoaderTask definition //******************************************************************************** class CustomStyleManager::StyleLoaderTask final : public TThread::Runnable { CustomStyleManager *m_manager; TFilePath m_fp; - PatternData m_data; + ChipData m_data; std::shared_ptr m_offScreenSurface; public: @@ -84,19 +270,96 @@ CustomStyleManager::StyleLoaderTask::StyleLoaderTask( //----------------------------------------------------------------------------- void CustomStyleManager::StyleLoaderTask::run() { + m_data = m_manager->createPattern(m_fp, m_offScreenSurface); +} + +//----------------------------------------------------------------------------- + +void CustomStyleManager::StyleLoaderTask::onFinished( + TThread::RunnableP sender) { + // On the main thread... + if (!m_data.image.isNull()) // Everything went ok + { + m_manager->m_chips.append(m_data); + emit m_manager->patternAdded(); + } +} + +//******************************************************************************** +// CustomStyleManager implementation +//******************************************************************************** + +CustomStyleManager::CustomStyleManager(std::string rasterIdName, + std::string vectorIdName, + const TFilePath &stylesFolder, + QString filters, QSize chipSize) + : BaseStyleManager(stylesFolder, filters, chipSize) + , m_started(false) + , m_rasterIdName(rasterIdName) + , m_vectorIdName(vectorIdName) { + m_executor.setMaxActiveTasks(1); +} + +//----------------------------------------------------------------------------- + +void CustomStyleManager::loadItems() { + // Build the folder to be read + const TFilePath &rootFP(getRootPath()); + + assert(rootFP != TFilePath()); + if (rootFP == TFilePath()) return; + + QDir patternDir( + QString::fromStdWString((rootFP + m_stylesFolder).getWideString())); + patternDir.setNameFilters(m_filters.split(' ')); + + // Read the said folder + TFilePathSet fps; + try { + TSystem::readDirectory(fps, patternDir); + } catch (...) { + return; + } + + // Delete patterns no longer in the folder + TFilePathSet newFps; + TFilePathSet::iterator it; + int i; + for (i = 0; i < m_chips.size(); i++) { + ChipData data = m_chips.at(i); + for (it = fps.begin(); it != fps.end(); ++it) { + int isVector = (it->getType() == "pli") ? 1 : 0; + QString name = QString::fromStdWString(it->getWideName()); + if (data.name == name && data.isVector == isVector) break; + } + + if (it == fps.end()) { + m_chips.removeAt(i); + i--; + } else + fps.erase(it); // The style is not new, so don't generate tasks for it + } + + // For each (now new) file entry, generate a fetching task + for (TFilePathSet::iterator it = fps.begin(); it != fps.end(); it++) + m_executor.addTask(new StyleLoaderTask(this, *it)); +} + +QImage CustomStyleManager::makeIcon( + const TFilePath &path, const QSize &qChipSize, + std::shared_ptr offsurf) { try { // Fetch the level - TLevelReaderP lr(m_fp); + TLevelReaderP lr(path); TLevelP level = lr->loadInfo(); - if (!level || level->getFrameCount() == 0) return; + if (!level || level->getFrameCount() == 0) return QImage(); // Fetch the image of the first frame in the level TLevel::Iterator frameIt = level->begin(); - if (frameIt == level->end()) return; + if (frameIt == level->end()) return QImage(); TImageP img = lr->getFrameReader(frameIt->first)->load(); // Process the image - const QSize &qChipSize = m_manager->getChipSize(); TDimension chipSize(qChipSize.width(), qChipSize.height()); TVectorImageP vimg = img; @@ -104,7 +367,7 @@ void CustomStyleManager::StyleLoaderTask::run() { TRaster32P ras; - QImage *image = nullptr; + QImage image; if (vimg) { assert(level->getPalette()); @@ -122,7 +385,7 @@ void CustomStyleManager::StyleLoaderTask::run() { glContext->setShareContext(QOpenGLContext::currentContext()); glContext->setFormat(QSurfaceFormat::defaultFormat()); glContext->create(); - glContext->makeCurrent(m_offScreenSurface.get()); + glContext->makeCurrent(offsurf.get()); // attaching stencil buffer here as some styles use it QOpenGLFramebufferObject fb( chipSize.lx, chipSize.ly, @@ -162,9 +425,9 @@ void CustomStyleManager::StyleLoaderTask::run() { #else tglDraw(rd, vimg.getPointer()); - image = new QImage(fb.toImage().scaled(QSize(chipSize.lx, chipSize.ly), - Qt::IgnoreAspectRatio, - Qt::SmoothTransformation)); + image = QImage(fb.toImage().scaled(QSize(chipSize.lx, chipSize.ly), + Qt::IgnoreAspectRatio, + Qt::SmoothTransformation)); fb.release(); glContext->deleteLater(); #endif @@ -183,108 +446,222 @@ void CustomStyleManager::StyleLoaderTask::run() { ras = rout; } #ifndef LINUX - image = new QImage(chipSize.lx, chipSize.ly, QImage::Format_RGB32); - convertRaster32ToImage(ras, image); + // image = QImage(chipSize.lx, chipSize.ly, QImage::Format_RGB32); + // convertRaster32ToImage(ras, &image); + image = rasterToQImage(ras); #endif } else assert(!"unsupported type for custom styles!"); #ifdef LINUX - image = new QImage(chipSize.lx, chipSize.ly, QImage::Format_RGB32); - convertRaster32ToImage(ras, image); + // image = QImage(chipSize.lx, chipSize.ly, QImage::Format_RGB32); + // convertRaster32ToImage(ras, &image); + image = rasterToQImage(ras); #endif - m_data.m_patternName = m_fp.getName(); - m_data.m_isVector = (m_fp.getType() == "pli" || m_fp.getType() == "svg"); - m_data.m_image = image; + return image; } catch (...) { } + + return QImage(); } -//----------------------------------------------------------------------------- +CustomStyleManager::ChipData CustomStyleManager::createPattern( + const TFilePath &path, std::shared_ptr offsurf) { + ChipData data; -void CustomStyleManager::StyleLoaderTask::onFinished( - TThread::RunnableP sender) { - // On the main thread... - if (m_data.m_image) // Everything went ok - { - m_manager->m_patterns.push_back(m_data); - emit m_manager->patternAdded(); + bool isVector = (path.getType() == "pli" || path.getType() == "svg"); + + // Generate preview + try { + data.image = makeIcon(path, getChipSize(), offsurf); + } catch (...) { } + + if (!data.image.isNull()) { + data.name = QString::fromStdWString(path.getWideName()); + data.desc = data.name; + data.isVector = isVector; + if (isVector) + data.idname = m_vectorIdName + data.name.toStdString(); + else + data.idname = m_rasterIdName + data.name.toStdString(); + data.hash = TColorStyle::generateHash(data.idname); + } + return data; } //******************************************************************************** -// CustomStyleManager implementation +// TextureStyleManager implementation //******************************************************************************** -CustomStyleManager::CustomStyleManager(const TFilePath &stylesFolder, - QString filters, QSize chipSize) - : m_stylesFolder(stylesFolder), m_filters(filters), m_chipSize(chipSize) { - m_executor.setMaxActiveTasks(1); -} +TextureStyleManager::TextureStyleManager(const TFilePath &stylesFolder, + QSize chipSize) + : BaseStyleManager(stylesFolder, QString(), chipSize) {} //----------------------------------------------------------------------------- -int CustomStyleManager::getPatternCount() { return m_patterns.size(); } +void TextureStyleManager::loadTexture(const TFilePath &fp) { + if (fp == TFilePath()) { + TRaster32P ras(25, 25); + TTextureStyle::fillCustomTextureIcon(ras); + // ras->fill(TPixel::Blue); + ChipData customText( + QString(""), QObject::tr("Custom Texture", "TextureStyleChooserPage"), + rasterToQImage(ras), 4, false, ras, + TTextureStyle::staticBrushIdName(L"")); + customText.hash = TTextureStyle::generateHash(customText.idname); + m_chips.append(customText); + return; + } -//----------------------------------------------------------------------------- + TRasterP ras; + TImageReader::load(fp, ras); + if (!ras || ras->getLx() < 2 || ras->getLy() < 2) return; + + TRaster32P ras32 = ras; + if (!ras32) return; + + TDimension d(2, 2); + while (d.lx < 256 && d.lx * 2 <= ras32->getLx()) d.lx *= 2; + while (d.ly < 256 && d.ly * 2 <= ras32->getLy()) d.ly *= 2; + + TRaster32P texture; + if (d == ras32->getSize()) + texture = ras32; + else { + texture = TRaster32P(d); + TScale sc((double)texture->getLx() / ras32->getLx(), + (double)texture->getLy() / ras32->getLy()); + TRop::resample(texture, ras32, sc); + } -CustomStyleManager::PatternData CustomStyleManager::getPattern(int index) { - return (index < 0 || index >= m_patterns.size()) ? PatternData() - : m_patterns[index]; + QString name = QString::fromStdWString(fp.getLevelNameW()); + ChipData text(name, name, rasterToQImage(ras), 4, false, texture, + TTextureStyle::staticBrushIdName(fp.getLevelNameW())); + text.hash = TTextureStyle::generateHash(text.idname); + + m_chips.append(text); } //----------------------------------------------------------------------------- -TFilePath CustomStyleManager::getRootPath() { return ::rootPath; } +void TextureStyleManager::loadItems() { + m_chips.clear(); + if (getRootPath() == TFilePath()) return; -//----------------------------------------------------------------------------- + TFilePath texturePath = getRootPath() + "textures"; + TFilePathSet fps; + try { + fps = TSystem::readDirectory(texturePath); + } catch (...) { + return; + } + if (fps.empty()) return; + int count = 0; + for (TFilePathSet::iterator it = fps.begin(); it != fps.end(); it++) + if (TFileType::getInfo(*it) == TFileType::RASTER_IMAGE) { + try { + loadTexture(*it); + ++count; + } catch (...) { + } + } + loadTexture(TFilePath()); // custom texture -void CustomStyleManager::setRootPath(const TFilePath &rootPath) { - ::rootPath = rootPath; + m_loaded = true; } -//----------------------------------------------------------------------------- +//******************************************************************************** +// MyPaintBrushStyleManager implementation +//******************************************************************************** -void CustomStyleManager::loadItems() { - // Build the folder to be read - const TFilePath &rootFP(getRootPath()); +MyPaintBrushStyleManager::MyPaintBrushStyleManager(QSize chipSize) + : BaseStyleManager(TFilePath(), QString(), chipSize) {} - assert(rootFP != TFilePath()); - if (rootFP == TFilePath()) return; +//----------------------------------------------------------------------------- - QDir patternDir( - QString::fromStdWString((rootFP + m_stylesFolder).getWideString())); - patternDir.setNameFilters(m_filters.split(' ')); +void MyPaintBrushStyleManager::loadItems() { + m_brushes.clear(); + m_chips.clear(); + std::set brushFiles; + + TFilePathSet dirs = TMyPaintBrushStyle::getBrushesDirs(); + for (TFilePathSet::iterator i = dirs.begin(); i != dirs.end(); ++i) { + TFileStatus fs(*i); + if (fs.doesExist() && fs.isDirectory()) { + TFilePathSet files = TSystem::readDirectoryTree(*i, false, true); + for (TFilePathSet::iterator j = files.begin(); j != files.end(); ++j) + if (j->getType() == TMyPaintBrushStyle::getBrushType()) + brushFiles.insert(*j - *i); + } + } - // Read the said folder - TFilePathSet fps; - try { - TSystem::readDirectory(fps, patternDir); - } catch (...) { - return; + // reserve memory to avoid reallocation + m_brushes.reserve(brushFiles.size()); + for (std::set::iterator i = brushFiles.begin(); + i != brushFiles.end(); ++i) { + TMyPaintBrushStyle style = TMyPaintBrushStyle(*i); + m_brushes.push_back(style); + + // Generate a QImage preview to draw the chip faster at cost of few memory + QImage previewQImage = rasterToQImage(style.getPreview()); + QString stylePath = style.getPath().getQString(); + m_chips.append(ChipData(stylePath, stylePath, previewQImage, 4001, false, + TRasterP(), style.getBrushIdName(), + style.getBrushIdHash())); } - // Delete patterns no longer in the folder - TFilePathSet newFps; - TFilePathSet::iterator it; - int i; - for (i = 0; i < m_patterns.size(); i++) { - PatternData data = m_patterns.at(i); - for (it = fps.begin(); it != fps.end(); ++it) { - if (data.m_patternName == it->getName() && - data.m_isVector == (it->getType() == "pli")) - break; - } + m_loaded = true; +} - if (it == fps.end()) { - m_patterns.removeAt(i); - i--; - } else - fps.erase(it); // The style is not new, so don't generate tasks for it +//******************************************************************************** +// SpecialStyleManager implementation +//******************************************************************************** + +SpecialStyleManager::SpecialStyleManager(QSize chipSize) + : BaseStyleManager(TFilePath(), QString(), chipSize) {} + +//----------------------------------------------------------------------------- + +void SpecialStyleManager::loadItems() { + m_chips.clear(); + + std::vector tags; + TColorStyle::getAllTags(tags); + + int chipCount = 0; + + for (int j = 0; j < (int)tags.size(); j++) { + int tagId = tags[j]; + if (tagId == 3 || // solid color + tagId == 4 || // texture + tagId == 100 || // obsolete imagepattern id + tagId == 2000 || // imagepattern + tagId == 2800 || // imagepattern + tagId == 2001 || // cleanup + tagId == 2002 || // black cleanup + tagId == 3000 || // vector brush + tagId == 4001 // mypaint brush + ) + continue; + + TColorStyle *style = TColorStyle::create(tagId); + if (style->isRasterStyle()) { + delete style; + continue; + } + TDimension chipSize(getChipSize().width(), getChipSize().height()); + // QImage *image = new QImage(chipSize.lx, chipSize.ly, + // QImage::Format_RGB32); convertRaster32ToImage(style->getIcon(chipSize), + // image); + TRaster32P raster = style->getIcon(chipSize); + ChipData chip(style->getDescription(), style->getDescription(), + rasterToQImage(raster), tagId, true, raster, + style->getBrushIdName(), style->getBrushIdHash()); + m_chips.append(chip); + delete style; } - // For each (now new) file entry, generate a fetching task - for (TFilePathSet::iterator it = fps.begin(); it != fps.end(); it++) - m_executor.addTask(new StyleLoaderTask(this, *it)); + m_loaded = true; } diff --git a/toonz/sources/toonzqt/styleeditor.cpp b/toonz/sources/toonzqt/styleeditor.cpp index 6392332..b40fa00 100644 --- a/toonz/sources/toonzqt/styleeditor.cpp +++ b/toonz/sources/toonzqt/styleeditor.cpp @@ -10,7 +10,6 @@ // TnzLib includes #include "toonz/txshlevel.h" -#include "toonz/stylemanager.h" #include "toonz/txshlevelhandle.h" #include "toonz/toonzfolders.h" #include "toonz/cleanupcolorstyles.h" @@ -1853,26 +1852,85 @@ TFilePath StyleChooserPage::m_rootPath; //----------------------------------------------------------------------------- -StyleChooserPage::StyleChooserPage(QWidget *parent) +StyleChooserPage::StyleChooserPage(StyleEditor *styleEditor, QWidget *parent) : StyleEditorPage(parent) , m_chipOrigin(5, 3) , m_chipSize(25, 25) , m_chipPerRow(0) - , m_currentIndex(-1) {} + , m_pinsToTopDirty(false) + , m_styleEditor(styleEditor) { + //, m_currentIndex(-1) { + + setObjectName("StyleChooserPage"); + + m_pinToTopAct = new QAction(tr("Pin To Top"), this); + m_pinToTopAct->setCheckable(true); + m_setPinsToTopAct = new QAction(tr("Set Pins To Top"), this); + m_clrPinsToTopAct = new QAction(tr("Clear Pins To Top"), this); + + FavoritesManager *favorites = FavoritesManager::instance(); + + bool ret = true; + + ret = ret && connect(m_pinToTopAct, SIGNAL(triggered()), this, + SLOT(togglePinToTop())); + ret = ret && connect(m_setPinsToTopAct, SIGNAL(triggered()), this, + SLOT(doSetPinsToTop())); + ret = ret && connect(m_clrPinsToTopAct, SIGNAL(triggered()), this, + SLOT(doClrPinsToTop())); + ret = ret && connect(favorites, SIGNAL(pinsToTopChanged()), this, + SLOT(doPinsToTopChange())); + assert(ret); + setMouseTracking(true); +} + +//----------------------------------------------------------------------------- + +void StyleChooserPage::setChipSize(QSize chipSize) { + if (chipSize.width() < 4) chipSize.setWidth(4); + if (chipSize.height() < 4) chipSize.setHeight(4); + m_chipSize = chipSize; + computeSize(); +} + +//----------------------------------------------------------------------------- + +void StyleChooserPage::applyFilter() { + assert(m_manager); + m_manager->applyFilter(); +} + +//----------------------------------------------------------------------------- + +void StyleChooserPage::applyFilter(const QString text) { + assert(m_manager); + m_manager->applyFilter(text); +} //----------------------------------------------------------------------------- void StyleChooserPage::paintEvent(QPaintEvent *) { - if (loadIfNeeded()) computeSize(); + if (loadIfNeeded() || m_pinsToTopDirty) { + m_pinsToTopDirty = false; + applyFilter(); + computeSize(); + } + + // Get current selected style + TColorStyleP selectedStyle = nullptr; + if (m_styleEditor) selectedStyle = m_styleEditor->getEditedStyle(); + QPainter p(this); // p.setRenderHint(QPainter::SmoothPixmapTransform); - if (m_chipPerRow == 0 || getChipCount() == 0) return; + + int maxCount = getChipCount(); + if (m_chipPerRow == 0 || maxCount == 0) return; int w = parentWidget()->width(); int chipLx = m_chipSize.width(), chipLy = m_chipSize.height(); int nX = m_chipPerRow; - int nY = (getChipCount() + m_chipPerRow - 1) / m_chipPerRow; + int nY = (maxCount + m_chipPerRow - 1) / m_chipPerRow; int x0 = m_chipOrigin.x(); int y0 = m_chipOrigin.y(); int i, j; @@ -1882,31 +1940,47 @@ void StyleChooserPage::paintEvent(QPaintEvent *) { for (j = 0; j < nX; j++) { QRect rect(x0 + chipLx * j + 2, y0 + chipLy * i + 2, chipLx, chipLy); - drawChip(p, rect, count); - p.setPen(Qt::black); - p.drawRect(rect); + int chipType = drawChip(p, rect, count); + if (chipType == COMMONCHIP) { + p.setPen(m_commonChipBoxColor); + p.drawRect(rect); + } else if (chipType == PINNEDCHIP) { + p.setPen(m_pinnedChipBoxColor); + p.drawRect(rect.adjusted(0, 0, -1, -1)); + } else { // SOLIDCHIP + p.setPen(m_solidChipBoxColor); + p.drawRect(rect.adjusted(0, 0, -1, -1)); + } - if (m_currentIndex == count) currentIndexRect = rect; + // if (m_currentIndex == count) currentIndexRect = rect; + if (isSameStyle(selectedStyle, count)) currentIndexRect = rect; count++; - if (count >= getChipCount()) break; + if (count >= maxCount) break; } if (!currentIndexRect.isEmpty()) { // Draw the curentIndex border - p.setPen(Qt::white); + p.setPen(m_selectedChipBoxColor); p.drawRect(currentIndexRect); - p.setPen(QColor(199, 202, 50)); + p.setPen(m_selectedChipBox2Color); p.drawRect(currentIndexRect.adjusted(1, 1, -1, -1)); - p.setPen(Qt::white); + p.setPen(m_selectedChipBoxColor); p.drawRect(currentIndexRect.adjusted(2, 2, -2, -2)); - p.setPen(Qt::black); + p.setPen(m_commonChipBoxColor); p.drawRect(currentIndexRect.adjusted(3, 3, -3, -3)); } } //----------------------------------------------------------------------------- +void StyleChooserPage::patternAdded() { + applyFilter(); + computeSize(); +} + +//----------------------------------------------------------------------------- + void StyleChooserPage::computeSize() { int w = width(); m_chipPerRow = (w - 15) / m_chipSize.width(); @@ -1939,7 +2013,7 @@ void StyleChooserPage::mousePressEvent(QMouseEvent *event) { QPoint pos = event->pos(); int currentIndex = posToIndex(pos); if (currentIndex < 0) return; - m_currentIndex = currentIndex; + // m_currentIndex = currentIndex; onSelect(currentIndex); update(); @@ -1947,178 +2021,185 @@ void StyleChooserPage::mousePressEvent(QMouseEvent *event) { //----------------------------------------------------------------------------- -void StyleChooserPage::mouseReleaseEvent(QMouseEvent *event) {} +void StyleChooserPage::mouseMoveEvent(QMouseEvent *event) { + QPoint pos = event->pos(); + int currentIndex = posToIndex(pos); + if (currentIndex >= 0 && currentIndex < getChipCount()) + setCursor(Qt::PointingHandCursor); + else + setCursor(Qt::ArrowCursor); +} //----------------------------------------------------------------------------- -// TOGLIERE -void StyleChooserPage::setRootPath(const TFilePath &rootPath) { - m_rootPath = rootPath; -} -//***************************************************************************** -// CustomStyleChooser definition -//***************************************************************************** +void StyleChooserPage::mouseReleaseEvent(QMouseEvent *event) {} -class CustomStyleChooserPage final : public StyleChooserPage { -public: - CustomStyleChooserPage(QWidget *parent = 0) : StyleChooserPage(parent) {} +//----------------------------------------------------------------------------- - static CustomStyleManager *styleManager(); +void StyleChooserPage::contextMenuEvent(QContextMenuEvent *event) { + QPoint pos = event->pos(); + int currentIndex = posToIndex(pos); + if (currentIndex < 0) return; - bool event(QEvent *e) override; + // Get current selected style + TColorStyleP selectedStyle = nullptr; + if (m_styleEditor) selectedStyle = m_styleEditor->getEditedStyle(); - void showEvent(QShowEvent *) override { - connect(styleManager(), SIGNAL(patternAdded()), this, SLOT(computeSize())); - styleManager()->loadItems(); - } - void hideEvent(QHideEvent *) override { - disconnect(styleManager(), SIGNAL(patternAdded()), this, - SLOT(computeSize())); - } - bool loadIfNeeded() override { return false; } // serve? - /* -if(!m_loaded) {loadItems(); m_loaded=true;return true;} -else return false; -} - */ + if (!selectedStyle) return; + std::string idname = selectedStyle->getBrushIdName(); - int getChipCount() const override { - return styleManager()->getPatternCount(); - } + // Blacklist "no brush" since it's always pinned/favorite + if (idname == "SolidColorStyle") return; - void drawChip(QPainter &p, QRect rect, int index) override { - assert(0 <= index && index < getChipCount()); - CustomStyleManager::PatternData pattern = styleManager()->getPattern(index); - if (pattern.m_image && !pattern.m_image->isNull()) - p.drawImage(rect, *pattern.m_image); - } - void onSelect(int index) override; -}; + QMenu menu(this); -//----------------------------------------------------------------------------- + FavoritesManager *favorites = FavoritesManager::instance(); -CustomStyleManager *CustomStyleChooserPage::styleManager() { - static const QString filters( - "*.pli *.tif *.png *.tga *.tiff *.sgi *.rgb *.pct *.pic"); - static CustomStyleManager theManager(TFilePath("custom styles"), filters); - return &theManager; + m_pinToTopAct->setChecked(favorites->getPinToTop(idname)); + menu.addAction(m_pinToTopAct); + // menu.addSeparator(); + // QMenu *menuvis = menu.addMenu("Visible Brushes"); + // menuvis->addAction(m_setPinsToTopAct); + // menuvis->addAction(m_clrPinsToTopAct); + menu.exec(event->globalPos()); } //----------------------------------------------------------------------------- -bool CustomStyleChooserPage::event(QEvent *e) { +bool StyleChooserPage::event(QEvent *e) { // Intercept tooltip events - if (e->type() != QEvent::ToolTip) return StyleChooserPage::event(e); + if (e->type() != QEvent::ToolTip) return StyleEditorPage::event(e); // see StyleChooserPage::paintEvent - CustomStyleManager *manager = styleManager(); - QHelpEvent *he = static_cast(e); + QHelpEvent *he = static_cast(e); - int chipIdx = posToIndex(he->pos()), chipCount = manager->getPatternCount(); - if (chipIdx < 0 || chipIdx >= chipCount) return false; + int chipIdx = posToIndex(he->pos()), chipCount = getChipCount(); + if (chipIdx < 0 || chipIdx >= chipCount) { + QToolTip::hideText(); + return false; + } - CustomStyleManager::PatternData pattern = manager->getPattern(chipIdx); - QToolTip::showText(he->globalPos(), - QString::fromStdString(pattern.m_patternName)); + QString toolTip = getChipDescription(chipIdx); + if (toolTip.isEmpty()) + QToolTip::hideText(); + else + QToolTip::showText(he->globalPos(), toolTip); return true; } //----------------------------------------------------------------------------- -void CustomStyleChooserPage::onSelect(int index) { - if (index < 0 || index >= getChipCount()) return; +void StyleChooserPage::togglePinToTop() { + // Get current selected style + TColorStyleP selectedStyle = nullptr; + if (m_styleEditor) selectedStyle = m_styleEditor->getEditedStyle(); - CustomStyleManager::PatternData pattern = styleManager()->getPattern(index); + if (!selectedStyle) return; + std::string idname = selectedStyle->getBrushIdName(); - if (m_currentIndex < 0) return; + FavoritesManager *favorites = FavoritesManager::instance(); - std::string name = pattern.m_patternName; - if (pattern.m_isVector) { - TVectorImagePatternStrokeStyle cs(name); - emit styleSelected(cs); - } else { - TRasterImagePatternStrokeStyle cs(name); - emit styleSelected(cs); - } + favorites->togglePinToTop(idname); + favorites->savePinsToTop(); + favorites->emitPinsToTopChange(); } -//***************************************************************************** -// VectorBrushStyleChooser definition -//***************************************************************************** +//----------------------------------------------------------------------------- -class VectorBrushStyleChooserPage final : public StyleChooserPage { -public: - VectorBrushStyleChooserPage(QWidget *parent = 0) : StyleChooserPage(parent) { - m_chipSize = QSize(60, 25); +void StyleChooserPage::doSetPinsToTop() { + FavoritesManager *favorites = FavoritesManager::instance(); + + int len = m_manager->countData(); + for (int i = 0; i < len; i++) { + auto &data = m_manager->getData(i); + favorites->setPinToTop(data.idname, true); } + favorites->savePinsToTop(); + favorites->emitPinsToTopChange(); +} - static CustomStyleManager *styleManager(); +//----------------------------------------------------------------------------- - bool event(QEvent *e) override; +void StyleChooserPage::doClrPinsToTop() { + FavoritesManager *favorites = FavoritesManager::instance(); - void showEvent(QShowEvent *) override { - connect(styleManager(), SIGNAL(patternAdded()), this, SLOT(computeSize())); - styleManager()->loadItems(); + int len = m_manager->countData(); + for (int i = 0; i < len; i++) { + auto &data = m_manager->getData(i); + favorites->setPinToTop(data.idname, false); } - void hideEvent(QHideEvent *) override { - disconnect(styleManager(), SIGNAL(patternAdded()), this, - SLOT(computeSize())); - } - bool loadIfNeeded() override { return false; } + favorites->savePinsToTop(); + favorites->emitPinsToTopChange(); +} - int getChipCount() const override { - return styleManager()->getPatternCount() + 1; - } +//----------------------------------------------------------------------------- - void drawChip(QPainter &p, QRect rect, int index) override; - void onSelect(int index) override; -}; +void StyleChooserPage::doPinsToTopChange() { + if (!m_pinsToTopDirty) m_pinsToTopDirty = true; + update(); +} //----------------------------------------------------------------------------- +// TOGLIERE +void StyleChooserPage::setRootPath(const TFilePath &rootPath) { + m_rootPath = rootPath; +} -CustomStyleManager *VectorBrushStyleChooserPage::styleManager() { - static CustomStyleManager theManager(TFilePath("vector brushes"), "*.pli", - QSize(60, 25)); - return &theManager; +//***************************************************************************** +// CustomStyleChooser implementation +//***************************************************************************** + +int CustomStyleChooserPage::drawChip(QPainter &p, QRect rect, int index) { + assert(0 <= index && index < getChipCount()); + auto &data = m_manager->getData(index); + if (!data.image.isNull()) p.drawImage(rect, data.image); + return data.markPinToTop ? PINNEDCHIP : COMMONCHIP; } //----------------------------------------------------------------------------- -bool VectorBrushStyleChooserPage::event(QEvent *e) { - // Intercept tooltip events - if (e->type() != QEvent::ToolTip) return StyleChooserPage::event(e); +void CustomStyleChooserPage::onSelect(int index) { + if (index < 0 || index >= getChipCount()) return; - // see StyleChooserPage::paintEvent - CustomStyleManager *manager = styleManager(); - QHelpEvent *he = static_cast(e); + auto &data = m_manager->getData(index); - int chipIdx = posToIndex(he->pos()), chipCount = getChipCount(); - if (chipIdx < 0 || chipIdx >= chipCount) return false; + std::string name = data.name.toStdString(); - if (chipIdx > 0) { - CustomStyleManager::PatternData pattern = manager->getPattern(chipIdx - 1); - QToolTip::showText(he->globalPos(), - QString::fromStdString(pattern.m_patternName)); - } else - QToolTip::showText( - he->globalPos(), - QObject::tr("Plain color", "VectorBrushStyleChooserPage")); + if (data.isVector) { + TVectorImagePatternStrokeStyle cs(name); + emit styleSelected(cs); + } else { + TRasterImagePatternStrokeStyle cs(name); + emit styleSelected(cs); + } +} - return true; +//----------------------------------------------------------------------------- + +bool CustomStyleChooserPage::isSameStyle(const TColorStyleP style, int index) { + return style->getBrushIdHash() == m_manager->getData(index).hash; } //----------------------------------------------------------------------------- -void VectorBrushStyleChooserPage::drawChip(QPainter &p, QRect rect, int index) { +QString CustomStyleChooserPage::getChipDescription(int index) { + return m_manager->getData(index).desc; +} + +//***************************************************************************** +// VectorBrushStyleChooser implementation +//***************************************************************************** + +int VectorBrushStyleChooserPage::drawChip(QPainter &p, QRect rect, int index) { if (index == 0) { static QImage noSpecialStyleImage(":Resources/no_vectorbrush.png"); p.drawImage(rect, noSpecialStyleImage); + return SOLIDCHIP; } else { - assert(0 <= index && index < getChipCount()); - CustomStyleManager::PatternData pattern = - styleManager()->getPattern(index - 1); - p.drawImage(rect, *pattern.m_image); + auto &data = m_manager->getData(index - 1); + p.drawImage(rect, data.image); + return data.markPinToTop ? PINNEDCHIP : COMMONCHIP; } } @@ -2128,393 +2209,191 @@ void VectorBrushStyleChooserPage::onSelect(int index) { if (index < 0 || index >= getChipCount()) return; if (index > 0) { - --index; - - CustomStyleManager::PatternData pattern = styleManager()->getPattern(index); - - if (m_currentIndex < 0) return; + auto &data = m_manager->getData(index - 1); - std::string name = pattern.m_patternName; - assert(pattern.m_isVector); - if (!pattern.m_isVector) return; + std::string name = data.name.toStdString(); + assert(data.isVector); // must be Vector + if (!data.isVector) return; TVectorBrushStyle cs(name); emit styleSelected(cs); } else { - TSolidColorStyle cs(TPixel32::Black); - emit styleSelected(cs); + static TSolidColorStyle noStyle(TPixel32::Black); + emit styleSelected(noStyle); } } -//***************************************************************************** -// TextureStyleChooser definition -//***************************************************************************** - -struct Texture { - TRasterP m_raster; - QString m_name; -}; - -//----------------------------------------------------------------------------- - -class TextureStyleChooserPage final : public StyleChooserPage { - static std::vector m_textures; - static bool m_loaded; - -public: - TextureStyleChooserPage(QWidget *parent = 0) : StyleChooserPage(parent) {} - - bool loadIfNeeded() override { - if (!m_loaded) { - loadItems(); - m_loaded = true; - return true; - } else - return false; - } - - int getChipCount() const override { return m_textures.size(); } - - static void loadTexture(const TFilePath &fp); - static void loadItems(); - - void drawChip(QPainter &p, QRect rect, int index) override { - assert(0 <= index && index < getChipCount()); - p.drawImage(rect, rasterToQImage(m_textures[index].m_raster)); - } - - void onSelect(int index) override; - - bool event(QEvent *e) override; -}; - //----------------------------------------------------------------------------- -std::vector TextureStyleChooserPage::m_textures; -bool TextureStyleChooserPage::m_loaded(false); +bool VectorBrushStyleChooserPage::isSameStyle(const TColorStyleP style, + int index) { + if (index > 0) { + auto &data = m_manager->getData(index - 1); + if (!data.isVector) return false; // must be Vector + return style->getBrushIdHash() == data.hash; + } else + return style->getBrushIdHash() == TSolidColorStyle::staticBrushIdHash(); +} //----------------------------------------------------------------------------- -void TextureStyleChooserPage::loadTexture(const TFilePath &fp) { - if (fp == TFilePath()) { - TRaster32P ras(25, 25); - TTextureStyle::fillCustomTextureIcon(ras); - // ras->fill(TPixel::Blue); - Texture customText = {ras, QString("")}; - - m_textures.push_back(customText); - return; - } - - TRasterP ras; - TImageReader::load(fp, ras); - if (!ras || ras->getLx() < 2 || ras->getLy() < 2) return; +QString VectorBrushStyleChooserPage::getChipDescription(int index) { + if (index > 0) + return m_manager->getData(index - 1).desc; + else + return QObject::tr("Plain color", "VectorBrushStyleChooserPage"); +} - TRaster32P ras32 = ras; - if (!ras32) return; +//***************************************************************************** +// TextureStyleChooser implementation +//***************************************************************************** - TDimension d(2, 2); - while (d.lx < 256 && d.lx * 2 <= ras32->getLx()) d.lx *= 2; - while (d.ly < 256 && d.ly * 2 <= ras32->getLy()) d.ly *= 2; +int TextureStyleChooserPage::drawChip(QPainter &p, QRect rect, int index) { + assert(0 <= index && index < getChipCount()); - TRaster32P texture; - if (d == ras32->getSize()) - texture = ras32; - else { - texture = TRaster32P(d); - TScale sc((double)texture->getLx() / ras32->getLx(), - (double)texture->getLy() / ras32->getLy()); - TRop::resample(texture, ras32, sc); + if (index == 0) { + static QImage noStyleImage(":Resources/no_texturestyle.png"); + p.drawImage(rect, noStyleImage); + return SOLIDCHIP; + } else { + auto &data = m_manager->getData(index - 1); + p.drawImage(rect, data.image); + return data.markPinToTop ? PINNEDCHIP : COMMONCHIP; } - - Texture text = {texture, QString::fromStdWString(fp.getLevelNameW())}; - - m_textures.push_back(text); } //----------------------------------------------------------------------------- -void TextureStyleChooserPage::loadItems() { - m_textures.clear(); - if (getRootPath() == TFilePath()) return; - TFilePath texturePath = getRootPath() + "textures"; - TFilePathSet fps; - try { - fps = TSystem::readDirectory(texturePath); - } catch (...) { - return; +void TextureStyleChooserPage::onSelect(int index) { + assert(0 <= index && index < getChipCount()); + + if (index == 0) { + static TSolidColorStyle noStyle(TPixel32::Black); + emit styleSelected(noStyle); + } else { + auto &data = m_manager->getData(index - 1); + + TTextureStyle style(data.raster, TFilePath(data.name.toStdWString())); + emit styleSelected(style); } - if (fps.empty()) return; - int count = 0; - for (TFilePathSet::iterator it = fps.begin(); it != fps.end(); it++) - if (TFileType::getInfo(*it) == TFileType::RASTER_IMAGE) { - try { - loadTexture(*it); - ++count; - } catch (...) { - } - } - loadTexture(TFilePath()); // custom texture } //----------------------------------------------------------------------------- -void TextureStyleChooserPage::onSelect(int index) { - assert(0 <= index && index < (int)m_textures.size()); - - TTextureStyle style(m_textures[index].m_raster, - TFilePath(m_textures[index].m_name.toStdWString())); - emit styleSelected(style); +bool TextureStyleChooserPage::isSameStyle(const TColorStyleP style, int index) { + if (index > 0) + return style->getBrushIdHash() == m_manager->getData(index - 1).hash; + else + return style->getBrushIdHash() == TSolidColorStyle::staticBrushIdHash(); } //----------------------------------------------------------------------------- -bool TextureStyleChooserPage::event(QEvent *e) { - if (e->type() == QEvent::ToolTip) { - QHelpEvent *helpEvent = dynamic_cast(e); - QString toolTip; - QPoint pos = helpEvent->pos(); - int index = posToIndex(pos); - if (index >= 0 && index < (int)m_textures.size()) { - toolTip = m_textures[index].m_name; - QToolTip::showText( - helpEvent->globalPos(), - toolTip != QString() - ? toolTip - : QObject::tr("Custom Texture", "TextureStyleChooserPage")); - } - e->accept(); - } - return StyleChooserPage::event(e); +QString TextureStyleChooserPage::getChipDescription(int index) { + if (index > 0) + return m_manager->getData(index - 1).desc; + else + return QObject::tr("Plain color", "TextureStyleChooserPage"); } //***************************************************************************** -// MyPaintBrushStyleChooserPage definition +// MyPaintBrushStyleChooserPage implementation //***************************************************************************** -class MyPaintBrushStyleChooserPage final : public StyleChooserPage { -public: - struct Brush { - TRasterP m_raster; - QString m_name; - }; - -private: - static std::vector m_brushes; - -public: - MyPaintBrushStyleChooserPage(QWidget *parent = 0) : StyleChooserPage(parent) { - m_chipSize = QSize(64, 64); - } - - bool loadIfNeeded() override { - static bool m_loaded = false; - if (!m_loaded) { - loadItems(); - m_loaded = true; - return true; - } else - return false; - } - - int getChipCount() const override { return m_brushes.size() + 1; } - - static void loadItems(); - - void drawChip(QPainter &p, QRect rect, int index) override { - assert(0 <= index && index <= (int)m_brushes.size()); +int MyPaintBrushStyleChooserPage::drawChip(QPainter &p, QRect rect, int index) { + assert(0 <= index && index < getChipCount()); + if (index == 0) { static QImage noStyleImage(":Resources/no_mypaintbrush.png"); - p.drawImage(rect, index == 0 - ? noStyleImage - : rasterToQImage(m_brushes[index - 1].getPreview())); + p.drawImage(rect, noStyleImage); + return SOLIDCHIP; + } else { + auto &data = m_manager->getData(index - 1); + p.drawImage(rect, data.image); + return data.markPinToTop ? PINNEDCHIP : COMMONCHIP; } +} - void onSelect(int index) override { - assert(0 <= index && index <= (int)m_brushes.size()); - static TSolidColorStyle noStyle(TPixel32::Black); - if (index == 0) { - emit styleSelected(noStyle); - } else { - emit styleSelected(m_brushes[index - 1]); - } - } +//----------------------------------------------------------------------------- - bool event(QEvent *e) override { +void MyPaintBrushStyleChooserPage::onSelect(int index) { + assert(0 <= index && index < getChipCount()); + if (index == 0) { static TSolidColorStyle noStyle(TPixel32::Black); - if (e->type() == QEvent::ToolTip) { - QHelpEvent *helpEvent = dynamic_cast(e); - QString toolTip; - QPoint pos = helpEvent->pos(); - int index = posToIndex(pos); - if (index == 0) { - toolTip = QObject::tr("Plain color", "MyPaintBrushStyleChooserPage"); - } else if (index > 0 && index <= (int)m_brushes.size()) { - toolTip = m_brushes[index - 1].getPath().getQString(); - } - QToolTip::showText(helpEvent->globalPos(), toolTip); - e->accept(); - } - return StyleChooserPage::event(e); + emit styleSelected(noStyle); + } else { + --index; + emit styleSelected(getBrush(index)); } -}; +} //----------------------------------------------------------------------------- -std::vector MyPaintBrushStyleChooserPage::m_brushes; +bool MyPaintBrushStyleChooserPage::isSameStyle(const TColorStyleP style, + int index) { + if (index > 0) + return style->getBrushIdHash() == getBrush(index - 1).getBrushIdHash(); + else + return style->getBrushIdHash() == TSolidColorStyle::staticBrushIdHash(); +} //----------------------------------------------------------------------------- -void MyPaintBrushStyleChooserPage::loadItems() { - m_brushes.clear(); - std::set brushFiles; - - TFilePathSet dirs = TMyPaintBrushStyle::getBrushesDirs(); - for (TFilePathSet::iterator i = dirs.begin(); i != dirs.end(); ++i) { - TFileStatus fs(*i); - if (fs.doesExist() && fs.isDirectory()) { - TFilePathSet files = TSystem::readDirectoryTree(*i, false, true); - for (TFilePathSet::iterator j = files.begin(); j != files.end(); ++j) - if (j->getType() == TMyPaintBrushStyle::getBrushType()) - brushFiles.insert(*j - *i); - } - } - - // reserve memory to avoid reallocation - m_brushes.reserve(brushFiles.size()); - for (std::set::iterator i = brushFiles.begin(); - i != brushFiles.end(); ++i) - m_brushes.push_back(TMyPaintBrushStyle(*i)); +QString MyPaintBrushStyleChooserPage::getChipDescription(int index) { + if (index > 0) + return m_manager->getData(index - 1).desc; + else + return QObject::tr("Plain color", "MyPaintBrushStyleChooserPage"); } //***************************************************************************** -// SpecialStyleChooser definition +// SpecialStyleChooser implementation //***************************************************************************** -class SpecialStyleChooserPage final : public StyleChooserPage { - static std::vector> m_customStyles; - static bool m_loaded; - -public: - SpecialStyleChooserPage(QWidget *parent = 0, - const TFilePath &rootDir = TFilePath()) - : StyleChooserPage(parent) {} - - bool loadIfNeeded() override { - if (!m_loaded) { - loadItems(); - m_loaded = true; - return true; - } else - return false; - } - int getChipCount() const override { return m_customStyles.size(); } - - void loadItems(); - - void drawChip(QPainter &p, QRect rect, int index) override; - void onSelect(int index) override; - bool event(QEvent *e) override; -}; - -//----------------------------------------------------------------------------- - -std::vector> SpecialStyleChooserPage::m_customStyles; -bool SpecialStyleChooserPage::m_loaded(false); - -//----------------------------------------------------------------------------- - -void SpecialStyleChooserPage::loadItems() { - std::vector tags; - TColorStyle::getAllTags(tags); - - int chipCount = 0; - - for (int j = 0; j < (int)tags.size(); j++) { - int tagId = tags[j]; - if (tagId == 3 || // solid color - tagId == 4 || // texture - tagId == 100 || // obsolete imagepattern id - tagId == 2000 || // imagepattern - tagId == 2800 || // imagepattern - tagId == 2001 || // cleanup - tagId == 2002 || // black cleanup - tagId == 3000 || // vector brush - tagId == 4001 // mypaint brush - ) - continue; - - TColorStyle *style = TColorStyle::create(tagId); - if (style->isRasterStyle()) { - delete style; - continue; - } - TDimension chipSize(getChipSize().width(), getChipSize().height()); - QImage *image = new QImage(rasterToQImage(style->getIcon(chipSize), false)); - m_customStyles.push_back(std::make_pair(tagId, image)); - delete style; - } -} - -//----------------------------------------------------------------------------- - -void SpecialStyleChooserPage::drawChip(QPainter &p, QRect rect, int index) { +int SpecialStyleChooserPage::drawChip(QPainter &p, QRect rect, int index) { if (index == 0) { static QImage noSpecialStyleImage(":Resources/no_specialstyle.png"); p.drawImage(rect, noSpecialStyleImage); + return SOLIDCHIP; } else { - int j = index - 1; - if (0 <= j && j < (int)m_customStyles.size()) - p.drawImage(rect, *m_customStyles[j].second); - else - p.fillRect(rect, QBrush(QColor(255, 0, 0))); + auto &data = m_manager->getData(index - 1); + p.drawImage(rect, data.image); + return data.markPinToTop ? PINNEDCHIP : COMMONCHIP; } } //----------------------------------------------------------------------------- void SpecialStyleChooserPage::onSelect(int index) { - assert(0 <= index && index < (int)m_customStyles.size()); + assert(0 <= index && index < getChipCount()); TColorStyle *cs = 0; - if (m_currentIndex < 0) return; + // if (m_currentIndex < 0) return; if (index == 0) cs = new TSolidColorStyle(TPixel32::Black); else { - int j = index - 1; - assert(0 <= j && j < (int)m_customStyles.size()); - int tagId = m_customStyles[j].first; - cs = TColorStyle::create(tagId); + auto &data = m_manager->getData(index - 1); + + cs = TColorStyle::create(data.tagId); } + emit styleSelected(*cs); } //----------------------------------------------------------------------------- -bool SpecialStyleChooserPage::event(QEvent *e) { - if (e->type() == QEvent::ToolTip) { - QHelpEvent *helpEvent = dynamic_cast(e); - QString toolTip; - QPoint pos = helpEvent->pos(); - int index = posToIndex(pos); - if (index == 0) - toolTip = QObject::tr("Plain color", "SpecialStyleChooserPage"); - else { - int j = index - 1; - if (0 <= j && j < (int)m_customStyles.size()) { - int tagId = m_customStyles[j].first; - TColorStyle *cs = TColorStyle::create(tagId); - if (cs) { - toolTip = cs->getDescription(); - delete cs; - } - } - } - if (toolTip != "") - QToolTip::showText(helpEvent->globalPos(), toolTip); - else - QToolTip::hideText(); - e->accept(); - } - return StyleChooserPage::event(e); +bool SpecialStyleChooserPage::isSameStyle(const TColorStyleP style, int index) { + if (index > 0) + return style->getBrushIdHash() == m_manager->getData(index - 1).hash; + else + return style->getBrushIdHash() == TSolidColorStyle::staticBrushIdHash(); +} + +//----------------------------------------------------------------------------- + +QString SpecialStyleChooserPage::getChipDescription(int index) { + if (index > 0) + return m_manager->getData(index - 1).desc; + else + return QObject::tr("Plain color", "SpecialStyleChooserPage"); } //============================================================================= @@ -3019,11 +2898,11 @@ StyleEditor::StyleEditor(PaletteController *paletteController, QWidget *parent) m_colorParameterSelector = new ColorParameterSelector(this); m_plainColorPage = new PlainColorPage(0); - m_textureStylePage = new TextureStyleChooserPage(0); - m_specialStylePage = new SpecialStyleChooserPage(0); - m_customStylePage = new CustomStyleChooserPage(0); - m_vectorBrushesStylePage = new VectorBrushStyleChooserPage(0); - m_mypaintBrushesStylePage = new MyPaintBrushStyleChooserPage(0); + m_textureStylePage = new TextureStyleChooserPage(this, 0); + m_specialStylePage = new SpecialStyleChooserPage(this, 0); + m_customStylePage = new CustomStyleChooserPage(this, 0); + m_vectorBrushesStylePage = new VectorBrushStyleChooserPage(this, 0); + m_mypaintBrushesStylePage = new MyPaintBrushStyleChooserPage(this, 0); m_settingsPage = new SettingsPage(0); QWidget *emptyPage = new StyleEditorPage(0); @@ -3031,13 +2910,17 @@ StyleEditor::StyleEditor(PaletteController *paletteController, QWidget *parent) // For the plainColorPage and the settingsPage // I create a "fake" QScrollArea (without ScrollingBar // in order to use the styleSheet to stylish its background - QScrollArea *plainArea = makeChooserPageWithoutScrollBar(m_plainColorPage); - QScrollArea *textureArea = makeChooserPage(m_textureStylePage); - QScrollArea *mypaintBrushesArea = makeChooserPage(m_mypaintBrushesStylePage); + QScrollArea *plainArea = makeChooserPageWithoutScrollBar(m_plainColorPage); + QScrollArea *textureArea = + makeChooserPageWithoutScrollBar(createTexturePage()); + QScrollArea *mypaintBrushesArea = + makeChooserPageWithoutScrollBar(createMyPaintPage()); QScrollArea *settingsArea = makeChooserPageWithoutScrollBar(m_settingsPage); QScrollArea *vectorOutsideArea = makeChooserPageWithoutScrollBar(createVectorPage()); + textureArea->setMinimumWidth(50); vectorOutsideArea->setMinimumWidth(50); + mypaintBrushesArea->setMinimumWidth(50); m_styleChooser = new QStackedWidget(this); m_styleChooser->addWidget(plainArea); @@ -3159,28 +3042,32 @@ QFrame *StyleEditor::createBottomWidget() { m_toolBar = new QToolBar(this); m_toolBar->setMovable(false); m_toolBar->setMaximumHeight(22); - QMenu *menu = new QMenu(); - m_wheelAction = new QAction(tr("Wheel"), this); - m_hsvAction = new QAction(tr("HSV"), this); - m_alphaAction = new QAction(tr("Alpha"), this); - m_rgbAction = new QAction(tr("RGB"), this); - m_hexAction = new QAction(tr("Hex"), this); + QMenu *menu = new QMenu(); + m_wheelAction = new QAction(tr("Wheel"), this); + m_hsvAction = new QAction(tr("HSV"), this); + m_alphaAction = new QAction(tr("Alpha"), this); + m_rgbAction = new QAction(tr("RGB"), this); + m_hexAction = new QAction(tr("Hex"), this); + m_searchAction = new QAction(tr("Search"), this); m_wheelAction->setCheckable(true); m_hsvAction->setCheckable(true); m_alphaAction->setCheckable(true); m_rgbAction->setCheckable(true); m_hexAction->setCheckable(true); + m_searchAction->setCheckable(true); m_wheelAction->setChecked(true); m_hsvAction->setChecked(true); m_alphaAction->setChecked(true); m_rgbAction->setChecked(true); m_hexAction->setChecked(false); + m_searchAction->setChecked(false); menu->addAction(m_wheelAction); menu->addAction(m_hsvAction); menu->addAction(m_alphaAction); menu->addAction(m_rgbAction); menu->addAction(m_hexAction); + menu->addAction(m_searchAction); m_sliderAppearanceAG = new QActionGroup(this); QAction *relColorAct = @@ -3280,6 +3167,8 @@ QFrame *StyleEditor::createBottomWidget() { m_plainColorPage->m_rgbFrame, SLOT(setVisible(bool))); ret = ret && connect(m_hexAction, SIGNAL(toggled(bool)), m_hexLineEdit, SLOT(setVisible(bool))); + ret = ret && connect(m_searchAction, SIGNAL(toggled(bool)), this, + SLOT(onSearchVisible(bool))); ret = ret && connect(m_hexLineEdit, SIGNAL(editingFinished()), this, SLOT(onHexChanged())); ret = ret && connect(m_hexEditorAction, SIGNAL(triggered()), this, @@ -3299,13 +3188,75 @@ QFrame *StyleEditor::createBottomWidget() { //----------------------------------------------------------------------------- +QFrame *StyleEditor::createTexturePage() { + QFrame *outsideFrame = new QFrame(); + outsideFrame->setMinimumWidth(50); + + m_textureSearchFrame = new QFrame(); + m_textureSearchText = new QLineEdit(); + m_textureSearchClear = new QPushButton(tr("Clear Search")); + m_textureSearchClear->setDisabled(true); + m_textureSearchClear->setSizePolicy(QSizePolicy::Minimum, + QSizePolicy::Preferred); + + /* ------ layout ------ */ + QVBoxLayout *outsideLayout = new QVBoxLayout(); + outsideLayout->setMargin(0); + outsideLayout->setSpacing(0); + outsideLayout->setSizeConstraint(QLayout::SetNoConstraint); + { + QVBoxLayout *insideLayout = new QVBoxLayout(); + insideLayout->setMargin(0); + insideLayout->setSpacing(0); + insideLayout->setSizeConstraint(QLayout::SetNoConstraint); + { insideLayout->addWidget(m_textureStylePage); } + + QFrame *insideFrame = new QFrame(); + insideFrame->setMinimumWidth(50); + insideFrame->setLayout(insideLayout); + m_textureArea = makeChooserPage(insideFrame); + m_textureArea->setMinimumWidth(50); + outsideLayout->addWidget(m_textureArea); + + QHBoxLayout *searchLayout = new QHBoxLayout(); + searchLayout->setMargin(2); + searchLayout->setSpacing(0); + searchLayout->setSizeConstraint(QLayout::SetNoConstraint); + { + searchLayout->addWidget(m_textureSearchText); + searchLayout->addWidget(m_textureSearchClear); + } + m_textureSearchFrame->setLayout(searchLayout); + outsideLayout->addWidget(m_textureSearchFrame); + } + outsideFrame->setLayout(outsideLayout); + + /* ------ signal-slot connections ------ */ + bool ret = true; + ret = + ret && connect(m_textureSearchText, SIGNAL(textChanged(const QString &)), + this, SLOT(onTextureSearch(const QString &))); + ret = ret && connect(m_textureSearchClear, SIGNAL(clicked()), this, + SLOT(onTextureClearSearch())); + return outsideFrame; +} + +//----------------------------------------------------------------------------- + QFrame *StyleEditor::createVectorPage() { - QFrame *vectorOutsideFrame = new QFrame(this); + QFrame *vectorOutsideFrame = new QFrame(); vectorOutsideFrame->setMinimumWidth(50); - QPushButton *specialButton = new QPushButton(tr("Generated"), this); - QPushButton *customButton = new QPushButton(tr("Trail"), this); - QPushButton *vectorBrushButton = new QPushButton(tr("Vector Brush"), this); + QPushButton *specialButton = new QPushButton(tr("Generated")); + QPushButton *customButton = new QPushButton(tr("Trail")); + QPushButton *vectorBrushButton = new QPushButton(tr("Vector Brush")); + + m_vectorsSearchFrame = new QFrame(); + m_vectorsSearchText = new QLineEdit(); + m_vectorsSearchClear = new QPushButton(tr("Clear Search")); + m_vectorsSearchClear->setDisabled(true); + m_vectorsSearchClear->setSizePolicy(QSizePolicy::Minimum, + QSizePolicy::Preferred); specialButton->setCheckable(true); customButton->setCheckable(true); @@ -3338,12 +3289,23 @@ QFrame *StyleEditor::createVectorPage() { vectorLayout->addWidget(m_customStylePage); vectorLayout->addWidget(m_vectorBrushesStylePage); } - QFrame *vectorFrame = new QFrame(this); + QFrame *vectorFrame = new QFrame(); vectorFrame->setMinimumWidth(50); vectorFrame->setLayout(vectorLayout); - m_vectorArea = makeChooserPage(vectorFrame); - m_vectorArea->setMinimumWidth(50); - vectorOutsideLayout->addWidget(m_vectorArea); + m_vectorsArea = makeChooserPage(vectorFrame); + m_vectorsArea->setMinimumWidth(50); + vectorOutsideLayout->addWidget(m_vectorsArea); + + QHBoxLayout *searchLayout = new QHBoxLayout(); + searchLayout->setMargin(2); + searchLayout->setSpacing(0); + searchLayout->setSizeConstraint(QLayout::SetNoConstraint); + { + searchLayout->addWidget(m_vectorsSearchText); + searchLayout->addWidget(m_vectorsSearchClear); + } + m_vectorsSearchFrame->setLayout(searchLayout); + vectorOutsideLayout->addWidget(m_vectorsSearchFrame); } vectorOutsideFrame->setLayout(vectorOutsideLayout); @@ -3355,12 +3317,123 @@ QFrame *StyleEditor::createVectorPage() { SLOT(onCustomButtonToggled(bool))); ret = ret && connect(vectorBrushButton, SIGNAL(toggled(bool)), this, SLOT(onVectorBrushButtonToggled(bool))); + ret = + ret && connect(m_vectorsSearchText, SIGNAL(textChanged(const QString &)), + this, SLOT(onVectorsSearch(const QString &))); + ret = ret && connect(m_vectorsSearchClear, SIGNAL(clicked()), this, + SLOT(onVectorsClearSearch())); + assert(ret); return vectorOutsideFrame; } //----------------------------------------------------------------------------- +QFrame *StyleEditor::createMyPaintPage() { + QFrame *outsideFrame = new QFrame(); + outsideFrame->setMinimumWidth(50); + + m_mypaintSearchFrame = new QFrame(); + m_mypaintSearchText = new QLineEdit(); + m_mypaintSearchClear = new QPushButton(tr("Clear Search")); + m_mypaintSearchClear->setDisabled(true); + m_mypaintSearchClear->setSizePolicy(QSizePolicy::Minimum, + QSizePolicy::Preferred); + + /* ------ layout ------ */ + QVBoxLayout *outsideLayout = new QVBoxLayout(); + outsideLayout->setMargin(0); + outsideLayout->setSpacing(0); + outsideLayout->setSizeConstraint(QLayout::SetNoConstraint); + { + QVBoxLayout *insideLayout = new QVBoxLayout(); + insideLayout->setMargin(0); + insideLayout->setSpacing(0); + insideLayout->setSizeConstraint(QLayout::SetNoConstraint); + { insideLayout->addWidget(m_mypaintBrushesStylePage); } + QFrame *insideFrame = new QFrame(); + insideFrame->setMinimumWidth(50); + insideFrame->setLayout(insideLayout); + m_mypaintArea = makeChooserPage(insideFrame); + m_mypaintArea->setMinimumWidth(50); + outsideLayout->addWidget(m_mypaintArea); + + QHBoxLayout *searchLayout = new QHBoxLayout(); + searchLayout->setMargin(2); + searchLayout->setSpacing(0); + searchLayout->setSizeConstraint(QLayout::SetNoConstraint); + { + searchLayout->addWidget(m_mypaintSearchText); + searchLayout->addWidget(m_mypaintSearchClear); + } + m_mypaintSearchFrame->setLayout(searchLayout); + outsideLayout->addWidget(m_mypaintSearchFrame); + } + outsideFrame->setLayout(outsideLayout); + + /* ------ signal-slot connections ------ */ + bool ret = true; + ret = + ret && connect(m_mypaintSearchText, SIGNAL(textChanged(const QString &)), + this, SLOT(onMyPaintSearch(const QString &))); + ret = ret && connect(m_mypaintSearchClear, SIGNAL(clicked()), this, + SLOT(onMyPaintClearSearch())); + + assert(ret); + return outsideFrame; +} + +//----------------------------------------------------------------------------- + +void StyleEditor::onTextureSearch(const QString &search) { + m_textureSearchClear->setDisabled(search.isEmpty()); + m_textureStylePage->applyFilter(search); + m_textureStylePage->computeSize(); +} + +//----------------------------------------------------------------------------- + +void StyleEditor::onTextureClearSearch() { + m_textureSearchText->setText(""); + m_textureSearchText->setFocus(); +} + +//----------------------------------------------------------------------------- + +void StyleEditor::onVectorsSearch(const QString &search) { + m_vectorsSearchClear->setDisabled(search.isEmpty()); + m_specialStylePage->applyFilter(search); + m_customStylePage->applyFilter(search); + m_vectorBrushesStylePage->applyFilter(search); + m_specialStylePage->computeSize(); + m_customStylePage->computeSize(); + m_vectorBrushesStylePage->computeSize(); +} + +//----------------------------------------------------------------------------- + +void StyleEditor::onVectorsClearSearch() { + m_vectorsSearchText->setText(""); + m_vectorsSearchText->setFocus(); +} + +//----------------------------------------------------------------------------- + +void StyleEditor::onMyPaintSearch(const QString &search) { + m_mypaintSearchClear->setDisabled(search.isEmpty()); + m_mypaintBrushesStylePage->applyFilter(search); + m_mypaintBrushesStylePage->computeSize(); +} + +//----------------------------------------------------------------------------- + +void StyleEditor::onMyPaintClearSearch() { + m_mypaintSearchText->setText(""); + m_mypaintSearchText->setFocus(); +} + +//----------------------------------------------------------------------------- + void StyleEditor::updateTabBar() { m_styleBar->clearTabBar(); if (m_enabled && !m_enabledOnlyFirstTab && !m_enabledFirstAndLastTab) { @@ -3411,6 +3484,7 @@ void StyleEditor::showEvent(QShowEvent *) { m_plainColorPage->m_alphaFrame->setVisible(m_alphaAction->isChecked()); m_plainColorPage->m_rgbFrame->setVisible(m_rgbAction->isChecked()); m_hexLineEdit->setVisible(m_hexAction->isChecked()); + onSearchVisible(m_searchAction->isChecked()); updateOrientationButton(); assert(ret); } @@ -3435,6 +3509,17 @@ void StyleEditor::updateOrientationButton() { //----------------------------------------------------------------------------- +void StyleEditor::updateStylePages() { + // Refresh all pages + m_textureStylePage->update(); + m_specialStylePage->update(); + m_customStylePage->update(); + m_vectorBrushesStylePage->update(); + m_mypaintBrushesStylePage->update(); +} + +//----------------------------------------------------------------------------- + void StyleEditor::onStyleSwitched() { TPalette *palette = getPalette(); @@ -3487,6 +3572,8 @@ void StyleEditor::onStyleSwitched() { m_parent->setWindowTitle(tr("Style Editor - No Valid Style Selected")); } enable(!isStyleNull && isValidIndex, isColorInField, isCleanUpPalette); + + updateStylePages(); } //----------------------------------------------------------------------------- @@ -3512,6 +3599,8 @@ void StyleEditor::onStyleChanged(bool isDragging) { *m_oldStyle, getColorParam()); // This line is needed for proper undo behavior m_hexLineEdit->setStyle(*m_editedStyle, getColorParam()); + + updateStylePages(); } //----------------------------------------------------------------------- @@ -3884,9 +3973,17 @@ void StyleEditor::onHexEditor() { //----------------------------------------------------------------------------- +void StyleEditor::onSearchVisible(bool on) { + m_textureSearchFrame->setVisible(on); + m_vectorsSearchFrame->setVisible(on); + m_mypaintSearchFrame->setVisible(on); +} + +//----------------------------------------------------------------------------- + void StyleEditor::onSpecialButtonToggled(bool on) { m_specialStylePage->setVisible(on); - m_vectorArea->widget()->resize(m_vectorArea->widget()->sizeHint()); + m_vectorsArea->widget()->resize(m_vectorsArea->widget()->sizeHint()); qApp->processEvents(); } @@ -3894,7 +3991,7 @@ void StyleEditor::onSpecialButtonToggled(bool on) { void StyleEditor::onCustomButtonToggled(bool on) { m_customStylePage->setVisible(on); - m_vectorArea->widget()->resize(m_vectorArea->widget()->sizeHint()); + m_vectorsArea->widget()->resize(m_vectorsArea->widget()->sizeHint()); qApp->processEvents(); } @@ -3902,7 +3999,7 @@ void StyleEditor::onCustomButtonToggled(bool on) { void StyleEditor::onVectorBrushButtonToggled(bool on) { m_vectorBrushesStylePage->setVisible(on); - m_vectorArea->widget()->resize(m_vectorArea->widget()->sizeHint()); + m_vectorsArea->widget()->resize(m_vectorsArea->widget()->sizeHint()); qApp->processEvents(); } @@ -3916,6 +4013,7 @@ void StyleEditor::save(QSettings &settings) const { if (m_alphaAction->isChecked()) visibleParts |= 0x04; if (m_rgbAction->isChecked()) visibleParts |= 0x08; if (m_hexAction->isChecked()) visibleParts |= 0x10; + if (m_searchAction->isChecked()) visibleParts |= 0x20; settings.setValue("visibleParts", visibleParts); settings.setValue("splitterState", m_plainColorPage->getSplitterState()); } @@ -3949,6 +4047,10 @@ void StyleEditor::load(QSettings &settings) { m_hexAction->setChecked(true); else m_hexAction->setChecked(false); + if (visiblePartsInt & 0x20) + m_searchAction->setChecked(true); + else + m_searchAction->setChecked(false); } QVariant splitterState = settings.value("splitterState"); if (splitterState.canConvert(QVariant::ByteArray))