Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <com/sun/star/uno/XComponentContext.hpp>
21 : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
22 : #include <com/sun/star/beans/XPropertyAccess.hpp>
23 : #include <com/sun/star/lang/XInitialization.hpp>
24 : #include <com/sun/star/lang/XServiceInfo.hpp>
25 : #include <com/sun/star/datatransfer/XTransferable.hpp>
26 : #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
27 : #include <com/sun/star/awt/XWindow.hpp>
28 : #include <cppuhelper/compbase4.hxx>
29 : #include <cppuhelper/supportsservice.hxx>
30 : #include <comphelper/broadcasthelper.hxx>
31 : #include <vcl/dialog.hxx>
32 : #include <vcl/button.hxx>
33 : #include <vcl/fixed.hxx>
34 : #include <vcl/edit.hxx>
35 : #include <vcl/field.hxx>
36 : #include <vcl/bmpacc.hxx>
37 : #include <vcl/decoview.hxx>
38 : #include <vcl/svapp.hxx>
39 : #include <vcl/builderfactory.hxx>
40 : #include <toolkit/helper/vclunohelper.hxx>
41 : #include <sot/exchange.hxx>
42 : #include <sot/formats.hxx>
43 : #include <sax/tools/converter.hxx>
44 : #include <basegfx/color/bcolortools.hxx>
45 : #include "dialmgr.hxx"
46 : #include "colorpicker.hxx"
47 : #include <cmath>
48 : #include <limits>
49 :
50 : using namespace ::com::sun::star::uno;
51 : using namespace ::com::sun::star::lang;
52 : using namespace ::com::sun::star::ui::dialogs;
53 : using namespace ::com::sun::star::beans;
54 : using namespace ::basegfx;
55 :
56 : namespace cui
57 : {
58 : const sal_uInt16 COLORMODE_RGB = 0x10;
59 : const sal_uInt16 COLORMODE_HSV = 0x20;
60 :
61 : const sal_uInt16 COLORCOMP_RED = 0x10;
62 : const sal_uInt16 COLORCOMP_GREEN = 0x11;
63 : const sal_uInt16 COLORCOMP_BLUE = 0x12;
64 :
65 : const sal_uInt16 COLORCOMP_HUE = 0x20;
66 : const sal_uInt16 COLORCOMP_SAT = 0x21;
67 : const sal_uInt16 COLORCOMP_BRI = 0x22;
68 :
69 : const sal_uInt16 COLORCOMP_CYAN = 0x40;
70 : const sal_uInt16 COLORCOMP_YELLOW = 0x41;
71 : const sal_uInt16 COLORCOMP_MAGENTA = 0x42;
72 : const sal_uInt16 COLORCOMP_KEY = 0x43;
73 :
74 : // color space conversion helpers
75 :
76 0 : static void RGBtoHSV( double dR, double dG, double dB, double& dH, double& dS, double& dV )
77 : {
78 0 : BColor result = basegfx::tools::rgb2hsv( BColor( dR, dG, dB ) );
79 :
80 0 : dH = result.getX();
81 0 : dS = result.getY();
82 0 : dV = result.getZ();
83 0 : }
84 :
85 0 : static void HSVtoRGB(double dH, double dS, double dV, double& dR, double& dG, double& dB )
86 : {
87 0 : BColor result = basegfx::tools::hsv2rgb( BColor( dH, dS, dV ) );
88 :
89 0 : dR = result.getRed();
90 0 : dG = result.getGreen();
91 0 : dB = result.getBlue();
92 0 : }
93 :
94 : // CMYK values from 0 to 1
95 0 : static void CMYKtoRGB( double fCyan, double fMagenta, double fYellow, double fKey, double& dR, double& dG, double& dB )
96 : {
97 0 : fCyan = (fCyan * ( 1.0 - fKey )) + fKey;
98 0 : fMagenta = (fMagenta * ( 1.0 - fKey )) + fKey;
99 0 : fYellow = (fYellow * ( 1.0 - fKey )) + fKey;
100 :
101 0 : dR = std::max( std::min( ( 1.0 - fCyan ), 1.0), 0.0 );
102 0 : dG = std::max( std::min( ( 1.0 - fMagenta ), 1.0), 0.0 );
103 0 : dB = std::max( std::min( ( 1.0 - fYellow ), 1.0), 0.0 );
104 0 : }
105 :
106 : // CMY results from 0 to 1
107 0 : static void RGBtoCMYK( double dR, double dG, double dB, double& fCyan, double& fMagenta, double& fYellow, double& fKey )
108 : {
109 0 : fCyan = 1 - dR;
110 0 : fMagenta = 1 - dG;
111 0 : fYellow = 1 - dB;
112 :
113 : //CMYK and CMY values from 0 to 1
114 0 : fKey = 1.0;
115 0 : if( fCyan < fKey ) fKey = fCyan;
116 0 : if( fMagenta < fKey ) fKey = fMagenta;
117 0 : if( fYellow < fKey ) fKey = fYellow;
118 :
119 0 : if( fKey >= 1.0 )
120 : {
121 : //Black
122 0 : fCyan = 0.0;
123 0 : fMagenta = 0.0;
124 0 : fYellow = 0.0;
125 : }
126 : else
127 : {
128 0 : fCyan = ( fCyan - fKey ) / ( 1.0 - fKey );
129 0 : fMagenta = ( fMagenta - fKey ) / ( 1.0 - fKey );
130 0 : fYellow = ( fYellow - fKey ) / ( 1.0 - fKey );
131 : }
132 0 : }
133 :
134 0 : class HexColorControl : public Edit
135 : {
136 : public:
137 : HexColorControl( vcl::Window* pParent, const WinBits& nStyle );
138 :
139 : virtual bool PreNotify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
140 : virtual void Paste() SAL_OVERRIDE;
141 :
142 : void SetColor( sal_Int32 nColor );
143 : sal_Int32 GetColor();
144 :
145 : private:
146 : static bool ImplProcessKeyInput( const KeyEvent& rKEv );
147 : };
148 :
149 0 : HexColorControl::HexColorControl( vcl::Window* pParent, const WinBits& nStyle )
150 0 : : Edit(pParent, nStyle)
151 : {
152 0 : SetMaxTextLen( 6 );
153 0 : }
154 :
155 0 : VCL_BUILDER_FACTORY_ARGS(HexColorControl, WB_BORDER)
156 :
157 0 : void HexColorControl::SetColor(sal_Int32 nColor)
158 : {
159 0 : OUStringBuffer aBuffer;
160 0 : sax::Converter::convertColor(aBuffer, nColor);
161 0 : SetText(aBuffer.makeStringAndClear().copy(1));
162 0 : }
163 :
164 0 : sal_Int32 HexColorControl::GetColor()
165 : {
166 0 : sal_Int32 nColor = -1;
167 :
168 0 : OUString aStr("#");
169 0 : aStr += GetText();
170 0 : sal_Int32 nLen = aStr.getLength();
171 :
172 0 : if (nLen < 7)
173 : {
174 : static const sal_Char* pNullStr = "000000";
175 0 : aStr += OUString::createFromAscii( &pNullStr[nLen-1] );
176 : }
177 :
178 0 : sax::Converter::convertColor(nColor, aStr);
179 :
180 0 : if (nColor == -1)
181 0 : SetControlBackground(Color(COL_RED));
182 : else
183 0 : SetControlBackground();
184 :
185 0 : return nColor;
186 : }
187 :
188 0 : bool HexColorControl::PreNotify( NotifyEvent& rNEvt )
189 : {
190 0 : if ( (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
191 : {
192 0 : if ( ImplProcessKeyInput( *rNEvt.GetKeyEvent() ) )
193 0 : return true;
194 : }
195 :
196 0 : return Edit::PreNotify( rNEvt );
197 : }
198 :
199 0 : void HexColorControl::Paste()
200 : {
201 0 : css::uno::Reference<css::datatransfer::clipboard::XClipboard> aClipboard(GetClipboard());
202 0 : if (aClipboard.is())
203 : {
204 0 : css::uno::Reference<css::datatransfer::XTransferable> xDataObj;
205 :
206 : try
207 : {
208 0 : SolarMutexReleaser aReleaser;
209 0 : xDataObj = aClipboard->getContents();
210 : }
211 0 : catch (const css::uno::Exception&)
212 : {
213 : }
214 :
215 0 : if (xDataObj.is())
216 : {
217 0 : css::datatransfer::DataFlavor aFlavor;
218 0 : SotExchange::GetFormatDataFlavor(SotClipboardFormatId::STRING, aFlavor);
219 : try
220 : {
221 0 : css::uno::Any aData = xDataObj->getTransferData(aFlavor);
222 0 : OUString aText;
223 0 : aData >>= aText;
224 :
225 0 : if( !aText.isEmpty() && aText.startsWith( "#" ) )
226 0 : aText = aText.copy(1);
227 :
228 0 : if( aText.getLength() > 6 )
229 0 : aText = aText.copy( 0, 6 );
230 :
231 0 : SetText(aText);
232 : }
233 0 : catch(const css::uno::Exception&)
234 0 : {}
235 0 : }
236 0 : }
237 0 : }
238 :
239 0 : bool HexColorControl::ImplProcessKeyInput( const KeyEvent& rKEv )
240 : {
241 0 : const vcl::KeyCode& rKeyCode = rKEv.GetKeyCode();
242 :
243 0 : if( rKeyCode.GetGroup() == KEYGROUP_ALPHA && !rKeyCode.IsMod1() && !rKeyCode.IsMod2() )
244 : {
245 0 : if( (rKeyCode.GetCode() < KEY_A) || (rKeyCode.GetCode() > KEY_F) )
246 0 : return true;
247 : }
248 0 : else if( rKeyCode.GetGroup() == KEYGROUP_NUM )
249 : {
250 0 : if( rKeyCode.IsShift() )
251 0 : return true;
252 : }
253 0 : return false;
254 : }
255 :
256 0 : class ColorPreviewControl : public Control
257 : {
258 : public:
259 : ColorPreviewControl( vcl::Window* pParent, const WinBits& nStyle );
260 :
261 : virtual void Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect) SAL_OVERRIDE;
262 :
263 : void SetColor(const Color& rColor);
264 :
265 : private:
266 : Color maColor;
267 : };
268 :
269 0 : ColorPreviewControl::ColorPreviewControl(vcl::Window* pParent, const WinBits& nStyle)
270 0 : : Control(pParent, nStyle)
271 : {
272 0 : }
273 :
274 0 : VCL_BUILDER_DECL_FACTORY(ColorPreviewControl)
275 : {
276 0 : WinBits nBits = 0;
277 :
278 0 : OString sBorder = VclBuilder::extractCustomProperty(rMap);
279 0 : if (!sBorder.isEmpty())
280 0 : nBits |= WB_BORDER;
281 :
282 0 : rRet = VclPtr<ColorPreviewControl>::Create(pParent, nBits);
283 0 : }
284 :
285 0 : void ColorPreviewControl::SetColor( const Color& rCol )
286 : {
287 0 : if (rCol != maColor)
288 : {
289 0 : maColor = rCol;
290 0 : Invalidate();
291 : }
292 0 : }
293 :
294 0 : void ColorPreviewControl::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect)
295 : {
296 0 : rRenderContext.SetFillColor(maColor);
297 0 : rRenderContext.SetLineColor(maColor);
298 0 : rRenderContext.DrawRect(rRect);
299 0 : }
300 :
301 : enum ColorMode { HUE, SATURATION, BRIGHTNESS, RED, GREEN, BLUE };
302 : const ColorMode DefaultMode = HUE;
303 :
304 : class ColorFieldControl : public Control
305 : {
306 : public:
307 : ColorFieldControl(vcl::Window* pParent, const WinBits& nStyle);
308 : virtual ~ColorFieldControl();
309 :
310 : virtual void dispose() SAL_OVERRIDE;
311 :
312 : virtual void MouseMove( const MouseEvent& rMEvt ) SAL_OVERRIDE;
313 : virtual void MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
314 : virtual void MouseButtonUp( const MouseEvent& rMEvt ) SAL_OVERRIDE;
315 : virtual void KeyInput( const KeyEvent& rKEvt ) SAL_OVERRIDE;
316 : virtual void Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect) SAL_OVERRIDE;
317 : virtual void Resize() SAL_OVERRIDE;
318 :
319 : virtual Size GetOptimalSize() const SAL_OVERRIDE;
320 :
321 : void UpdateBitmap();
322 : void ShowPosition( const Point& rPos, bool bUpdate );
323 : void UpdatePosition();
324 : void Modify();
325 :
326 : void SetValues(Color aColor, ColorMode eMode, double x, double y);
327 0 : double GetX() { return mdX;}
328 0 : double GetY() { return mdY;}
329 :
330 : void KeyMove(int dx, int dy);
331 :
332 0 : void SetModifyHdl(Link<>& rLink) { maModifyHdl = rLink; }
333 :
334 : private:
335 : Link<> maModifyHdl;
336 : ColorMode meMode;
337 : Color maColor;
338 : double mdX;
339 : double mdY;
340 : Point maPosition;
341 : Bitmap* mpBitmap;
342 : std::vector<sal_uInt8> maRGB_Horiz;
343 : std::vector<sal_uInt16> maGrad_Horiz;
344 : std::vector<sal_uInt16> maPercent_Horiz;
345 : std::vector<sal_uInt8> maRGB_Vert;
346 : std::vector<sal_uInt16> maPercent_Vert;
347 : };
348 :
349 0 : ColorFieldControl::ColorFieldControl( vcl::Window* pParent, const WinBits& nStyle )
350 : : Control( pParent, nStyle )
351 : , meMode( DefaultMode )
352 : , mdX( -1.0 )
353 : , mdY( -1.0 )
354 0 : , mpBitmap( 0 )
355 : {
356 0 : SetControlBackground();
357 0 : }
358 :
359 0 : ColorFieldControl::~ColorFieldControl()
360 : {
361 0 : disposeOnce();
362 0 : }
363 :
364 0 : void ColorFieldControl::dispose()
365 : {
366 0 : delete mpBitmap;
367 0 : mpBitmap = NULL;
368 0 : Control::dispose();
369 0 : }
370 :
371 0 : VCL_BUILDER_DECL_FACTORY(ColorFieldControl)
372 : {
373 0 : WinBits nBits = 0;
374 :
375 0 : OString sBorder = VclBuilder::extractCustomProperty(rMap);
376 0 : if (!sBorder.isEmpty())
377 0 : nBits |= WB_BORDER;
378 :
379 0 : rRet = VclPtr<ColorFieldControl>::Create(pParent, nBits);
380 0 : }
381 :
382 0 : Size ColorFieldControl::GetOptimalSize() const
383 : {
384 0 : return LogicToPixel(Size(158, 158), MAP_APPFONT);
385 : }
386 :
387 0 : void ColorFieldControl::UpdateBitmap()
388 : {
389 0 : const Size aSize(GetOutputSizePixel());
390 :
391 0 : if (mpBitmap && mpBitmap->GetSizePixel() != aSize)
392 0 : delete mpBitmap, mpBitmap = NULL;
393 :
394 0 : const sal_Int32 nWidth = aSize.Width();
395 0 : const sal_Int32 nHeight = aSize.Height();
396 :
397 0 : if (nWidth == 0 || nHeight == 0)
398 0 : return;
399 :
400 0 : if (!mpBitmap)
401 : {
402 0 : mpBitmap = new Bitmap( aSize, 24 );
403 :
404 0 : maRGB_Horiz.resize( nWidth );
405 0 : maGrad_Horiz.resize( nWidth );
406 0 : maPercent_Horiz.resize( nWidth );
407 :
408 0 : sal_uInt8* pRGB = maRGB_Horiz.data();
409 0 : sal_uInt16* pGrad = maGrad_Horiz.data();
410 0 : sal_uInt16* pPercent = maPercent_Horiz.data();
411 :
412 0 : for( sal_Int32 x = 0; x < nWidth; x++ )
413 : {
414 0 : *pRGB++ = static_cast<sal_uInt8>((x * 256) / nWidth);
415 0 : *pGrad++ = static_cast<sal_uInt16>((x * 359) / nWidth);
416 0 : *pPercent++ = static_cast<sal_uInt16>((x * 100) / nWidth);
417 : }
418 :
419 0 : maRGB_Vert.resize(nHeight);
420 0 : maPercent_Vert.resize(nHeight);
421 :
422 0 : pRGB = maRGB_Vert.data();
423 0 : pPercent = maPercent_Vert.data();
424 :
425 0 : sal_Int32 y = nHeight;
426 0 : while (y--)
427 : {
428 0 : *pRGB++ = static_cast<sal_uInt8>((y * 256) / nHeight);
429 0 : *pPercent++ = static_cast<sal_uInt16>((y * 100) / nHeight);
430 : }
431 : }
432 :
433 0 : sal_uInt8* pRGB_Horiz = maRGB_Horiz.data();
434 0 : sal_uInt16* pGrad_Horiz = maGrad_Horiz.data();
435 0 : sal_uInt16* pPercent_Horiz = maPercent_Horiz.data();
436 0 : sal_uInt8* pRGB_Vert = maRGB_Vert.data();
437 0 : sal_uInt16* pPercent_Vert = maPercent_Vert.data();
438 :
439 0 : BitmapWriteAccess* pWriteAccess = mpBitmap->AcquireWriteAccess();
440 0 : if (pWriteAccess)
441 : {
442 0 : BitmapColor aBitmapColor(maColor);
443 :
444 : sal_uInt16 nHue, nSat, nBri;
445 0 : maColor.RGBtoHSB(nHue, nSat, nBri);
446 :
447 : // this has been unlooped for performance reason, please do not merge back!
448 :
449 0 : sal_uInt16 y = nHeight,x;
450 :
451 0 : switch(meMode)
452 : {
453 : case HUE:
454 0 : while (y--)
455 : {
456 0 : nBri = pPercent_Vert[y];
457 0 : x = nWidth;
458 0 : while (x--)
459 : {
460 0 : nSat = pPercent_Horiz[x];
461 0 : pWriteAccess->SetPixel(y, x, BitmapColor(Color(Color::HSBtoRGB(nHue, nSat, nBri))));
462 : }
463 : }
464 0 : break;
465 : case SATURATION:
466 0 : while (y--)
467 : {
468 0 : nBri = pPercent_Vert[y];
469 0 : x = nWidth;
470 0 : while (x--)
471 : {
472 0 : nHue = pGrad_Horiz[x];
473 0 : pWriteAccess->SetPixel(y, x, BitmapColor(Color(Color::HSBtoRGB(nHue, nSat, nBri))));
474 : }
475 : }
476 0 : break;
477 : case BRIGHTNESS:
478 0 : while (y--)
479 : {
480 0 : nSat = pPercent_Vert[y];
481 0 : x = nWidth;
482 0 : while (x--)
483 : {
484 0 : nHue = pGrad_Horiz[x];
485 0 : pWriteAccess->SetPixel(y, x, BitmapColor(Color(Color::HSBtoRGB(nHue, nSat, nBri))));
486 : }
487 : }
488 0 : break;
489 : case RED:
490 0 : while (y--)
491 : {
492 0 : aBitmapColor.SetGreen(pRGB_Vert[y]);
493 0 : x = nWidth;
494 0 : while (x--)
495 : {
496 0 : aBitmapColor.SetBlue(pRGB_Horiz[x]);
497 0 : pWriteAccess->SetPixel(y, x, aBitmapColor);
498 : }
499 : }
500 0 : break;
501 : case GREEN:
502 0 : while (y--)
503 : {
504 0 : aBitmapColor.SetRed(pRGB_Vert[y]);
505 0 : x = nWidth;
506 0 : while (x--)
507 : {
508 0 : aBitmapColor.SetBlue(pRGB_Horiz[x]);
509 0 : pWriteAccess->SetPixel(y, x, aBitmapColor);
510 : }
511 : }
512 0 : break;
513 : case BLUE:
514 0 : while (y--)
515 : {
516 0 : aBitmapColor.SetGreen(pRGB_Vert[y]);
517 0 : x = nWidth;
518 0 : while (x--)
519 : {
520 0 : aBitmapColor.SetRed(pRGB_Horiz[x]);
521 0 : pWriteAccess->SetPixel(y, x, aBitmapColor);
522 : }
523 : }
524 0 : break;
525 : }
526 :
527 0 : Bitmap::ReleaseAccess(pWriteAccess);
528 : }
529 : }
530 :
531 0 : void ColorFieldControl::ShowPosition( const Point& rPos, bool bUpdate )
532 : {
533 0 : if (!mpBitmap)
534 : {
535 0 : UpdateBitmap();
536 0 : Invalidate();
537 : }
538 :
539 0 : if (!mpBitmap)
540 0 : return;
541 :
542 0 : const Size aSize(mpBitmap->GetSizePixel());
543 :
544 0 : long nX = rPos.X();
545 0 : long nY = rPos.Y();
546 0 : if (nX < 0L)
547 0 : nX = 0L;
548 0 : else if (nX >= aSize.Width())
549 0 : nX = aSize.Width() - 1L;
550 :
551 0 : if (nY < 0L)
552 0 : nY = 0L;
553 0 : else if (nY >= aSize.Height())
554 0 : nY = aSize.Height() - 1L;
555 :
556 0 : Point aPos = maPosition;
557 0 : maPosition.X() = nX - 5;
558 0 : maPosition.Y() = nY - 5;
559 0 : Invalidate(Rectangle(aPos, Size(11, 11)));
560 0 : Invalidate(Rectangle(maPosition, Size(11, 11)));
561 :
562 0 : if (bUpdate)
563 : {
564 0 : mdX = double(nX) / double(aSize.Width() - 1.0);
565 0 : mdY = double(aSize.Height() - 1.0 - nY) / double(aSize.Height() - 1.0);
566 :
567 0 : BitmapReadAccess* pReadAccess = mpBitmap->AcquireReadAccess();
568 0 : if (pReadAccess != NULL)
569 : {
570 : // mpBitmap always has a bit count of 24 => use of GetPixel(...) is safe
571 0 : maColor = pReadAccess->GetPixel(nY, nX);
572 0 : Bitmap::ReleaseAccess(pReadAccess);
573 0 : pReadAccess = NULL;
574 : }
575 : }
576 : }
577 :
578 0 : void ColorFieldControl::MouseMove( const MouseEvent& rMEvt )
579 : {
580 0 : if( rMEvt.IsLeft() )
581 : {
582 0 : ShowPosition( rMEvt.GetPosPixel(), true );
583 0 : Modify();
584 : }
585 0 : }
586 :
587 0 : void ColorFieldControl::MouseButtonDown( const MouseEvent& rMEvt )
588 : {
589 0 : if( rMEvt.IsLeft() && !rMEvt.IsShift() )
590 : {
591 0 : CaptureMouse();
592 0 : ShowPosition( rMEvt.GetPosPixel(), true );
593 0 : Modify();
594 : }
595 0 : }
596 :
597 0 : void ColorFieldControl::MouseButtonUp( const MouseEvent& )
598 : {
599 0 : if( IsMouseCaptured() )
600 0 : ReleaseMouse();
601 0 : }
602 :
603 0 : void ColorFieldControl::KeyMove( int dx, int dy )
604 : {
605 0 : Size aSize(GetOutputSizePixel());
606 0 : Point aPos(static_cast<long>(mdX * aSize.Width()), static_cast<long>((1.0 - mdY) * aSize.Height()));
607 0 : aPos.X() += dx;
608 0 : aPos.Y() += dy;
609 0 : if( aPos.X() < 0 )
610 0 : aPos.X() += aSize.Width();
611 0 : else if( aPos.X() >= aSize.Width() )
612 0 : aPos.X() -= aSize.Width();
613 :
614 0 : if( aPos.Y() < 0 )
615 0 : aPos.Y() += aSize.Height();
616 0 : else if( aPos.Y() >= aSize.Height() )
617 0 : aPos.Y() -= aSize.Height();
618 :
619 0 : ShowPosition( aPos, true );
620 0 : Modify();
621 0 : }
622 :
623 0 : void ColorFieldControl::KeyInput( const KeyEvent& rKEvt )
624 : {
625 0 : bool bShift = rKEvt.GetKeyCode().IsShift();
626 0 : bool bCtrl = rKEvt.GetKeyCode().IsMod1();
627 0 : bool bAlt = rKEvt.GetKeyCode().IsMod2();
628 :
629 0 : if (!bAlt && !bShift)
630 : {
631 0 : switch( rKEvt.GetKeyCode().GetCode() )
632 : {
633 : case KEY_DOWN:
634 0 : KeyMove(0, bCtrl ? 5 : 1);
635 0 : return;
636 : case KEY_UP:
637 0 : KeyMove(0, bCtrl ? -5 : -1);
638 0 : return;
639 : case KEY_LEFT:
640 0 : KeyMove(bCtrl ? -5 : -1, 0);
641 0 : return;
642 : case KEY_RIGHT:
643 0 : KeyMove(bCtrl ? 5 : 1, 0);
644 0 : return;
645 : }
646 : }
647 0 : Control::KeyInput(rKEvt);
648 : }
649 :
650 0 : void ColorFieldControl::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect)
651 : {
652 0 : if (!mpBitmap)
653 0 : UpdateBitmap();
654 :
655 0 : if (mpBitmap)
656 : {
657 0 : Bitmap aOutputBitmap(*mpBitmap);
658 :
659 0 : if (GetBitCount() <= 8)
660 0 : aOutputBitmap.Dither();
661 :
662 0 : rRenderContext.DrawBitmap(rRect.TopLeft(), rRect.GetSize(), rRect.TopLeft(), rRect.GetSize(), aOutputBitmap);
663 : }
664 :
665 : // draw circle around current color
666 0 : if (maColor.IsDark())
667 0 : rRenderContext.SetLineColor( COL_WHITE );
668 : else
669 0 : rRenderContext.SetLineColor( COL_BLACK );
670 :
671 0 : rRenderContext.SetFillColor();
672 :
673 0 : rRenderContext.DrawEllipse(Rectangle(maPosition, Size(11, 11)));
674 0 : }
675 :
676 0 : void ColorFieldControl::Resize()
677 : {
678 0 : UpdateBitmap();
679 0 : UpdatePosition();
680 0 : Control::Resize();
681 0 : }
682 :
683 0 : void ColorFieldControl::Modify()
684 : {
685 0 : maModifyHdl.Call( this );
686 0 : }
687 :
688 0 : void ColorFieldControl::SetValues( Color aColor, ColorMode eMode, double x, double y )
689 : {
690 0 : bool bUpdateBitmap = (maColor!= aColor) || (meMode != eMode);
691 0 : if( bUpdateBitmap || (mdX != x) || (mdY != y) )
692 : {
693 0 : maColor = aColor;
694 0 : meMode = eMode;
695 0 : mdX = x;
696 0 : mdY = y;
697 :
698 0 : if (bUpdateBitmap)
699 0 : UpdateBitmap();
700 0 : UpdatePosition();
701 0 : if (bUpdateBitmap)
702 0 : Invalidate();
703 : }
704 0 : }
705 :
706 0 : void ColorFieldControl::UpdatePosition()
707 : {
708 0 : Size aSize(GetOutputSizePixel());
709 0 : ShowPosition(Point(static_cast<long>(mdX * aSize.Width()), static_cast<long>((1.0 - mdY) * aSize.Height())), false);
710 0 : }
711 :
712 : class ColorSliderControl : public Control
713 : {
714 : public:
715 : ColorSliderControl( vcl::Window* pParent, const WinBits& nStyle );
716 : virtual ~ColorSliderControl();
717 : virtual void dispose() SAL_OVERRIDE;
718 :
719 : virtual void MouseMove( const MouseEvent& rMEvt ) SAL_OVERRIDE;
720 : virtual void MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
721 : virtual void MouseButtonUp( const MouseEvent& rMEvt ) SAL_OVERRIDE;
722 : virtual void KeyInput( const KeyEvent& rKEvt ) SAL_OVERRIDE;
723 : virtual void Paint( vcl::RenderContext& rRenderContext, const Rectangle& rRect ) SAL_OVERRIDE;
724 : virtual void Resize() SAL_OVERRIDE;
725 :
726 : void UpdateBitmap();
727 : void ChangePosition( long nY );
728 : void Modify();
729 :
730 : void SetValue( const Color& rColor, ColorMode eMode, double dValue );
731 0 : double GetValue() const { return mdValue; }
732 :
733 : void KeyMove( int dy );
734 :
735 0 : void SetModifyHdl( Link<>& rLink ) { maModifyHdl = rLink; }
736 :
737 0 : sal_Int16 GetLevel() const { return mnLevel; }
738 :
739 : private:
740 : Link<> maModifyHdl;
741 : Color maColor;
742 : ColorMode meMode;
743 : Bitmap* mpBitmap;
744 : sal_Int16 mnLevel;
745 : double mdValue;
746 : };
747 :
748 0 : ColorSliderControl::ColorSliderControl( vcl::Window* pParent, const WinBits& nStyle )
749 : : Control( pParent, nStyle )
750 : , meMode( DefaultMode )
751 : , mpBitmap( 0 )
752 : , mnLevel( 0 )
753 0 : , mdValue( -1.0 )
754 : {
755 0 : SetControlBackground();
756 0 : }
757 :
758 0 : ColorSliderControl::~ColorSliderControl()
759 : {
760 0 : disposeOnce();
761 0 : }
762 :
763 0 : void ColorSliderControl::dispose()
764 : {
765 0 : delete mpBitmap;
766 0 : mpBitmap = NULL;
767 0 : Control::dispose();
768 0 : }
769 :
770 0 : VCL_BUILDER_DECL_FACTORY(ColorSliderControl)
771 : {
772 0 : WinBits nBits = 0;
773 :
774 0 : OString sBorder = VclBuilder::extractCustomProperty(rMap);
775 0 : if (!sBorder.isEmpty())
776 0 : nBits |= WB_BORDER;
777 :
778 0 : rRet = VclPtr<ColorSliderControl>::Create(pParent, nBits);
779 0 : }
780 :
781 0 : void ColorSliderControl::UpdateBitmap()
782 : {
783 0 : Size aSize(1, GetOutputSizePixel().Height());
784 :
785 0 : if (mpBitmap && mpBitmap->GetSizePixel() != aSize)
786 0 : delete mpBitmap, mpBitmap = NULL;
787 :
788 0 : if (!mpBitmap)
789 0 : mpBitmap = new Bitmap(aSize, 24);
790 :
791 0 : BitmapWriteAccess* pWriteAccess = mpBitmap->AcquireWriteAccess();
792 :
793 0 : if (pWriteAccess)
794 : {
795 0 : const long nY = aSize.Height() - 1;
796 :
797 0 : BitmapColor aBitmapColor(maColor);
798 :
799 : sal_uInt16 nHue, nSat, nBri;
800 0 : maColor.RGBtoHSB(nHue, nSat, nBri);
801 :
802 : // this has been unlooped for performance reason, please do not merge back!
803 :
804 0 : switch (meMode)
805 : {
806 : case HUE:
807 0 : nSat = 100;
808 0 : nBri = 100;
809 0 : for (long y = 0; y <= nY; y++)
810 : {
811 0 : nHue = static_cast<sal_uInt16>((359 * y) / nY);
812 0 : aBitmapColor = BitmapColor(Color(Color::HSBtoRGB(nHue, nSat, nBri)));
813 0 : pWriteAccess->SetPixel(nY - y, 0, aBitmapColor);
814 : }
815 0 : break;
816 :
817 : case SATURATION:
818 0 : nBri = std::max(sal_uInt16(32), nBri);
819 0 : for (long y = 0; y <= nY; y++)
820 : {
821 0 : nSat = static_cast<sal_uInt16>((100 * y) / nY);
822 0 : pWriteAccess->SetPixel(nY - y, 0, BitmapColor(Color(Color::HSBtoRGB(nHue, nSat, nBri))));
823 : }
824 0 : break;
825 :
826 : case BRIGHTNESS:
827 0 : for (long y = 0; y <= nY; y++)
828 : {
829 0 : nBri = static_cast<sal_uInt16>((100 * y) / nY);
830 0 : pWriteAccess->SetPixel(nY - y, 0, BitmapColor(Color(Color::HSBtoRGB(nHue, nSat, nBri))));
831 : }
832 0 : break;
833 :
834 : case RED:
835 0 : for (long y = 0; y <= nY; y++)
836 : {
837 0 : aBitmapColor.SetRed(sal_uInt8(((long)255 * y) / nY));
838 0 : pWriteAccess->SetPixel(nY - y, 0, aBitmapColor);
839 : }
840 0 : break;
841 :
842 : case GREEN:
843 0 : for (long y = 0; y <= nY; y++)
844 : {
845 0 : aBitmapColor.SetGreen(sal_uInt8(((long)255 * y) / nY));
846 0 : pWriteAccess->SetPixel(nY - y, 0, aBitmapColor);
847 : }
848 0 : break;
849 :
850 : case BLUE:
851 0 : for (long y = 0; y <= nY; y++)
852 : {
853 0 : aBitmapColor.SetBlue(sal_uInt8(((long)255 * y) / nY));
854 0 : pWriteAccess->SetPixel(nY - y, 0, aBitmapColor);
855 : }
856 0 : break;
857 : }
858 :
859 0 : Bitmap::ReleaseAccess(pWriteAccess);
860 : }
861 0 : }
862 :
863 0 : void ColorSliderControl::ChangePosition(long nY)
864 : {
865 0 : const long nHeight = GetOutputSizePixel().Height() - 1;
866 :
867 0 : if (nY < 0L)
868 0 : nY = 0;
869 0 : else if (nY > nHeight)
870 0 : nY = nHeight;
871 :
872 0 : mnLevel = nY;
873 0 : mdValue = double(nHeight - nY) / double(nHeight);
874 0 : }
875 :
876 0 : void ColorSliderControl::MouseMove( const MouseEvent& rMEvt )
877 : {
878 0 : if (rMEvt.IsLeft())
879 : {
880 0 : ChangePosition(rMEvt.GetPosPixel().Y());
881 0 : Modify();
882 : }
883 0 : }
884 :
885 0 : void ColorSliderControl::MouseButtonDown(const MouseEvent& rMEvt)
886 : {
887 0 : if (rMEvt.IsLeft() && !rMEvt.IsShift())
888 : {
889 0 : CaptureMouse();
890 0 : ChangePosition( rMEvt.GetPosPixel().Y() );
891 0 : Modify();
892 : }
893 0 : }
894 :
895 0 : void ColorSliderControl::MouseButtonUp(const MouseEvent&)
896 : {
897 0 : if (IsMouseCaptured())
898 0 : ReleaseMouse();
899 0 : }
900 :
901 0 : void ColorSliderControl::KeyMove(int dy)
902 : {
903 0 : ChangePosition( mnLevel + dy );
904 0 : Modify();
905 0 : }
906 :
907 0 : void ColorSliderControl::KeyInput(const KeyEvent& rKEvt)
908 : {
909 0 : if (!rKEvt.GetKeyCode().IsMod2() && !rKEvt.GetKeyCode().IsShift())
910 : {
911 0 : switch (rKEvt.GetKeyCode().GetCode())
912 : {
913 : case KEY_DOWN:
914 0 : KeyMove(rKEvt.GetKeyCode().IsMod1() ? 5 : 1);
915 0 : return;
916 : case KEY_UP:
917 0 : KeyMove(rKEvt.GetKeyCode().IsMod1() ? -5 : -1);
918 0 : return;
919 : }
920 : }
921 :
922 0 : Control::KeyInput( rKEvt );
923 : }
924 :
925 0 : void ColorSliderControl::Paint(vcl::RenderContext& rRenderContext, const Rectangle& /*rRect*/)
926 : {
927 0 : if (!mpBitmap)
928 0 : UpdateBitmap();
929 :
930 0 : const Size aSize(rRenderContext.GetOutputSizePixel());
931 :
932 0 : Bitmap aOutputBitmap(*mpBitmap);
933 :
934 0 : if (GetBitCount() <= 8)
935 0 : aOutputBitmap.Dither();
936 :
937 0 : Point aPos;
938 0 : int x = aSize.Width();
939 0 : while (x--)
940 : {
941 0 : rRenderContext.DrawBitmap(aPos, aOutputBitmap);
942 0 : aPos.X() += 1;
943 0 : }
944 0 : }
945 :
946 0 : void ColorSliderControl::Resize()
947 : {
948 0 : UpdateBitmap();
949 0 : Control::Resize();
950 0 : }
951 :
952 0 : void ColorSliderControl::Modify()
953 : {
954 0 : maModifyHdl.Call(this);
955 0 : }
956 :
957 0 : void ColorSliderControl::SetValue(const Color& rColor, ColorMode eMode, double dValue)
958 : {
959 0 : bool bUpdateBitmap = (rColor != maColor) || (eMode != meMode);
960 0 : if( bUpdateBitmap || (mdValue != dValue))
961 : {
962 0 : maColor = rColor;
963 0 : mdValue = dValue;
964 0 : mnLevel = static_cast<sal_Int16>((1.0-dValue) * GetOutputSizePixel().Height());
965 0 : meMode = eMode;
966 0 : if (bUpdateBitmap)
967 0 : UpdateBitmap();
968 0 : Invalidate();
969 : }
970 0 : }
971 :
972 : const sal_uInt16 UPDATE_RGB = 0x01;
973 : const sal_uInt16 UPDATE_CMYK = 0x02;
974 : const sal_uInt16 UPDATE_HSB = 0x04;
975 : const sal_uInt16 UPDATE_COLORCHOOSER = 0x08;
976 : const sal_uInt16 UPDATE_COLORSLIDER = 0x10;
977 : const sal_uInt16 UPDATE_HEX = 0x20;
978 : const sal_uInt16 UPDATE_ALL = 0xff;
979 :
980 : class ColorPickerDialog : public ModalDialog
981 : {
982 : public:
983 : ColorPickerDialog(vcl::Window* pParent, sal_Int32 nColor, sal_Int16 nMode);
984 0 : virtual ~ColorPickerDialog()
985 0 : {
986 0 : disposeOnce();
987 0 : }
988 : virtual void dispose() SAL_OVERRIDE;
989 :
990 : void update_color(sal_uInt16 n = UPDATE_ALL);
991 :
992 : DECL_LINK(ColorModifyHdl, void*);
993 : DECL_LINK(ModeModifyHdl, void*);
994 :
995 : sal_Int32 GetColor() const;
996 :
997 : void setColorComponent(sal_uInt16 nComp, double dValue);
998 :
999 : private:
1000 : sal_Int16 mnDialogMode;
1001 : ColorMode meMode;
1002 :
1003 : double mdRed, mdGreen, mdBlue;
1004 : double mdHue, mdSat, mdBri;
1005 : double mdCyan, mdMagenta, mdYellow, mdKey;
1006 :
1007 : private:
1008 : VclPtr<ColorFieldControl> mpColorField;
1009 : VclPtr<ColorSliderControl> mpColorSlider;
1010 : VclPtr<ColorPreviewControl> mpColorPreview;
1011 : VclPtr<ColorPreviewControl> mpColorPrevious;
1012 :
1013 : VclPtr<FixedImage> mpFISliderLeft;
1014 : VclPtr<FixedImage> mpFISliderRight;
1015 : Image maSliderImage;
1016 :
1017 : VclPtr<RadioButton> mpRBRed;
1018 : VclPtr<RadioButton> mpRBGreen;
1019 : VclPtr<RadioButton> mpRBBlue;
1020 : VclPtr<RadioButton> mpRBHue;
1021 : VclPtr<RadioButton> mpRBSaturation;
1022 : VclPtr<RadioButton> mpRBBrightness;
1023 :
1024 : VclPtr<MetricField> mpMFRed;
1025 : VclPtr<MetricField> mpMFGreen;
1026 : VclPtr<MetricField> mpMFBlue;
1027 : VclPtr<HexColorControl> mpEDHex;
1028 :
1029 : VclPtr<MetricField> mpMFHue;
1030 : VclPtr<MetricField> mpMFSaturation;
1031 : VclPtr<MetricField> mpMFBrightness;
1032 :
1033 : VclPtr<MetricField> mpMFCyan;
1034 : VclPtr<MetricField> mpMFMagenta;
1035 : VclPtr<MetricField> mpMFYellow;
1036 : VclPtr<MetricField> mpMFKey;
1037 : };
1038 :
1039 0 : ColorPickerDialog::ColorPickerDialog( vcl::Window* pParent, sal_Int32 nColor, sal_Int16 nMode )
1040 : : ModalDialog( pParent, "ColorPicker", "cui/ui/colorpickerdialog.ui" )
1041 : , mnDialogMode( nMode )
1042 : , meMode( DefaultMode )
1043 0 : , maSliderImage( FixedImage::loadThemeImage("res/colorslider.png") )
1044 : {
1045 0 : get(mpColorField, "colorField");
1046 0 : get(mpColorSlider, "colorSlider");
1047 0 : get(mpColorPreview, "preview");
1048 0 : get(mpColorPrevious, "previous");
1049 0 : get(mpRBRed, "redRadiobutton");
1050 0 : get(mpRBGreen, "greenRadiobutton");
1051 0 : get(mpRBBlue, "blueRadiobutton");
1052 0 : get(mpRBHue, "hueRadiobutton");
1053 0 : get(mpRBSaturation, "satRadiobutton");
1054 0 : get(mpRBBrightness, "brightRadiobutton");
1055 0 : get(mpMFRed, "redSpinbutton");
1056 0 : get(mpMFGreen, "greenSpinbutton");
1057 0 : get(mpMFBlue, "blueSpinbutton");
1058 0 : get(mpEDHex, "hexEntry");
1059 0 : get(mpMFHue, "hueSpinbutton");
1060 0 : get(mpMFSaturation, "satSpinbutton");
1061 0 : get(mpMFBrightness, "brightSpinbutton");
1062 0 : get(mpMFCyan, "cyanSpinbutton");
1063 0 : get(mpMFMagenta, "magSpinbutton");
1064 0 : get(mpMFYellow, "yellowSpinbutton");
1065 0 : get(mpMFKey, "keySpinbutton");
1066 0 : get(mpFISliderLeft, "leftImage");
1067 0 : get(mpFISliderRight, "rightImage");
1068 :
1069 0 : Size aDialogSize = get_preferred_size();
1070 0 : set_width_request(aDialogSize.Width() + 50);
1071 0 : set_height_request(aDialogSize.Height() + 30);
1072 :
1073 0 : Link<> aLink( LINK( this, ColorPickerDialog, ColorModifyHdl ) );
1074 0 : mpColorField->SetModifyHdl( aLink );
1075 0 : mpColorSlider->SetModifyHdl( aLink );
1076 :
1077 0 : mpMFRed->SetModifyHdl( aLink );
1078 0 : mpMFGreen->SetModifyHdl( aLink );
1079 0 : mpMFBlue->SetModifyHdl( aLink );
1080 :
1081 0 : mpMFCyan->SetModifyHdl( aLink );
1082 0 : mpMFMagenta->SetModifyHdl( aLink );
1083 0 : mpMFYellow->SetModifyHdl( aLink );
1084 0 : mpMFKey->SetModifyHdl( aLink );
1085 :
1086 0 : mpMFHue->SetModifyHdl( aLink );
1087 0 : mpMFSaturation->SetModifyHdl( aLink );
1088 0 : mpMFBrightness->SetModifyHdl( aLink );
1089 :
1090 0 : mpEDHex->SetModifyHdl( aLink );
1091 :
1092 0 : aLink = LINK( this, ColorPickerDialog, ModeModifyHdl );
1093 0 : mpRBRed->SetToggleHdl( aLink );
1094 0 : mpRBGreen->SetToggleHdl( aLink );
1095 0 : mpRBBlue->SetToggleHdl( aLink );
1096 0 : mpRBHue->SetToggleHdl( aLink );
1097 0 : mpRBSaturation->SetToggleHdl( aLink );
1098 0 : mpRBBrightness->SetToggleHdl( aLink );
1099 :
1100 0 : Image aSliderImage( maSliderImage );
1101 :
1102 0 : mpFISliderLeft->SetImage( aSliderImage );
1103 0 : mpFISliderLeft->Show(true);
1104 :
1105 0 : BitmapEx aTmpBmp( maSliderImage.GetBitmapEx() );
1106 0 : aTmpBmp.Mirror( BmpMirrorFlags::Horizontal );
1107 0 : mpFISliderRight->SetImage( Image( aTmpBmp ) );
1108 :
1109 0 : Size aSize( maSliderImage.GetSizePixel() );
1110 0 : mpFISliderLeft->SetSizePixel( aSize );
1111 0 : mpFISliderRight->SetSizePixel( aSize );
1112 :
1113 0 : Point aPos( mpColorSlider->GetPosPixel() );
1114 :
1115 0 : aPos.X() -= aSize.Width();
1116 0 : aPos.Y() -= aSize.Height() / 2;
1117 0 : mpFISliderLeft->SetPosPixel( aPos );
1118 :
1119 0 : aPos.X() += aSize.Width() + mpColorSlider->GetSizePixel().Width();
1120 0 : mpFISliderRight->SetPosPixel( aPos );
1121 :
1122 0 : Color aColor( nColor );
1123 :
1124 : // modify
1125 0 : if( mnDialogMode == 2 )
1126 : {
1127 0 : mpColorPreview->SetSizePixel( mpColorPrevious->GetSizePixel() );
1128 0 : mpColorPrevious->SetColor( aColor );
1129 0 : mpColorPrevious->Show( true );
1130 : }
1131 :
1132 0 : mdRed = ((double)aColor.GetRed()) / 255.0;
1133 0 : mdGreen = ((double)aColor.GetGreen()) / 255.0;
1134 0 : mdBlue = ((double)aColor.GetBlue()) / 255.0;
1135 :
1136 0 : RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
1137 0 : RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
1138 :
1139 0 : update_color();
1140 0 : }
1141 :
1142 0 : void ColorPickerDialog::dispose()
1143 : {
1144 0 : mpColorField.clear();
1145 0 : mpColorSlider.clear();
1146 0 : mpColorPreview.clear();
1147 0 : mpColorPrevious.clear();
1148 0 : mpFISliderLeft.clear();
1149 0 : mpFISliderRight.clear();
1150 0 : mpRBRed.clear();
1151 0 : mpRBGreen.clear();
1152 0 : mpRBBlue.clear();
1153 0 : mpRBHue.clear();
1154 0 : mpRBSaturation.clear();
1155 0 : mpRBBrightness.clear();
1156 0 : mpMFRed.clear();
1157 0 : mpMFGreen.clear();
1158 0 : mpMFBlue.clear();
1159 0 : mpEDHex.clear();
1160 0 : mpMFHue.clear();
1161 0 : mpMFSaturation.clear();
1162 0 : mpMFBrightness.clear();
1163 0 : mpMFCyan.clear();
1164 0 : mpMFMagenta.clear();
1165 0 : mpMFYellow.clear();
1166 0 : mpMFKey.clear();
1167 0 : ModalDialog::dispose();
1168 0 : }
1169 :
1170 0 : static int toInt( double dValue, double dRange )
1171 : {
1172 0 : return static_cast< int >( std::floor((dValue * dRange) + 0.5 ) );
1173 : }
1174 :
1175 0 : sal_Int32 ColorPickerDialog::GetColor() const
1176 : {
1177 0 : return Color( toInt(mdRed,255.0), toInt(mdGreen,255.0), toInt(mdBlue,255.0) ).GetColor();
1178 : }
1179 :
1180 0 : void ColorPickerDialog::update_color( sal_uInt16 n )
1181 : {
1182 0 : sal_uInt8 nRed = toInt(mdRed,255.0);
1183 0 : sal_uInt8 nGreen = toInt(mdGreen,255.0);
1184 0 : sal_uInt8 nBlue = toInt(mdBlue,255.0);
1185 :
1186 0 : Color aColor(nRed, nGreen, nBlue);
1187 :
1188 0 : if (n & UPDATE_RGB) // update RGB
1189 : {
1190 0 : mpMFRed->SetValue(nRed);
1191 0 : mpMFGreen->SetValue(nGreen);
1192 0 : mpMFBlue->SetValue(nBlue);
1193 : }
1194 :
1195 0 : if (n & UPDATE_CMYK) // update CMYK
1196 : {
1197 0 : mpMFCyan->SetValue(toInt(mdCyan, 100.0));
1198 0 : mpMFMagenta->SetValue(toInt(mdMagenta, 100.0));
1199 0 : mpMFYellow->SetValue(toInt(mdYellow, 100.0));
1200 0 : mpMFKey->SetValue(toInt(mdKey, 100.0));
1201 : }
1202 :
1203 0 : if (n & UPDATE_HSB ) // update HSB
1204 : {
1205 0 : mpMFHue->SetValue(toInt(mdHue, 1.0));
1206 0 : mpMFSaturation->SetValue(toInt( mdSat, 100.0));
1207 0 : mpMFBrightness->SetValue(toInt( mdBri, 100.0));
1208 : }
1209 :
1210 0 : if (n & UPDATE_COLORCHOOSER ) // update Color Chooser 1
1211 : {
1212 0 : switch( meMode )
1213 : {
1214 : case HUE:
1215 0 : mpColorField->SetValues(aColor, meMode, mdSat, mdBri);
1216 0 : break;
1217 : case SATURATION:
1218 0 : mpColorField->SetValues(aColor, meMode, mdHue / 360.0, mdBri);
1219 0 : break;
1220 : case BRIGHTNESS:
1221 0 : mpColorField->SetValues(aColor, meMode, mdHue / 360.0, mdSat);
1222 0 : break;
1223 : case RED:
1224 0 : mpColorField->SetValues(aColor, meMode, mdBlue, mdGreen);
1225 0 : break;
1226 : case GREEN:
1227 0 : mpColorField->SetValues(aColor, meMode, mdBlue, mdRed);
1228 0 : break;
1229 : case BLUE:
1230 0 : mpColorField->SetValues(aColor, meMode, mdRed, mdGreen);
1231 0 : break;
1232 : }
1233 : }
1234 :
1235 0 : if (n & UPDATE_COLORSLIDER) // update Color Chooser 2
1236 : {
1237 0 : switch (meMode)
1238 : {
1239 : case HUE:
1240 0 : mpColorSlider->SetValue(aColor, meMode, mdHue / 360.0);
1241 0 : break;
1242 : case SATURATION:
1243 0 : mpColorSlider->SetValue(aColor, meMode, mdSat);
1244 0 : break;
1245 : case BRIGHTNESS:
1246 0 : mpColorSlider->SetValue(aColor, meMode, mdBri);
1247 0 : break;
1248 : case RED:
1249 0 : mpColorSlider->SetValue(aColor, meMode, mdRed);
1250 0 : break;
1251 : case GREEN:
1252 0 : mpColorSlider->SetValue(aColor, meMode, mdGreen);
1253 0 : break;
1254 : case BLUE:
1255 0 : mpColorSlider->SetValue(aColor, meMode, mdBlue);
1256 0 : break;
1257 : }
1258 : }
1259 :
1260 0 : if (n & UPDATE_HEX) // update hex
1261 : {
1262 0 : mpEDHex->SetColor(aColor.GetColor());
1263 : }
1264 :
1265 : {
1266 0 : Point aPos(0, mpColorSlider->GetLevel() + mpColorSlider->GetPosPixel().Y() - 1);
1267 :
1268 0 : aPos.X() = mpFISliderLeft->GetPosPixel().X();
1269 0 : if (aPos != mpFISliderLeft->GetPosPixel())
1270 : {
1271 0 : mpFISliderLeft->SetPosPixel(aPos);
1272 :
1273 0 : aPos.X() = mpFISliderRight->GetPosPixel().X();
1274 0 : mpFISliderRight->SetPosPixel(aPos);
1275 : }
1276 : }
1277 :
1278 0 : mpColorPreview->SetColor(aColor);
1279 0 : }
1280 :
1281 0 : IMPL_LINK(ColorPickerDialog, ColorModifyHdl, void *, p)
1282 : {
1283 0 : sal_uInt16 n = 0;
1284 :
1285 0 : if (p == mpColorField)
1286 : {
1287 0 : double x = mpColorField->GetX();
1288 0 : double y = mpColorField->GetY();
1289 :
1290 0 : switch( meMode )
1291 : {
1292 : case HUE:
1293 0 : mdSat = x;
1294 0 : setColorComponent( COLORCOMP_BRI, y );
1295 0 : break;
1296 : case SATURATION:
1297 0 : mdHue = x * 360.0;
1298 0 : setColorComponent( COLORCOMP_BRI, y );
1299 0 : break;
1300 : case BRIGHTNESS:
1301 0 : mdHue = x * 360.0;
1302 0 : setColorComponent( COLORCOMP_SAT, y );
1303 0 : break;
1304 : case RED:
1305 0 : mdBlue = x;
1306 0 : setColorComponent( COLORCOMP_GREEN, y );
1307 0 : break;
1308 : case GREEN:
1309 0 : mdBlue = x;
1310 0 : setColorComponent( COLORCOMP_RED, y );
1311 0 : break;
1312 : case BLUE:
1313 0 : mdRed = x;
1314 0 : setColorComponent( COLORCOMP_GREEN, y );
1315 0 : break;
1316 : }
1317 :
1318 0 : n = UPDATE_ALL &~ (UPDATE_COLORCHOOSER);
1319 : }
1320 0 : else if (p == mpColorSlider)
1321 : {
1322 0 : double dValue = mpColorSlider->GetValue();
1323 0 : switch (meMode)
1324 : {
1325 : case HUE:
1326 0 : setColorComponent( COLORCOMP_HUE, dValue * 360.0 );
1327 0 : break;
1328 : case SATURATION:
1329 0 : setColorComponent( COLORCOMP_SAT, dValue );
1330 0 : break;
1331 : case BRIGHTNESS:
1332 0 : setColorComponent( COLORCOMP_BRI, dValue );
1333 0 : break;
1334 : case RED:
1335 0 : setColorComponent( COLORCOMP_RED, dValue );
1336 0 : break;
1337 : case GREEN:
1338 0 : setColorComponent( COLORCOMP_GREEN, dValue );
1339 0 : break;
1340 : case BLUE:
1341 0 : setColorComponent( COLORCOMP_BLUE, dValue );
1342 0 : break;
1343 : }
1344 :
1345 0 : n = UPDATE_ALL&~(UPDATE_COLORSLIDER);
1346 : }
1347 0 : else if (p == mpMFRed)
1348 : {
1349 0 : setColorComponent( COLORCOMP_RED, ((double)mpMFRed->GetValue()) / 255.0 );
1350 0 : n = UPDATE_ALL &~ (UPDATE_RGB);
1351 : }
1352 0 : else if (p == mpMFGreen)
1353 : {
1354 0 : setColorComponent( COLORCOMP_GREEN, ((double)mpMFGreen->GetValue()) / 255.0 );
1355 0 : n = UPDATE_ALL &~ (UPDATE_RGB);
1356 : }
1357 0 : else if (p == mpMFBlue)
1358 : {
1359 0 : setColorComponent( COLORCOMP_BLUE, ((double)mpMFBlue->GetValue()) / 255.0 );
1360 0 : n = UPDATE_ALL &~ (UPDATE_RGB);
1361 : }
1362 0 : else if (p == mpMFHue)
1363 : {
1364 0 : setColorComponent( COLORCOMP_HUE, (double)mpMFHue->GetValue() );
1365 0 : n = UPDATE_ALL &~ (UPDATE_HSB);
1366 : }
1367 0 : else if (p == mpMFSaturation)
1368 : {
1369 0 : setColorComponent( COLORCOMP_SAT, ((double)mpMFSaturation->GetValue()) / 100.0 );
1370 0 : n = UPDATE_ALL &~ (UPDATE_HSB);
1371 : }
1372 0 : else if (p == mpMFBrightness)
1373 : {
1374 0 : setColorComponent( COLORCOMP_BRI, ((double)mpMFBrightness->GetValue()) / 100.0 );
1375 0 : n = UPDATE_ALL &~ (UPDATE_HSB);
1376 : }
1377 0 : else if (p == mpMFCyan)
1378 : {
1379 0 : setColorComponent( COLORCOMP_CYAN, ((double)mpMFCyan->GetValue()) / 100.0 );
1380 0 : n = UPDATE_ALL &~ (UPDATE_CMYK);
1381 : }
1382 0 : else if (p == mpMFMagenta)
1383 : {
1384 0 : setColorComponent( COLORCOMP_MAGENTA, ((double)mpMFMagenta->GetValue()) / 100.0 );
1385 0 : n = UPDATE_ALL &~ (UPDATE_CMYK);
1386 : }
1387 0 : else if (p == mpMFYellow)
1388 : {
1389 0 : setColorComponent( COLORCOMP_YELLOW, ((double)mpMFYellow->GetValue()) / 100.0 );
1390 0 : n = UPDATE_ALL &~ (UPDATE_CMYK);
1391 : }
1392 0 : else if (p == mpMFKey)
1393 : {
1394 0 : setColorComponent( COLORCOMP_KEY, ((double)mpMFKey->GetValue()) / 100.0 );
1395 0 : n = UPDATE_ALL&~(UPDATE_CMYK);
1396 : }
1397 0 : else if (p == mpEDHex)
1398 : {
1399 0 : sal_Int32 nColor = mpEDHex->GetColor();
1400 :
1401 0 : if (nColor != -1)
1402 : {
1403 0 : Color aColor(nColor);
1404 :
1405 0 : if (aColor != GetColor())
1406 : {
1407 0 : mdRed = ((double)aColor.GetRed()) / 255.0;
1408 0 : mdGreen = ((double)aColor.GetGreen()) / 255.0;
1409 0 : mdBlue = ((double)aColor.GetBlue()) / 255.0;
1410 :
1411 0 : RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
1412 0 : RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
1413 0 : n = UPDATE_ALL &~ (UPDATE_HEX);
1414 : }
1415 : }
1416 : }
1417 :
1418 0 : if (n)
1419 0 : update_color(n);
1420 :
1421 0 : return 0;
1422 : }
1423 :
1424 0 : IMPL_LINK_NOARG(ColorPickerDialog, ModeModifyHdl)
1425 : {
1426 0 : ColorMode eMode = HUE;
1427 :
1428 0 : if (mpRBRed->IsChecked())
1429 : {
1430 0 : eMode = RED;
1431 : }
1432 0 : else if (mpRBGreen->IsChecked())
1433 : {
1434 0 : eMode = GREEN;
1435 : }
1436 0 : else if (mpRBBlue->IsChecked())
1437 : {
1438 0 : eMode = BLUE;
1439 : }
1440 0 : else if (mpRBSaturation->IsChecked())
1441 : {
1442 0 : eMode = SATURATION;
1443 : }
1444 0 : else if (mpRBBrightness->IsChecked())
1445 : {
1446 0 : eMode = BRIGHTNESS;
1447 : }
1448 :
1449 0 : if (meMode != eMode)
1450 : {
1451 0 : meMode = eMode;
1452 0 : update_color(UPDATE_COLORCHOOSER | UPDATE_COLORSLIDER);
1453 : }
1454 :
1455 0 : return 0;
1456 : }
1457 :
1458 0 : void ColorPickerDialog::setColorComponent( sal_uInt16 nComp, double dValue )
1459 : {
1460 0 : switch( nComp )
1461 : {
1462 : case COLORCOMP_RED:
1463 0 : mdRed = dValue;
1464 0 : break;
1465 : case COLORCOMP_GREEN:
1466 0 : mdGreen = dValue;
1467 0 : break;
1468 : case COLORCOMP_BLUE:
1469 0 : mdBlue = dValue;
1470 0 : break;
1471 : case COLORCOMP_HUE:
1472 0 : mdHue = dValue;
1473 0 : break;
1474 : case COLORCOMP_SAT:
1475 0 : mdSat = dValue;
1476 0 : break;
1477 : case COLORCOMP_BRI:
1478 0 : mdBri = dValue;
1479 0 : break;
1480 : case COLORCOMP_CYAN:
1481 0 : mdCyan = dValue;
1482 0 : break;
1483 : case COLORCOMP_YELLOW:
1484 0 : mdYellow = dValue;
1485 0 : break;
1486 : case COLORCOMP_MAGENTA:
1487 0 : mdMagenta = dValue;
1488 0 : break;
1489 : case COLORCOMP_KEY:
1490 0 : mdKey = dValue;
1491 0 : break;
1492 : }
1493 :
1494 0 : if (nComp & COLORMODE_RGB)
1495 : {
1496 0 : RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
1497 0 : RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
1498 : }
1499 0 : else if (nComp & COLORMODE_HSV)
1500 : {
1501 0 : HSVtoRGB( mdHue, mdSat, mdBri, mdRed, mdGreen, mdBlue );
1502 0 : RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
1503 : }
1504 : else
1505 : {
1506 0 : CMYKtoRGB( mdCyan, mdMagenta, mdYellow, mdKey, mdRed, mdGreen, mdBlue );
1507 0 : RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
1508 : }
1509 0 : }
1510 :
1511 : typedef ::cppu::WeakComponentImplHelper4< XServiceInfo, XExecutableDialog, XInitialization, XPropertyAccess > ColorPickerBase;
1512 :
1513 0 : class ColorPicker : protected ::comphelper::OBaseMutex, // Struct for right initalization of mutex member! Must be first of baseclasses.
1514 : public ColorPickerBase
1515 : {
1516 : public:
1517 : ColorPicker( Reference< XComponentContext > const & xContext );
1518 :
1519 : // XInitialization
1520 : virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
1521 :
1522 : // XInitialization
1523 : virtual OUString SAL_CALL getImplementationName( ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
1524 : virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
1525 : virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
1526 :
1527 : // XPropertyAccess
1528 : virtual Sequence< PropertyValue > SAL_CALL getPropertyValues( ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
1529 : virtual void SAL_CALL setPropertyValues( const Sequence< PropertyValue >& aProps ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception) SAL_OVERRIDE;
1530 :
1531 : // XExecutableDialog
1532 : virtual void SAL_CALL setTitle( const OUString& aTitle ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
1533 : virtual sal_Int16 SAL_CALL execute( ) throw (RuntimeException, std::exception) SAL_OVERRIDE;
1534 :
1535 : private:
1536 : Reference< XComponentContext > mxContext;
1537 : OUString msTitle;
1538 : const OUString msColorKey;
1539 : const OUString msModeKey;
1540 : sal_Int32 mnColor;
1541 : sal_Int16 mnMode;
1542 : Reference<css::awt::XWindow> mxParent;
1543 : };
1544 :
1545 0 : OUString SAL_CALL ColorPicker_getImplementationName()
1546 : {
1547 0 : return OUString( "com.sun.star.cui.ColorPicker" );
1548 : }
1549 :
1550 0 : Reference< XInterface > SAL_CALL ColorPicker_createInstance( Reference< XComponentContext > const & xContext )
1551 : {
1552 0 : return static_cast<XWeak*>( new ColorPicker( xContext ) );
1553 : }
1554 :
1555 0 : Sequence< OUString > SAL_CALL ColorPicker_getSupportedServiceNames() throw( RuntimeException )
1556 : {
1557 0 : Sequence< OUString > seq(1);
1558 0 : seq[0] = "com.sun.star.ui.dialogs.ColorPicker";
1559 0 : return seq;
1560 : }
1561 :
1562 0 : ColorPicker::ColorPicker( Reference< XComponentContext > const & xContext )
1563 : : ColorPickerBase( m_aMutex )
1564 : , mxContext( xContext )
1565 : , msColorKey( "Color" )
1566 : , msModeKey( "Mode" )
1567 : , mnColor( 0 )
1568 0 : , mnMode( 0 )
1569 : {
1570 0 : }
1571 :
1572 : // XInitialization
1573 0 : void SAL_CALL ColorPicker::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException, std::exception)
1574 : {
1575 0 : if( aArguments.getLength() == 1 )
1576 : {
1577 0 : aArguments[0] >>= mxParent;
1578 : }
1579 0 : }
1580 :
1581 : // XInitialization
1582 0 : OUString SAL_CALL ColorPicker::getImplementationName( ) throw (RuntimeException, std::exception)
1583 : {
1584 0 : return ColorPicker_getImplementationName();
1585 : }
1586 :
1587 0 : sal_Bool SAL_CALL ColorPicker::supportsService( const OUString& sServiceName ) throw (RuntimeException, std::exception)
1588 : {
1589 0 : return cppu::supportsService(this, sServiceName);
1590 : }
1591 :
1592 0 : Sequence< OUString > SAL_CALL ColorPicker::getSupportedServiceNames( ) throw (RuntimeException, std::exception)
1593 : {
1594 0 : return ColorPicker_getSupportedServiceNames();
1595 : }
1596 :
1597 : // XPropertyAccess
1598 0 : Sequence< PropertyValue > SAL_CALL ColorPicker::getPropertyValues( ) throw (RuntimeException, std::exception)
1599 : {
1600 0 : Sequence< PropertyValue > props(1);
1601 0 : props[0].Name = msColorKey;
1602 0 : props[0].Value <<= mnColor;
1603 0 : return props;
1604 : }
1605 :
1606 0 : void SAL_CALL ColorPicker::setPropertyValues( const Sequence< PropertyValue >& aProps ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception)
1607 : {
1608 0 : for( sal_Int32 n = 0; n < aProps.getLength(); n++ )
1609 : {
1610 0 : if( aProps[n].Name.equals( msColorKey ) )
1611 : {
1612 0 : aProps[n].Value >>= mnColor;
1613 : }
1614 0 : else if( aProps[n].Name.equals( msModeKey ) )
1615 : {
1616 0 : aProps[n].Value >>= mnMode;
1617 : }
1618 : }
1619 0 : }
1620 :
1621 : // XExecutableDialog
1622 0 : void SAL_CALL ColorPicker::setTitle( const OUString& sTitle ) throw (RuntimeException, std::exception)
1623 : {
1624 0 : msTitle = sTitle;
1625 0 : }
1626 :
1627 0 : sal_Int16 SAL_CALL ColorPicker::execute( ) throw (RuntimeException, std::exception)
1628 : {
1629 0 : ScopedVclPtrInstance< ColorPickerDialog > aDlg( VCLUnoHelper::GetWindow( mxParent ), mnColor, mnMode );
1630 0 : sal_Int16 ret = aDlg->Execute();
1631 0 : if( ret )
1632 0 : mnColor = aDlg->GetColor();
1633 :
1634 0 : return ret;
1635 : }
1636 :
1637 0 : }
1638 :
1639 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|