bump product version to 5.0.4.1
[LibreOffice.git] / cui / source / dialogs / colorpicker.cxx
blob0eb56724958ca5b9c8b84fa86660e0f11dd45218
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
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;
56 namespace cui
58 const sal_uInt16 COLORMODE_RGB = 0x10;
59 const sal_uInt16 COLORMODE_HSV = 0x20;
61 const sal_uInt16 COLORCOMP_RED = 0x10;
62 const sal_uInt16 COLORCOMP_GREEN = 0x11;
63 const sal_uInt16 COLORCOMP_BLUE = 0x12;
65 const sal_uInt16 COLORCOMP_HUE = 0x20;
66 const sal_uInt16 COLORCOMP_SAT = 0x21;
67 const sal_uInt16 COLORCOMP_BRI = 0x22;
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;
74 // color space conversion helpers
76 static void RGBtoHSV( double dR, double dG, double dB, double& dH, double& dS, double& dV )
78 BColor result = basegfx::tools::rgb2hsv( BColor( dR, dG, dB ) );
80 dH = result.getX();
81 dS = result.getY();
82 dV = result.getZ();
85 static void HSVtoRGB(double dH, double dS, double dV, double& dR, double& dG, double& dB )
87 BColor result = basegfx::tools::hsv2rgb( BColor( dH, dS, dV ) );
89 dR = result.getRed();
90 dG = result.getGreen();
91 dB = result.getBlue();
94 // CMYK values from 0 to 1
95 static void CMYKtoRGB( double fCyan, double fMagenta, double fYellow, double fKey, double& dR, double& dG, double& dB )
97 fCyan = (fCyan * ( 1.0 - fKey )) + fKey;
98 fMagenta = (fMagenta * ( 1.0 - fKey )) + fKey;
99 fYellow = (fYellow * ( 1.0 - fKey )) + fKey;
101 dR = std::max( std::min( ( 1.0 - fCyan ), 1.0), 0.0 );
102 dG = std::max( std::min( ( 1.0 - fMagenta ), 1.0), 0.0 );
103 dB = std::max( std::min( ( 1.0 - fYellow ), 1.0), 0.0 );
106 // CMY results from 0 to 1
107 static void RGBtoCMYK( double dR, double dG, double dB, double& fCyan, double& fMagenta, double& fYellow, double& fKey )
109 fCyan = 1 - dR;
110 fMagenta = 1 - dG;
111 fYellow = 1 - dB;
113 //CMYK and CMY values from 0 to 1
114 fKey = 1.0;
115 if( fCyan < fKey ) fKey = fCyan;
116 if( fMagenta < fKey ) fKey = fMagenta;
117 if( fYellow < fKey ) fKey = fYellow;
119 if( fKey >= 1.0 )
121 //Black
122 fCyan = 0.0;
123 fMagenta = 0.0;
124 fYellow = 0.0;
126 else
128 fCyan = ( fCyan - fKey ) / ( 1.0 - fKey );
129 fMagenta = ( fMagenta - fKey ) / ( 1.0 - fKey );
130 fYellow = ( fYellow - fKey ) / ( 1.0 - fKey );
134 class HexColorControl : public Edit
136 public:
137 HexColorControl( vcl::Window* pParent, const WinBits& nStyle );
139 virtual bool PreNotify( NotifyEvent& rNEvt ) SAL_OVERRIDE;
140 virtual void Paste() SAL_OVERRIDE;
142 void SetColor( sal_Int32 nColor );
143 sal_Int32 GetColor();
145 private:
146 static bool ImplProcessKeyInput( const KeyEvent& rKEv );
149 HexColorControl::HexColorControl( vcl::Window* pParent, const WinBits& nStyle )
150 : Edit(pParent, nStyle)
152 SetMaxTextLen( 6 );
155 VCL_BUILDER_FACTORY_ARGS(HexColorControl, WB_BORDER)
157 void HexColorControl::SetColor(sal_Int32 nColor)
159 OUStringBuffer aBuffer;
160 sax::Converter::convertColor(aBuffer, nColor);
161 SetText(aBuffer.makeStringAndClear().copy(1));
164 sal_Int32 HexColorControl::GetColor()
166 sal_Int32 nColor = -1;
168 OUString aStr("#");
169 aStr += GetText();
170 sal_Int32 nLen = aStr.getLength();
172 if (nLen < 7)
174 static const sal_Char* pNullStr = "000000";
175 aStr += OUString::createFromAscii( &pNullStr[nLen-1] );
178 sax::Converter::convertColor(nColor, aStr);
180 if (nColor == -1)
181 SetControlBackground(Color(COL_RED));
182 else
183 SetControlBackground();
185 return nColor;
188 bool HexColorControl::PreNotify( NotifyEvent& rNEvt )
190 if ( (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT) && !rNEvt.GetKeyEvent()->GetKeyCode().IsMod2() )
192 if ( ImplProcessKeyInput( *rNEvt.GetKeyEvent() ) )
193 return true;
196 return Edit::PreNotify( rNEvt );
199 void HexColorControl::Paste()
201 css::uno::Reference<css::datatransfer::clipboard::XClipboard> aClipboard(GetClipboard());
202 if (aClipboard.is())
204 css::uno::Reference<css::datatransfer::XTransferable> xDataObj;
208 SolarMutexReleaser aReleaser;
209 xDataObj = aClipboard->getContents();
211 catch (const css::uno::Exception&)
215 if (xDataObj.is())
217 css::datatransfer::DataFlavor aFlavor;
218 SotExchange::GetFormatDataFlavor(SotClipboardFormatId::STRING, aFlavor);
221 css::uno::Any aData = xDataObj->getTransferData(aFlavor);
222 OUString aText;
223 aData >>= aText;
225 if( !aText.isEmpty() && aText.startsWith( "#" ) )
226 aText = aText.copy(1);
228 if( aText.getLength() > 6 )
229 aText = aText.copy( 0, 6 );
231 SetText(aText);
233 catch(const css::uno::Exception&)
239 bool HexColorControl::ImplProcessKeyInput( const KeyEvent& rKEv )
241 const vcl::KeyCode& rKeyCode = rKEv.GetKeyCode();
243 if( rKeyCode.GetGroup() == KEYGROUP_ALPHA && !rKeyCode.IsMod1() && !rKeyCode.IsMod2() )
245 if( (rKeyCode.GetCode() < KEY_A) || (rKeyCode.GetCode() > KEY_F) )
246 return true;
248 else if( rKeyCode.GetGroup() == KEYGROUP_NUM )
250 if( rKeyCode.IsShift() )
251 return true;
253 return false;
256 class ColorPreviewControl : public Control
258 public:
259 ColorPreviewControl( vcl::Window* pParent, const WinBits& nStyle );
261 virtual void Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect) SAL_OVERRIDE;
263 void SetColor(const Color& rColor);
265 private:
266 Color maColor;
269 ColorPreviewControl::ColorPreviewControl(vcl::Window* pParent, const WinBits& nStyle)
270 : Control(pParent, nStyle)
274 VCL_BUILDER_DECL_FACTORY(ColorPreviewControl)
276 WinBits nBits = 0;
278 OString sBorder = VclBuilder::extractCustomProperty(rMap);
279 if (!sBorder.isEmpty())
280 nBits |= WB_BORDER;
282 rRet = VclPtr<ColorPreviewControl>::Create(pParent, nBits);
285 void ColorPreviewControl::SetColor( const Color& rCol )
287 if (rCol != maColor)
289 maColor = rCol;
290 Invalidate();
294 void ColorPreviewControl::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect)
296 rRenderContext.SetFillColor(maColor);
297 rRenderContext.SetLineColor(maColor);
298 rRenderContext.DrawRect(rRect);
301 enum ColorMode { HUE, SATURATION, BRIGHTNESS, RED, GREEN, BLUE };
302 const ColorMode DefaultMode = HUE;
304 class ColorFieldControl : public Control
306 public:
307 ColorFieldControl(vcl::Window* pParent, const WinBits& nStyle);
308 virtual ~ColorFieldControl();
310 virtual void dispose() SAL_OVERRIDE;
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;
319 virtual Size GetOptimalSize() const SAL_OVERRIDE;
321 void UpdateBitmap();
322 void ShowPosition( const Point& rPos, bool bUpdate );
323 void UpdatePosition();
324 void Modify();
326 void SetValues(Color aColor, ColorMode eMode, double x, double y);
327 double GetX() { return mdX;}
328 double GetY() { return mdY;}
330 void KeyMove(int dx, int dy);
332 void SetModifyHdl(Link<>& rLink) { maModifyHdl = rLink; }
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;
349 ColorFieldControl::ColorFieldControl( vcl::Window* pParent, const WinBits& nStyle )
350 : Control( pParent, nStyle )
351 , meMode( DefaultMode )
352 , mdX( -1.0 )
353 , mdY( -1.0 )
354 , mpBitmap( 0 )
356 SetControlBackground();
359 ColorFieldControl::~ColorFieldControl()
361 disposeOnce();
364 void ColorFieldControl::dispose()
366 delete mpBitmap;
367 mpBitmap = NULL;
368 Control::dispose();
371 VCL_BUILDER_DECL_FACTORY(ColorFieldControl)
373 WinBits nBits = 0;
375 OString sBorder = VclBuilder::extractCustomProperty(rMap);
376 if (!sBorder.isEmpty())
377 nBits |= WB_BORDER;
379 rRet = VclPtr<ColorFieldControl>::Create(pParent, nBits);
382 Size ColorFieldControl::GetOptimalSize() const
384 return LogicToPixel(Size(158, 158), MAP_APPFONT);
387 void ColorFieldControl::UpdateBitmap()
389 const Size aSize(GetOutputSizePixel());
391 if (mpBitmap && mpBitmap->GetSizePixel() != aSize)
392 delete mpBitmap, mpBitmap = NULL;
394 const sal_Int32 nWidth = aSize.Width();
395 const sal_Int32 nHeight = aSize.Height();
397 if (nWidth == 0 || nHeight == 0)
398 return;
400 if (!mpBitmap)
402 mpBitmap = new Bitmap( aSize, 24 );
404 maRGB_Horiz.resize( nWidth );
405 maGrad_Horiz.resize( nWidth );
406 maPercent_Horiz.resize( nWidth );
408 sal_uInt8* pRGB = maRGB_Horiz.data();
409 sal_uInt16* pGrad = maGrad_Horiz.data();
410 sal_uInt16* pPercent = maPercent_Horiz.data();
412 for( sal_Int32 x = 0; x < nWidth; x++ )
414 *pRGB++ = static_cast<sal_uInt8>((x * 256) / nWidth);
415 *pGrad++ = static_cast<sal_uInt16>((x * 359) / nWidth);
416 *pPercent++ = static_cast<sal_uInt16>((x * 100) / nWidth);
419 maRGB_Vert.resize(nHeight);
420 maPercent_Vert.resize(nHeight);
422 pRGB = maRGB_Vert.data();
423 pPercent = maPercent_Vert.data();
425 sal_Int32 y = nHeight;
426 while (y--)
428 *pRGB++ = static_cast<sal_uInt8>((y * 256) / nHeight);
429 *pPercent++ = static_cast<sal_uInt16>((y * 100) / nHeight);
433 sal_uInt8* pRGB_Horiz = maRGB_Horiz.data();
434 sal_uInt16* pGrad_Horiz = maGrad_Horiz.data();
435 sal_uInt16* pPercent_Horiz = maPercent_Horiz.data();
436 sal_uInt8* pRGB_Vert = maRGB_Vert.data();
437 sal_uInt16* pPercent_Vert = maPercent_Vert.data();
439 BitmapWriteAccess* pWriteAccess = mpBitmap->AcquireWriteAccess();
440 if (pWriteAccess)
442 BitmapColor aBitmapColor(maColor);
444 sal_uInt16 nHue, nSat, nBri;
445 maColor.RGBtoHSB(nHue, nSat, nBri);
447 // this has been unlooped for performance reason, please do not merge back!
449 sal_uInt16 y = nHeight,x;
451 switch(meMode)
453 case HUE:
454 while (y--)
456 nBri = pPercent_Vert[y];
457 x = nWidth;
458 while (x--)
460 nSat = pPercent_Horiz[x];
461 pWriteAccess->SetPixel(y, x, BitmapColor(Color(Color::HSBtoRGB(nHue, nSat, nBri))));
464 break;
465 case SATURATION:
466 while (y--)
468 nBri = pPercent_Vert[y];
469 x = nWidth;
470 while (x--)
472 nHue = pGrad_Horiz[x];
473 pWriteAccess->SetPixel(y, x, BitmapColor(Color(Color::HSBtoRGB(nHue, nSat, nBri))));
476 break;
477 case BRIGHTNESS:
478 while (y--)
480 nSat = pPercent_Vert[y];
481 x = nWidth;
482 while (x--)
484 nHue = pGrad_Horiz[x];
485 pWriteAccess->SetPixel(y, x, BitmapColor(Color(Color::HSBtoRGB(nHue, nSat, nBri))));
488 break;
489 case RED:
490 while (y--)
492 aBitmapColor.SetGreen(pRGB_Vert[y]);
493 x = nWidth;
494 while (x--)
496 aBitmapColor.SetBlue(pRGB_Horiz[x]);
497 pWriteAccess->SetPixel(y, x, aBitmapColor);
500 break;
501 case GREEN:
502 while (y--)
504 aBitmapColor.SetRed(pRGB_Vert[y]);
505 x = nWidth;
506 while (x--)
508 aBitmapColor.SetBlue(pRGB_Horiz[x]);
509 pWriteAccess->SetPixel(y, x, aBitmapColor);
512 break;
513 case BLUE:
514 while (y--)
516 aBitmapColor.SetGreen(pRGB_Vert[y]);
517 x = nWidth;
518 while (x--)
520 aBitmapColor.SetRed(pRGB_Horiz[x]);
521 pWriteAccess->SetPixel(y, x, aBitmapColor);
524 break;
527 Bitmap::ReleaseAccess(pWriteAccess);
531 void ColorFieldControl::ShowPosition( const Point& rPos, bool bUpdate )
533 if (!mpBitmap)
535 UpdateBitmap();
536 Invalidate();
539 if (!mpBitmap)
540 return;
542 const Size aSize(mpBitmap->GetSizePixel());
544 long nX = rPos.X();
545 long nY = rPos.Y();
546 if (nX < 0L)
547 nX = 0L;
548 else if (nX >= aSize.Width())
549 nX = aSize.Width() - 1L;
551 if (nY < 0L)
552 nY = 0L;
553 else if (nY >= aSize.Height())
554 nY = aSize.Height() - 1L;
556 Point aPos = maPosition;
557 maPosition.X() = nX - 5;
558 maPosition.Y() = nY - 5;
559 Invalidate(Rectangle(aPos, Size(11, 11)));
560 Invalidate(Rectangle(maPosition, Size(11, 11)));
562 if (bUpdate)
564 mdX = double(nX) / double(aSize.Width() - 1.0);
565 mdY = double(aSize.Height() - 1.0 - nY) / double(aSize.Height() - 1.0);
567 BitmapReadAccess* pReadAccess = mpBitmap->AcquireReadAccess();
568 if (pReadAccess != NULL)
570 // mpBitmap always has a bit count of 24 => use of GetPixel(...) is safe
571 maColor = pReadAccess->GetPixel(nY, nX);
572 Bitmap::ReleaseAccess(pReadAccess);
573 pReadAccess = NULL;
578 void ColorFieldControl::MouseMove( const MouseEvent& rMEvt )
580 if( rMEvt.IsLeft() )
582 ShowPosition( rMEvt.GetPosPixel(), true );
583 Modify();
587 void ColorFieldControl::MouseButtonDown( const MouseEvent& rMEvt )
589 if( rMEvt.IsLeft() && !rMEvt.IsShift() )
591 CaptureMouse();
592 ShowPosition( rMEvt.GetPosPixel(), true );
593 Modify();
597 void ColorFieldControl::MouseButtonUp( const MouseEvent& )
599 if( IsMouseCaptured() )
600 ReleaseMouse();
603 void ColorFieldControl::KeyMove( int dx, int dy )
605 Size aSize(GetOutputSizePixel());
606 Point aPos(static_cast<long>(mdX * aSize.Width()), static_cast<long>((1.0 - mdY) * aSize.Height()));
607 aPos.X() += dx;
608 aPos.Y() += dy;
609 if( aPos.X() < 0 )
610 aPos.X() += aSize.Width();
611 else if( aPos.X() >= aSize.Width() )
612 aPos.X() -= aSize.Width();
614 if( aPos.Y() < 0 )
615 aPos.Y() += aSize.Height();
616 else if( aPos.Y() >= aSize.Height() )
617 aPos.Y() -= aSize.Height();
619 ShowPosition( aPos, true );
620 Modify();
623 void ColorFieldControl::KeyInput( const KeyEvent& rKEvt )
625 bool bShift = rKEvt.GetKeyCode().IsShift();
626 bool bCtrl = rKEvt.GetKeyCode().IsMod1();
627 bool bAlt = rKEvt.GetKeyCode().IsMod2();
629 if (!bAlt && !bShift)
631 switch( rKEvt.GetKeyCode().GetCode() )
633 case KEY_DOWN:
634 KeyMove(0, bCtrl ? 5 : 1);
635 return;
636 case KEY_UP:
637 KeyMove(0, bCtrl ? -5 : -1);
638 return;
639 case KEY_LEFT:
640 KeyMove(bCtrl ? -5 : -1, 0);
641 return;
642 case KEY_RIGHT:
643 KeyMove(bCtrl ? 5 : 1, 0);
644 return;
647 Control::KeyInput(rKEvt);
650 void ColorFieldControl::Paint(vcl::RenderContext& rRenderContext, const Rectangle& rRect)
652 if (!mpBitmap)
653 UpdateBitmap();
655 if (mpBitmap)
657 Bitmap aOutputBitmap(*mpBitmap);
659 if (GetBitCount() <= 8)
660 aOutputBitmap.Dither();
662 rRenderContext.DrawBitmap(rRect.TopLeft(), rRect.GetSize(), rRect.TopLeft(), rRect.GetSize(), aOutputBitmap);
665 // draw circle around current color
666 if (maColor.IsDark())
667 rRenderContext.SetLineColor( COL_WHITE );
668 else
669 rRenderContext.SetLineColor( COL_BLACK );
671 rRenderContext.SetFillColor();
673 rRenderContext.DrawEllipse(Rectangle(maPosition, Size(11, 11)));
676 void ColorFieldControl::Resize()
678 UpdateBitmap();
679 UpdatePosition();
680 Control::Resize();
683 void ColorFieldControl::Modify()
685 maModifyHdl.Call( this );
688 void ColorFieldControl::SetValues( Color aColor, ColorMode eMode, double x, double y )
690 bool bUpdateBitmap = (maColor!= aColor) || (meMode != eMode);
691 if( bUpdateBitmap || (mdX != x) || (mdY != y) )
693 maColor = aColor;
694 meMode = eMode;
695 mdX = x;
696 mdY = y;
698 if (bUpdateBitmap)
699 UpdateBitmap();
700 UpdatePosition();
701 if (bUpdateBitmap)
702 Invalidate();
706 void ColorFieldControl::UpdatePosition()
708 Size aSize(GetOutputSizePixel());
709 ShowPosition(Point(static_cast<long>(mdX * aSize.Width()), static_cast<long>((1.0 - mdY) * aSize.Height())), false);
712 class ColorSliderControl : public Control
714 public:
715 ColorSliderControl( vcl::Window* pParent, const WinBits& nStyle );
716 virtual ~ColorSliderControl();
717 virtual void dispose() SAL_OVERRIDE;
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;
726 void UpdateBitmap();
727 void ChangePosition( long nY );
728 void Modify();
730 void SetValue( const Color& rColor, ColorMode eMode, double dValue );
731 double GetValue() const { return mdValue; }
733 void KeyMove( int dy );
735 void SetModifyHdl( Link<>& rLink ) { maModifyHdl = rLink; }
737 sal_Int16 GetLevel() const { return mnLevel; }
739 private:
740 Link<> maModifyHdl;
741 Color maColor;
742 ColorMode meMode;
743 Bitmap* mpBitmap;
744 sal_Int16 mnLevel;
745 double mdValue;
748 ColorSliderControl::ColorSliderControl( vcl::Window* pParent, const WinBits& nStyle )
749 : Control( pParent, nStyle )
750 , meMode( DefaultMode )
751 , mpBitmap( 0 )
752 , mnLevel( 0 )
753 , mdValue( -1.0 )
755 SetControlBackground();
758 ColorSliderControl::~ColorSliderControl()
760 disposeOnce();
763 void ColorSliderControl::dispose()
765 delete mpBitmap;
766 mpBitmap = NULL;
767 Control::dispose();
770 VCL_BUILDER_DECL_FACTORY(ColorSliderControl)
772 WinBits nBits = 0;
774 OString sBorder = VclBuilder::extractCustomProperty(rMap);
775 if (!sBorder.isEmpty())
776 nBits |= WB_BORDER;
778 rRet = VclPtr<ColorSliderControl>::Create(pParent, nBits);
781 void ColorSliderControl::UpdateBitmap()
783 Size aSize(1, GetOutputSizePixel().Height());
785 if (mpBitmap && mpBitmap->GetSizePixel() != aSize)
786 delete mpBitmap, mpBitmap = NULL;
788 if (!mpBitmap)
789 mpBitmap = new Bitmap(aSize, 24);
791 BitmapWriteAccess* pWriteAccess = mpBitmap->AcquireWriteAccess();
793 if (pWriteAccess)
795 const long nY = aSize.Height() - 1;
797 BitmapColor aBitmapColor(maColor);
799 sal_uInt16 nHue, nSat, nBri;
800 maColor.RGBtoHSB(nHue, nSat, nBri);
802 // this has been unlooped for performance reason, please do not merge back!
804 switch (meMode)
806 case HUE:
807 nSat = 100;
808 nBri = 100;
809 for (long y = 0; y <= nY; y++)
811 nHue = static_cast<sal_uInt16>((359 * y) / nY);
812 aBitmapColor = BitmapColor(Color(Color::HSBtoRGB(nHue, nSat, nBri)));
813 pWriteAccess->SetPixel(nY - y, 0, aBitmapColor);
815 break;
817 case SATURATION:
818 nBri = std::max(sal_uInt16(32), nBri);
819 for (long y = 0; y <= nY; y++)
821 nSat = static_cast<sal_uInt16>((100 * y) / nY);
822 pWriteAccess->SetPixel(nY - y, 0, BitmapColor(Color(Color::HSBtoRGB(nHue, nSat, nBri))));
824 break;
826 case BRIGHTNESS:
827 for (long y = 0; y <= nY; y++)
829 nBri = static_cast<sal_uInt16>((100 * y) / nY);
830 pWriteAccess->SetPixel(nY - y, 0, BitmapColor(Color(Color::HSBtoRGB(nHue, nSat, nBri))));
832 break;
834 case RED:
835 for (long y = 0; y <= nY; y++)
837 aBitmapColor.SetRed(sal_uInt8(((long)255 * y) / nY));
838 pWriteAccess->SetPixel(nY - y, 0, aBitmapColor);
840 break;
842 case GREEN:
843 for (long y = 0; y <= nY; y++)
845 aBitmapColor.SetGreen(sal_uInt8(((long)255 * y) / nY));
846 pWriteAccess->SetPixel(nY - y, 0, aBitmapColor);
848 break;
850 case BLUE:
851 for (long y = 0; y <= nY; y++)
853 aBitmapColor.SetBlue(sal_uInt8(((long)255 * y) / nY));
854 pWriteAccess->SetPixel(nY - y, 0, aBitmapColor);
856 break;
859 Bitmap::ReleaseAccess(pWriteAccess);
863 void ColorSliderControl::ChangePosition(long nY)
865 const long nHeight = GetOutputSizePixel().Height() - 1;
867 if (nY < 0L)
868 nY = 0;
869 else if (nY > nHeight)
870 nY = nHeight;
872 mnLevel = nY;
873 mdValue = double(nHeight - nY) / double(nHeight);
876 void ColorSliderControl::MouseMove( const MouseEvent& rMEvt )
878 if (rMEvt.IsLeft())
880 ChangePosition(rMEvt.GetPosPixel().Y());
881 Modify();
885 void ColorSliderControl::MouseButtonDown(const MouseEvent& rMEvt)
887 if (rMEvt.IsLeft() && !rMEvt.IsShift())
889 CaptureMouse();
890 ChangePosition( rMEvt.GetPosPixel().Y() );
891 Modify();
895 void ColorSliderControl::MouseButtonUp(const MouseEvent&)
897 if (IsMouseCaptured())
898 ReleaseMouse();
901 void ColorSliderControl::KeyMove(int dy)
903 ChangePosition( mnLevel + dy );
904 Modify();
907 void ColorSliderControl::KeyInput(const KeyEvent& rKEvt)
909 if (!rKEvt.GetKeyCode().IsMod2() && !rKEvt.GetKeyCode().IsShift())
911 switch (rKEvt.GetKeyCode().GetCode())
913 case KEY_DOWN:
914 KeyMove(rKEvt.GetKeyCode().IsMod1() ? 5 : 1);
915 return;
916 case KEY_UP:
917 KeyMove(rKEvt.GetKeyCode().IsMod1() ? -5 : -1);
918 return;
922 Control::KeyInput( rKEvt );
925 void ColorSliderControl::Paint(vcl::RenderContext& rRenderContext, const Rectangle& /*rRect*/)
927 if (!mpBitmap)
928 UpdateBitmap();
930 const Size aSize(GetOutputSizePixel());
932 Bitmap aOutputBitmap(*mpBitmap);
934 if (GetBitCount() <= 8)
935 aOutputBitmap.Dither();
937 Point aPos;
938 int x = aSize.Width();
939 while (x--)
941 rRenderContext.DrawBitmap(aPos, aOutputBitmap);
942 aPos.X() += 1;
946 void ColorSliderControl::Resize()
948 UpdateBitmap();
949 Control::Resize();
952 void ColorSliderControl::Modify()
954 maModifyHdl.Call(this);
957 void ColorSliderControl::SetValue(const Color& rColor, ColorMode eMode, double dValue)
959 bool bUpdateBitmap = (rColor != maColor) || (eMode != meMode);
960 if( bUpdateBitmap || (mdValue != dValue))
962 maColor = rColor;
963 mdValue = dValue;
964 mnLevel = static_cast<sal_Int16>((1.0-dValue) * GetOutputSizePixel().Height());
965 meMode = eMode;
966 if (bUpdateBitmap)
967 UpdateBitmap();
968 Invalidate();
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;
980 class ColorPickerDialog : public ModalDialog
982 public:
983 ColorPickerDialog(vcl::Window* pParent, sal_Int32 nColor, sal_Int16 nMode);
984 virtual ~ColorPickerDialog()
986 disposeOnce();
988 virtual void dispose() SAL_OVERRIDE;
990 void update_color(sal_uInt16 n = UPDATE_ALL);
992 DECL_LINK(ColorModifyHdl, void*);
993 DECL_LINK(ModeModifyHdl, void*);
995 sal_Int32 GetColor() const;
997 void setColorComponent(sal_uInt16 nComp, double dValue);
999 private:
1000 sal_Int16 mnDialogMode;
1001 ColorMode meMode;
1003 double mdRed, mdGreen, mdBlue;
1004 double mdHue, mdSat, mdBri;
1005 double mdCyan, mdMagenta, mdYellow, mdKey;
1007 private:
1008 VclPtr<ColorFieldControl> mpColorField;
1009 VclPtr<ColorSliderControl> mpColorSlider;
1010 VclPtr<ColorPreviewControl> mpColorPreview;
1011 VclPtr<ColorPreviewControl> mpColorPrevious;
1013 VclPtr<FixedImage> mpFISliderLeft;
1014 VclPtr<FixedImage> mpFISliderRight;
1015 Image maSliderImage;
1017 VclPtr<RadioButton> mpRBRed;
1018 VclPtr<RadioButton> mpRBGreen;
1019 VclPtr<RadioButton> mpRBBlue;
1020 VclPtr<RadioButton> mpRBHue;
1021 VclPtr<RadioButton> mpRBSaturation;
1022 VclPtr<RadioButton> mpRBBrightness;
1024 VclPtr<MetricField> mpMFRed;
1025 VclPtr<MetricField> mpMFGreen;
1026 VclPtr<MetricField> mpMFBlue;
1027 VclPtr<HexColorControl> mpEDHex;
1029 VclPtr<MetricField> mpMFHue;
1030 VclPtr<MetricField> mpMFSaturation;
1031 VclPtr<MetricField> mpMFBrightness;
1033 VclPtr<MetricField> mpMFCyan;
1034 VclPtr<MetricField> mpMFMagenta;
1035 VclPtr<MetricField> mpMFYellow;
1036 VclPtr<MetricField> mpMFKey;
1039 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 , maSliderImage( FixedImage::loadThemeImage("res/colorslider.png") )
1045 get(mpColorField, "colorField");
1046 get(mpColorSlider, "colorSlider");
1047 get(mpColorPreview, "preview");
1048 get(mpColorPrevious, "previous");
1049 get(mpRBRed, "redRadiobutton");
1050 get(mpRBGreen, "greenRadiobutton");
1051 get(mpRBBlue, "blueRadiobutton");
1052 get(mpRBHue, "hueRadiobutton");
1053 get(mpRBSaturation, "satRadiobutton");
1054 get(mpRBBrightness, "brightRadiobutton");
1055 get(mpMFRed, "redSpinbutton");
1056 get(mpMFGreen, "greenSpinbutton");
1057 get(mpMFBlue, "blueSpinbutton");
1058 get(mpEDHex, "hexEntry");
1059 get(mpMFHue, "hueSpinbutton");
1060 get(mpMFSaturation, "satSpinbutton");
1061 get(mpMFBrightness, "brightSpinbutton");
1062 get(mpMFCyan, "cyanSpinbutton");
1063 get(mpMFMagenta, "magSpinbutton");
1064 get(mpMFYellow, "yellowSpinbutton");
1065 get(mpMFKey, "keySpinbutton");
1066 get(mpFISliderLeft, "leftImage");
1067 get(mpFISliderRight, "rightImage");
1069 Size aDialogSize = get_preferred_size();
1070 set_width_request(aDialogSize.Width() + 50);
1071 set_height_request(aDialogSize.Height() + 30);
1073 Link<> aLink( LINK( this, ColorPickerDialog, ColorModifyHdl ) );
1074 mpColorField->SetModifyHdl( aLink );
1075 mpColorSlider->SetModifyHdl( aLink );
1077 mpMFRed->SetModifyHdl( aLink );
1078 mpMFGreen->SetModifyHdl( aLink );
1079 mpMFBlue->SetModifyHdl( aLink );
1081 mpMFCyan->SetModifyHdl( aLink );
1082 mpMFMagenta->SetModifyHdl( aLink );
1083 mpMFYellow->SetModifyHdl( aLink );
1084 mpMFKey->SetModifyHdl( aLink );
1086 mpMFHue->SetModifyHdl( aLink );
1087 mpMFSaturation->SetModifyHdl( aLink );
1088 mpMFBrightness->SetModifyHdl( aLink );
1090 mpEDHex->SetModifyHdl( aLink );
1092 aLink = LINK( this, ColorPickerDialog, ModeModifyHdl );
1093 mpRBRed->SetToggleHdl( aLink );
1094 mpRBGreen->SetToggleHdl( aLink );
1095 mpRBBlue->SetToggleHdl( aLink );
1096 mpRBHue->SetToggleHdl( aLink );
1097 mpRBSaturation->SetToggleHdl( aLink );
1098 mpRBBrightness->SetToggleHdl( aLink );
1100 Image aSliderImage( maSliderImage );
1102 mpFISliderLeft->SetImage( aSliderImage );
1103 mpFISliderLeft->Show(true);
1105 BitmapEx aTmpBmp( maSliderImage.GetBitmapEx() );
1106 aTmpBmp.Mirror( BmpMirrorFlags::Horizontal );
1107 mpFISliderRight->SetImage( Image( aTmpBmp ) );
1109 Size aSize( maSliderImage.GetSizePixel() );
1110 mpFISliderLeft->SetSizePixel( aSize );
1111 mpFISliderRight->SetSizePixel( aSize );
1113 Point aPos( mpColorSlider->GetPosPixel() );
1115 aPos.X() -= aSize.Width();
1116 aPos.Y() -= aSize.Height() / 2;
1117 mpFISliderLeft->SetPosPixel( aPos );
1119 aPos.X() += aSize.Width() + mpColorSlider->GetSizePixel().Width();
1120 mpFISliderRight->SetPosPixel( aPos );
1122 Color aColor( nColor );
1124 // modify
1125 if( mnDialogMode == 2 )
1127 mpColorPreview->SetSizePixel( mpColorPrevious->GetSizePixel() );
1128 mpColorPrevious->SetColor( aColor );
1129 mpColorPrevious->Show( true );
1132 mdRed = ((double)aColor.GetRed()) / 255.0;
1133 mdGreen = ((double)aColor.GetGreen()) / 255.0;
1134 mdBlue = ((double)aColor.GetBlue()) / 255.0;
1136 RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
1137 RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
1139 update_color();
1142 void ColorPickerDialog::dispose()
1144 mpColorField.clear();
1145 mpColorSlider.clear();
1146 mpColorPreview.clear();
1147 mpColorPrevious.clear();
1148 mpFISliderLeft.clear();
1149 mpFISliderRight.clear();
1150 mpRBRed.clear();
1151 mpRBGreen.clear();
1152 mpRBBlue.clear();
1153 mpRBHue.clear();
1154 mpRBSaturation.clear();
1155 mpRBBrightness.clear();
1156 mpMFRed.clear();
1157 mpMFGreen.clear();
1158 mpMFBlue.clear();
1159 mpEDHex.clear();
1160 mpMFHue.clear();
1161 mpMFSaturation.clear();
1162 mpMFBrightness.clear();
1163 mpMFCyan.clear();
1164 mpMFMagenta.clear();
1165 mpMFYellow.clear();
1166 mpMFKey.clear();
1167 ModalDialog::dispose();
1170 static int toInt( double dValue, double dRange )
1172 return static_cast< int >( std::floor((dValue * dRange) + 0.5 ) );
1175 sal_Int32 ColorPickerDialog::GetColor() const
1177 return Color( toInt(mdRed,255.0), toInt(mdGreen,255.0), toInt(mdBlue,255.0) ).GetColor();
1180 void ColorPickerDialog::update_color( sal_uInt16 n )
1182 sal_uInt8 nRed = toInt(mdRed,255.0);
1183 sal_uInt8 nGreen = toInt(mdGreen,255.0);
1184 sal_uInt8 nBlue = toInt(mdBlue,255.0);
1186 Color aColor(nRed, nGreen, nBlue);
1188 if (n & UPDATE_RGB) // update RGB
1190 mpMFRed->SetValue(nRed);
1191 mpMFGreen->SetValue(nGreen);
1192 mpMFBlue->SetValue(nBlue);
1195 if (n & UPDATE_CMYK) // update CMYK
1197 mpMFCyan->SetValue(toInt(mdCyan, 100.0));
1198 mpMFMagenta->SetValue(toInt(mdMagenta, 100.0));
1199 mpMFYellow->SetValue(toInt(mdYellow, 100.0));
1200 mpMFKey->SetValue(toInt(mdKey, 100.0));
1203 if (n & UPDATE_HSB ) // update HSB
1205 mpMFHue->SetValue(toInt(mdHue, 1.0));
1206 mpMFSaturation->SetValue(toInt( mdSat, 100.0));
1207 mpMFBrightness->SetValue(toInt( mdBri, 100.0));
1210 if (n & UPDATE_COLORCHOOSER ) // update Color Chooser 1
1212 switch( meMode )
1214 case HUE:
1215 mpColorField->SetValues(aColor, meMode, mdSat, mdBri);
1216 break;
1217 case SATURATION:
1218 mpColorField->SetValues(aColor, meMode, mdHue / 360.0, mdBri);
1219 break;
1220 case BRIGHTNESS:
1221 mpColorField->SetValues(aColor, meMode, mdHue / 360.0, mdSat);
1222 break;
1223 case RED:
1224 mpColorField->SetValues(aColor, meMode, mdBlue, mdGreen);
1225 break;
1226 case GREEN:
1227 mpColorField->SetValues(aColor, meMode, mdBlue, mdRed);
1228 break;
1229 case BLUE:
1230 mpColorField->SetValues(aColor, meMode, mdRed, mdGreen);
1231 break;
1235 if (n & UPDATE_COLORSLIDER) // update Color Chooser 2
1237 switch (meMode)
1239 case HUE:
1240 mpColorSlider->SetValue(aColor, meMode, mdHue / 360.0);
1241 break;
1242 case SATURATION:
1243 mpColorSlider->SetValue(aColor, meMode, mdSat);
1244 break;
1245 case BRIGHTNESS:
1246 mpColorSlider->SetValue(aColor, meMode, mdBri);
1247 break;
1248 case RED:
1249 mpColorSlider->SetValue(aColor, meMode, mdRed);
1250 break;
1251 case GREEN:
1252 mpColorSlider->SetValue(aColor, meMode, mdGreen);
1253 break;
1254 case BLUE:
1255 mpColorSlider->SetValue(aColor, meMode, mdBlue);
1256 break;
1260 if (n & UPDATE_HEX) // update hex
1262 mpEDHex->SetColor(aColor.GetColor());
1266 Point aPos(0, mpColorSlider->GetLevel() + mpColorSlider->GetPosPixel().Y() - 1);
1268 aPos.X() = mpFISliderLeft->GetPosPixel().X();
1269 if (aPos != mpFISliderLeft->GetPosPixel())
1271 mpFISliderLeft->SetPosPixel(aPos);
1273 aPos.X() = mpFISliderRight->GetPosPixel().X();
1274 mpFISliderRight->SetPosPixel(aPos);
1278 mpColorPreview->SetColor(aColor);
1281 IMPL_LINK(ColorPickerDialog, ColorModifyHdl, void *, p)
1283 sal_uInt16 n = 0;
1285 if (p == mpColorField)
1287 double x = mpColorField->GetX();
1288 double y = mpColorField->GetY();
1290 switch( meMode )
1292 case HUE:
1293 mdSat = x;
1294 setColorComponent( COLORCOMP_BRI, y );
1295 break;
1296 case SATURATION:
1297 mdHue = x * 360.0;
1298 setColorComponent( COLORCOMP_BRI, y );
1299 break;
1300 case BRIGHTNESS:
1301 mdHue = x * 360.0;
1302 setColorComponent( COLORCOMP_SAT, y );
1303 break;
1304 case RED:
1305 mdBlue = x;
1306 setColorComponent( COLORCOMP_GREEN, y );
1307 break;
1308 case GREEN:
1309 mdBlue = x;
1310 setColorComponent( COLORCOMP_RED, y );
1311 break;
1312 case BLUE:
1313 mdRed = x;
1314 setColorComponent( COLORCOMP_GREEN, y );
1315 break;
1318 n = UPDATE_ALL &~ (UPDATE_COLORCHOOSER);
1320 else if (p == mpColorSlider)
1322 double dValue = mpColorSlider->GetValue();
1323 switch (meMode)
1325 case HUE:
1326 setColorComponent( COLORCOMP_HUE, dValue * 360.0 );
1327 break;
1328 case SATURATION:
1329 setColorComponent( COLORCOMP_SAT, dValue );
1330 break;
1331 case BRIGHTNESS:
1332 setColorComponent( COLORCOMP_BRI, dValue );
1333 break;
1334 case RED:
1335 setColorComponent( COLORCOMP_RED, dValue );
1336 break;
1337 case GREEN:
1338 setColorComponent( COLORCOMP_GREEN, dValue );
1339 break;
1340 case BLUE:
1341 setColorComponent( COLORCOMP_BLUE, dValue );
1342 break;
1345 n = UPDATE_ALL&~(UPDATE_COLORSLIDER);
1347 else if (p == mpMFRed)
1349 setColorComponent( COLORCOMP_RED, ((double)mpMFRed->GetValue()) / 255.0 );
1350 n = UPDATE_ALL &~ (UPDATE_RGB);
1352 else if (p == mpMFGreen)
1354 setColorComponent( COLORCOMP_GREEN, ((double)mpMFGreen->GetValue()) / 255.0 );
1355 n = UPDATE_ALL &~ (UPDATE_RGB);
1357 else if (p == mpMFBlue)
1359 setColorComponent( COLORCOMP_BLUE, ((double)mpMFBlue->GetValue()) / 255.0 );
1360 n = UPDATE_ALL &~ (UPDATE_RGB);
1362 else if (p == mpMFHue)
1364 setColorComponent( COLORCOMP_HUE, (double)mpMFHue->GetValue() );
1365 n = UPDATE_ALL &~ (UPDATE_HSB);
1367 else if (p == mpMFSaturation)
1369 setColorComponent( COLORCOMP_SAT, ((double)mpMFSaturation->GetValue()) / 100.0 );
1370 n = UPDATE_ALL &~ (UPDATE_HSB);
1372 else if (p == mpMFBrightness)
1374 setColorComponent( COLORCOMP_BRI, ((double)mpMFBrightness->GetValue()) / 100.0 );
1375 n = UPDATE_ALL &~ (UPDATE_HSB);
1377 else if (p == mpMFCyan)
1379 setColorComponent( COLORCOMP_CYAN, ((double)mpMFCyan->GetValue()) / 100.0 );
1380 n = UPDATE_ALL &~ (UPDATE_CMYK);
1382 else if (p == mpMFMagenta)
1384 setColorComponent( COLORCOMP_MAGENTA, ((double)mpMFMagenta->GetValue()) / 100.0 );
1385 n = UPDATE_ALL &~ (UPDATE_CMYK);
1387 else if (p == mpMFYellow)
1389 setColorComponent( COLORCOMP_YELLOW, ((double)mpMFYellow->GetValue()) / 100.0 );
1390 n = UPDATE_ALL &~ (UPDATE_CMYK);
1392 else if (p == mpMFKey)
1394 setColorComponent( COLORCOMP_KEY, ((double)mpMFKey->GetValue()) / 100.0 );
1395 n = UPDATE_ALL&~(UPDATE_CMYK);
1397 else if (p == mpEDHex)
1399 sal_Int32 nColor = mpEDHex->GetColor();
1401 if (nColor != -1)
1403 Color aColor(nColor);
1405 if (aColor != GetColor())
1407 mdRed = ((double)aColor.GetRed()) / 255.0;
1408 mdGreen = ((double)aColor.GetGreen()) / 255.0;
1409 mdBlue = ((double)aColor.GetBlue()) / 255.0;
1411 RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
1412 RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
1413 n = UPDATE_ALL &~ (UPDATE_HEX);
1418 if (n)
1419 update_color(n);
1421 return 0;
1424 IMPL_LINK_NOARG(ColorPickerDialog, ModeModifyHdl)
1426 ColorMode eMode = HUE;
1428 if (mpRBRed->IsChecked())
1430 eMode = RED;
1432 else if (mpRBGreen->IsChecked())
1434 eMode = GREEN;
1436 else if (mpRBBlue->IsChecked())
1438 eMode = BLUE;
1440 else if (mpRBSaturation->IsChecked())
1442 eMode = SATURATION;
1444 else if (mpRBBrightness->IsChecked())
1446 eMode = BRIGHTNESS;
1449 if (meMode != eMode)
1451 meMode = eMode;
1452 update_color(UPDATE_COLORCHOOSER | UPDATE_COLORSLIDER);
1455 return 0;
1458 void ColorPickerDialog::setColorComponent( sal_uInt16 nComp, double dValue )
1460 switch( nComp )
1462 case COLORCOMP_RED:
1463 mdRed = dValue;
1464 break;
1465 case COLORCOMP_GREEN:
1466 mdGreen = dValue;
1467 break;
1468 case COLORCOMP_BLUE:
1469 mdBlue = dValue;
1470 break;
1471 case COLORCOMP_HUE:
1472 mdHue = dValue;
1473 break;
1474 case COLORCOMP_SAT:
1475 mdSat = dValue;
1476 break;
1477 case COLORCOMP_BRI:
1478 mdBri = dValue;
1479 break;
1480 case COLORCOMP_CYAN:
1481 mdCyan = dValue;
1482 break;
1483 case COLORCOMP_YELLOW:
1484 mdYellow = dValue;
1485 break;
1486 case COLORCOMP_MAGENTA:
1487 mdMagenta = dValue;
1488 break;
1489 case COLORCOMP_KEY:
1490 mdKey = dValue;
1491 break;
1494 if (nComp & COLORMODE_RGB)
1496 RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
1497 RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
1499 else if (nComp & COLORMODE_HSV)
1501 HSVtoRGB( mdHue, mdSat, mdBri, mdRed, mdGreen, mdBlue );
1502 RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
1504 else
1506 CMYKtoRGB( mdCyan, mdMagenta, mdYellow, mdKey, mdRed, mdGreen, mdBlue );
1507 RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
1511 typedef ::cppu::WeakComponentImplHelper4< XServiceInfo, XExecutableDialog, XInitialization, XPropertyAccess > ColorPickerBase;
1513 class ColorPicker : protected ::comphelper::OBaseMutex, // Struct for right initalization of mutex member! Must be first of baseclasses.
1514 public ColorPickerBase
1516 public:
1517 ColorPicker( Reference< XComponentContext > const & xContext );
1519 // XInitialization
1520 virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException, std::exception) SAL_OVERRIDE;
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;
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;
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;
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;
1545 OUString SAL_CALL ColorPicker_getImplementationName()
1547 return OUString( "com.sun.star.cui.ColorPicker" );
1550 Reference< XInterface > SAL_CALL ColorPicker_createInstance( Reference< XComponentContext > const & xContext )
1552 return static_cast<XWeak*>( new ColorPicker( xContext ) );
1555 Sequence< OUString > SAL_CALL ColorPicker_getSupportedServiceNames() throw( RuntimeException )
1557 Sequence< OUString > seq(1);
1558 seq[0] = "com.sun.star.ui.dialogs.ColorPicker";
1559 return seq;
1562 ColorPicker::ColorPicker( Reference< XComponentContext > const & xContext )
1563 : ColorPickerBase( m_aMutex )
1564 , mxContext( xContext )
1565 , msColorKey( "Color" )
1566 , msModeKey( "Mode" )
1567 , mnColor( 0 )
1568 , mnMode( 0 )
1572 // XInitialization
1573 void SAL_CALL ColorPicker::initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException, std::exception)
1575 if( aArguments.getLength() == 1 )
1577 aArguments[0] >>= mxParent;
1581 // XInitialization
1582 OUString SAL_CALL ColorPicker::getImplementationName( ) throw (RuntimeException, std::exception)
1584 return ColorPicker_getImplementationName();
1587 sal_Bool SAL_CALL ColorPicker::supportsService( const OUString& sServiceName ) throw (RuntimeException, std::exception)
1589 return cppu::supportsService(this, sServiceName);
1592 Sequence< OUString > SAL_CALL ColorPicker::getSupportedServiceNames( ) throw (RuntimeException, std::exception)
1594 return ColorPicker_getSupportedServiceNames();
1597 // XPropertyAccess
1598 Sequence< PropertyValue > SAL_CALL ColorPicker::getPropertyValues( ) throw (RuntimeException, std::exception)
1600 Sequence< PropertyValue > props(1);
1601 props[0].Name = msColorKey;
1602 props[0].Value <<= mnColor;
1603 return props;
1606 void SAL_CALL ColorPicker::setPropertyValues( const Sequence< PropertyValue >& aProps ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException, std::exception)
1608 for( sal_Int32 n = 0; n < aProps.getLength(); n++ )
1610 if( aProps[n].Name.equals( msColorKey ) )
1612 aProps[n].Value >>= mnColor;
1614 else if( aProps[n].Name.equals( msModeKey ) )
1616 aProps[n].Value >>= mnMode;
1621 // XExecutableDialog
1622 void SAL_CALL ColorPicker::setTitle( const OUString& sTitle ) throw (RuntimeException, std::exception)
1624 msTitle = sTitle;
1627 sal_Int16 SAL_CALL ColorPicker::execute( ) throw (RuntimeException, std::exception)
1629 ScopedVclPtrInstance< ColorPickerDialog > aDlg( VCLUnoHelper::GetWindow( mxParent ), mnColor, mnMode );
1630 sal_Int16 ret = aDlg->Execute();
1631 if( ret )
1632 mnColor = aDlg->GetColor();
1634 return ret;
1639 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */