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