1 /*! 2 @file 3 @author Albert Semenov 4 @date 08/2008 5 */ 6 #include "Precompiled.h" 7 #include "ColourPanel.h" 8 9 namespace demo 10 { 11 ColourPanel()12 ColourPanel::ColourPanel() 13 { 14 initialiseByAttributes(this); 15 16 mCurrentColour = MyGUI::Colour::Green; 17 mBaseColour = MyGUI::Colour::Green; 18 19 mColourRect->eventMouseButtonPressed += MyGUI::newDelegate(this, &ColourPanel::notifyMouseButtonPressed); 20 mColourRect->eventMouseDrag += MyGUI::newDelegate(this, &ColourPanel::notifyMouseDrag); 21 mImageColourPicker->eventMouseDrag += MyGUI::newDelegate(this, &ColourPanel::notifyMouseDrag); 22 mScrollRange->eventScrollChangePosition += MyGUI::newDelegate(this, &ColourPanel::notifyScrollChangePosition); 23 24 mEditRed->eventEditTextChange += MyGUI::newDelegate(this, &ColourPanel::notifyEditTextChange); 25 mEditGreen->eventEditTextChange += MyGUI::newDelegate(this, &ColourPanel::notifyEditTextChange); 26 mEditBlue->eventEditTextChange += MyGUI::newDelegate(this, &ColourPanel::notifyEditTextChange); 27 28 mOk->eventMouseButtonClick += MyGUI::newDelegate(this, &ColourPanel::notifyMouseButtonClick); 29 30 mColourRange.push_back(MyGUI::Colour(1, 0, 0)); 31 mColourRange.push_back(MyGUI::Colour(1, 0, 1)); 32 mColourRange.push_back(MyGUI::Colour(0, 0, 1)); 33 mColourRange.push_back(MyGUI::Colour(0, 1, 1)); 34 mColourRange.push_back(MyGUI::Colour(0, 1, 0)); 35 mColourRange.push_back(MyGUI::Colour(1, 1, 0)); 36 mColourRange.push_back(mColourRange[0]); 37 38 createTexture(); 39 40 updateFirst(); 41 } 42 ~ColourPanel()43 ColourPanel::~ColourPanel() 44 { 45 destroyTexture(); 46 } 47 notifyMouseButtonClick(MyGUI::Widget * _sender)48 void ColourPanel::notifyMouseButtonClick(MyGUI::Widget* _sender) 49 { 50 eventColourAccept(this); 51 } 52 updateFirst()53 void ColourPanel::updateFirst() 54 { 55 notifyScrollChangePosition(nullptr, mScrollRange->getScrollPosition()); 56 57 notifyMouseDrag(nullptr, 58 mImageColourPicker->getAbsoluteLeft() + (mColourRect->getWidth() / 2), 59 mImageColourPicker->getAbsoluteTop() + (mColourRect->getHeight() / 2), 60 MyGUI::MouseButton::Left); 61 } 62 createTexture()63 void ColourPanel::createTexture() 64 { 65 int size = 32; 66 mTexture = MyGUI::RenderManager::getInstance().createTexture("ColourGradient"); 67 mTexture->createManual(size, size, 68 MyGUI::TextureUsage::Static | MyGUI::TextureUsage::Write, 69 MyGUI::PixelFormat::R8G8B8A8); 70 71 mColourRect->setImageTexture("ColourGradient"); 72 } 73 destroyTexture()74 void ColourPanel::destroyTexture() 75 { 76 MyGUI::RenderManager::getInstance().destroyTexture( mTexture ); 77 mTexture = nullptr; 78 } 79 updateTexture(const MyGUI::Colour & _colour)80 void ColourPanel::updateTexture(const MyGUI::Colour& _colour) 81 { 82 size_t size = 32; 83 84 MyGUI::uint8* pDest = static_cast<MyGUI::uint8*>(mTexture->lock(MyGUI::TextureUsage::Write)); 85 86 for (size_t j = 0; j < size; j++) 87 for (size_t i = 0; i < size; i++) 88 { 89 float x = (float)i / size; 90 float y = (float)j / size; 91 *pDest++ = MyGUI::uint8((1.0f - y) * (_colour.blue * x + (1.0f - x)) * 255); // B 92 *pDest++ = MyGUI::uint8((1.0f - y) * (_colour.green * x + (1.0f - x)) * 255); // G 93 *pDest++ = MyGUI::uint8((1.0f - y) * (_colour.red * x + (1.0f - x)) * 255); // R 94 *pDest++ = 255; // A 95 } 96 97 // Unlock the pixel buffer 98 mTexture->unlock(); 99 } 100 notifyMouseDrag(MyGUI::Widget * _sender,int _left,int _top,MyGUI::MouseButton _id)101 void ColourPanel::notifyMouseDrag(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) 102 { 103 if (_id != MyGUI::MouseButton::Left) 104 return; 105 106 MyGUI::Widget* parent = mImageColourPicker->getParent(); 107 MyGUI::IntPoint point(_left - parent->getAbsoluteLeft(), _top - parent->getAbsoluteTop()); 108 109 if (point.left < 0) point.left = 0; 110 if (point.top < 0) point.top = 0; 111 if (point.left > mColourRect->getWidth()) point.left = mColourRect->getWidth(); 112 if (point.top > mColourRect->getHeight()) point.top = mColourRect->getHeight(); 113 114 mImageColourPicker->setPosition(point.left - (mImageColourPicker->getWidth() / 2), point.top - (mImageColourPicker->getHeight() / 2)); 115 116 updateFromPoint(point); 117 } 118 notifyMouseButtonPressed(MyGUI::Widget * _sender,int _left,int _top,MyGUI::MouseButton _id)119 void ColourPanel::notifyMouseButtonPressed(MyGUI::Widget* _sender, int _left, int _top, MyGUI::MouseButton _id) 120 { 121 if (_id == MyGUI::MouseButton::Left) 122 notifyMouseDrag(nullptr, _left, _top, _id); 123 } 124 updateFromPoint(const MyGUI::IntPoint & _point)125 void ColourPanel::updateFromPoint(const MyGUI::IntPoint& _point) 126 { 127 // get colour by cursor position Altren 09.2008 128 float x = 1.0f * _point.left / mColourRect->getWidth(); 129 float y = 1.0f * _point.top / mColourRect->getHeight(); 130 if (x > 1) x = 1; 131 else if (x < 0) x = 0; 132 if (y > 1) y = 1; 133 else if (y < 0) y = 0; 134 135 mCurrentColour.red = (1 - y) * (mBaseColour.red * x + MyGUI::Colour::White.red * (1 - x)); 136 mCurrentColour.green = (1 - y) * (mBaseColour.green * x + MyGUI::Colour::White.green * (1 - x)); 137 mCurrentColour.blue = (1 - y) * (mBaseColour.blue * x + MyGUI::Colour::White.blue * (1 - x)); 138 139 mColourView->setColour(mCurrentColour); 140 141 mEditRed->setCaption(MyGUI::utility::toString((int)(mCurrentColour.red * 255))); 142 mEditGreen->setCaption(MyGUI::utility::toString((int)(mCurrentColour.green * 255))); 143 mEditBlue->setCaption(MyGUI::utility::toString((int)(mCurrentColour.blue * 255))); 144 } 145 notifyScrollChangePosition(MyGUI::ScrollBar * _sender,size_t _position)146 void ColourPanel::notifyScrollChangePosition(MyGUI::ScrollBar* _sender, size_t _position) 147 { 148 float sector_size = (float)mScrollRange->getScrollRange() / 6.0f; 149 float sector_current = (float)_position / sector_size; 150 151 // current sector 152 size_t current = (size_t)sector_current; 153 assert(current < 6); 154 // смещение до следующего сектора от 0 до 1 155 float offfset = (sector_current - (float)current); 156 157 const MyGUI::Colour& from = mColourRange[current]; 158 const MyGUI::Colour& to = mColourRange[current + 1]; 159 160 mBaseColour.red = from.red + offfset * (to.red - from.red); 161 mBaseColour.green = from.green + offfset * (to.green - from.green); 162 mBaseColour.blue = from.blue + offfset * (to.blue - from.blue); 163 164 updateTexture(mBaseColour); 165 166 MyGUI::IntPoint point( 167 mImageColourPicker->getLeft() + (mImageColourPicker->getWidth() / 2), 168 mImageColourPicker->getTop() + (mImageColourPicker->getHeight() / 2)); 169 170 updateFromPoint(point); 171 } 172 notifyEditTextChange(MyGUI::EditBox * _sender)173 void ColourPanel::notifyEditTextChange(MyGUI::EditBox* _sender) 174 { 175 MyGUI::EditBox* edit = static_cast<MyGUI::EditBox*>(_sender); 176 size_t cursor = edit->getTextCursor(); 177 size_t num = MyGUI::utility::parseSizeT(edit->getOnlyText()); 178 if (num > 255) num = 255; 179 edit->setCaption(MyGUI::utility::toString(num)); 180 if (cursor < edit->getTextLength()) edit->setTextCursor(cursor); 181 182 MyGUI::Colour colour( 183 MyGUI::utility::parseFloat(mEditRed->getOnlyText()) / 255.0f, 184 MyGUI::utility::parseFloat(mEditGreen->getOnlyText()) / 255.0f, 185 MyGUI::utility::parseFloat(mEditBlue->getOnlyText()) / 255.0f); 186 187 updateFromColour(colour); 188 } 189 setColour(const MyGUI::Colour & _colour)190 void ColourPanel::setColour(const MyGUI::Colour& _colour) 191 { 192 MyGUI::Colour colour = getSaturate(_colour); 193 mEditRed->setCaption(MyGUI::utility::toString((int)(colour.red * 255))); 194 mEditGreen->setCaption(MyGUI::utility::toString((int)(colour.green * 255))); 195 mEditBlue->setCaption(MyGUI::utility::toString((int)(colour.blue * 255))); 196 197 updateFromColour(colour); 198 } 199 updateFromColour(const MyGUI::Colour & _colour)200 void ColourPanel::updateFromColour(const MyGUI::Colour& _colour) 201 { 202 mCurrentColour = _colour; 203 204 std::vector<float> vec; 205 vec.push_back(_colour.red); 206 vec.push_back(_colour.green); 207 vec.push_back(_colour.blue); 208 std::sort(vec.begin(), vec.end()); 209 210 MyGUI::IntPoint point((int)((1 - vec[0] / vec[2]) * mColourRect->getWidth()), (int)((1 - vec[2]) * mColourRect->getHeight())); 211 mImageColourPicker->setPosition(point.left - (mImageColourPicker->getWidth() / 2), point.top - (mImageColourPicker->getHeight() / 2)); 212 213 int iMax = (_colour.red == vec[2]) ? 0 : (_colour.green == vec[2]) ? 1 : 2; 214 int iMin = (_colour.red == vec[0]) ? 0 : (_colour.green == vec[0]) ? 1 : 2; 215 int iAvg = 3 - iMax - iMin; 216 217 if (iMin == iMax) // if gray colour - set base red 218 { 219 iMax = 0; 220 iMin = 1; 221 iAvg = 2; 222 byIndex(mBaseColour, iMin) = 0.; 223 byIndex(mBaseColour, iAvg) = 0.; 224 byIndex(mBaseColour, iMax) = 1.; 225 } 226 else 227 { 228 byIndex(mBaseColour, iMin) = 0.; 229 byIndex(mBaseColour, iAvg) = (vec[1] - vec[0]) / (vec[2] - vec[0]); 230 byIndex(mBaseColour, iMax) = 1.; 231 } 232 233 234 int i; 235 for (i = 0; i < 6; ++i) 236 { 237 if ((std::abs(byIndex(mColourRange[i], iMin) - byIndex(mBaseColour, iMin)) < 0.001f) && 238 (std::abs(byIndex(mColourRange[i], iMax) - byIndex(mBaseColour, iMax)) < 0.001f) && 239 (std::abs(byIndex(mColourRange[i+1], iMin) - byIndex(mBaseColour, iMin)) < 0.001f) && 240 (std::abs(byIndex(mColourRange[i+1], iMax) - byIndex(mBaseColour, iMax)) < 0.001f)) 241 break; 242 } 243 244 float sector_size = (float)mScrollRange->getScrollRange() / 6.0f; 245 size_t current = i; 246 247 float offset = byIndex(mBaseColour, iAvg); 248 if (byIndex(mColourRange[i+1], iAvg) < byIndex(mColourRange[i], iAvg)) offset = 1 - byIndex(mBaseColour, iAvg); 249 250 size_t pos = size_t((current + offset) * sector_size); 251 252 mScrollRange->setScrollPosition(pos); 253 254 // бонус для обрезки цвета под шкалу 255 mBaseColour.red = mColourRange[i].red + offset * (mColourRange[i+1].red - mColourRange[i].red); 256 mBaseColour.green = mColourRange[i].green + offset * (mColourRange[i+1].green - mColourRange[i].green); 257 mBaseColour.blue = mColourRange[i].blue + offset * (mColourRange[i+1].blue - mColourRange[i].blue); 258 259 updateTexture(mBaseColour); 260 261 mColourView->setColour(mCurrentColour); 262 } 263 getSaturate(const MyGUI::Colour & _colour) const264 MyGUI::Colour ColourPanel::getSaturate(const MyGUI::Colour& _colour) const 265 { 266 MyGUI::Colour colour = _colour; 267 if (colour.red < 0) 268 colour.red = 0; 269 else if (colour.red > 1) 270 colour.red = 1; 271 272 if (colour.green < 0) 273 colour.green = 0; 274 else if (colour.green > 1) 275 colour.green = 1; 276 277 if (colour.blue < 0) 278 colour.blue = 0; 279 else if (colour.blue > 1) 280 colour.blue = 1; 281 282 return colour; 283 } 284 byIndex(MyGUI::Colour & _colour,size_t _index)285 float& ColourPanel::byIndex(MyGUI::Colour& _colour, size_t _index) 286 { 287 if (_index == 0) return _colour.red; 288 else if (_index == 1) return _colour.green; 289 else if (_index == 2) return _colour.blue; 290 else return _colour.alpha; 291 } 292 getColour() const293 const MyGUI::Colour& ColourPanel::getColour() const 294 { 295 return mCurrentColour; 296 } 297 298 } // namespace demo 299