1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include "precompiled_sd.hxx"
25
26 #include "view/SlsTheme.hxx"
27 #include "SlsResource.hxx"
28 #include "controller/SlsProperties.hxx"
29 #include "sdresid.hxx"
30 #include <tools/color.hxx>
31 #include <vcl/outdev.hxx>
32 #include <vcl/image.hxx>
33 #include <vcl/svapp.hxx>
34 #include <svtools/colorcfg.hxx>
35
36 namespace sd { namespace slidesorter { namespace view {
37
38 const static ColorData Black = 0x000000;
39 const static ColorData White = 0xffffff;
40
41
42
ChangeLuminance(const ColorData aColorData,const int nValue)43 ColorData ChangeLuminance (const ColorData aColorData, const int nValue)
44 {
45 Color aColor (aColorData);
46 if (nValue > 0)
47 aColor.IncreaseLuminance(nValue);
48 else
49 aColor.DecreaseLuminance(-nValue);
50 return aColor.GetColor();
51 }
52
HGBAdapt(const ColorData aColorData,const sal_Int32 nNewSaturation,const sal_Int32 nNewBrightness)53 ColorData HGBAdapt (
54 const ColorData aColorData,
55 const sal_Int32 nNewSaturation,
56 const sal_Int32 nNewBrightness)
57 {
58 sal_uInt16 nHue (0);
59 sal_uInt16 nSaturation (0);
60 sal_uInt16 nBrightness (0);
61 Color(aColorData).RGBtoHSB(nHue, nSaturation, nBrightness);
62 return Color::HSBtoRGB(
63 nHue,
64 nNewSaturation>=0 ? nNewSaturation : nSaturation,
65 nNewBrightness>=0 ? nNewBrightness : nBrightness);
66 }
67
68
69
70
Theme(const::boost::shared_ptr<controller::Properties> & rpProperties)71 Theme::Theme (const ::boost::shared_ptr<controller::Properties>& rpProperties)
72 : mbIsHighContrastMode(false),
73 maBackgroundColor(rpProperties->GetBackgroundColor().GetColor()),
74 maPageBackgroundColor(COL_WHITE),
75 maGradients(),
76 maIcons(),
77 maColor(),
78 maIntegerValues()
79 {
80 {
81 LocalResource aResource (RID_SLIDESORTER_ICONS);
82
83 maStrings.resize(_StringType_Size_);
84 maStrings[String_DragAndDropPages] = String(SdResId(STRING_DRAG_AND_DROP_PAGES));
85 maStrings[String_DragAndDropSlides] = String(SdResId(STRING_DRAG_AND_DROP_SLIDES));
86 maStrings[String_Command1] = String(SdResId(STRING_COMMAND1));
87 maStrings[String_Command2] = String(SdResId(STRING_COMMAND2_A));
88 maStrings[String_Command2B] = String(SdResId(STRING_COMMAND2_B));
89 maStrings[String_Command3] = String(SdResId(STRING_COMMAND3));
90
91 maColor.resize(_ColorType_Size_);
92 maColor[Color_Background] = maBackgroundColor;
93 maColor[Color_ButtonBackground] = Black;
94 maColor[Color_ButtonText] = 0xc0c0c0;
95 maColor[Color_ButtonTextHover] = White;
96 maColor[Color_PageNumberDefault] = 0x0808080;
97 maColor[Color_PageNumberHover] = 0x4c4c4c;
98 maColor[Color_PageNumberHighContrast] = White;
99 maColor[Color_PageNumberBrightBackground] = 0x333333;
100 maColor[Color_PageNumberDarkBackground] = 0xcccccc;
101 maColor[Color_PreviewBorder] = 0x949599;
102
103 maIntegerValues.resize(_IntegerValueType_Size_);
104 maIntegerValues[Integer_ButtonCornerRadius] = 3;
105 maIntegerValues[Integer_ButtonMaxAlpha] = 0;
106 maIntegerValues[Integer_ButtonBarMaxAlpha] = 0;
107 maIntegerValues[Integer_ButtonPaintType] = 1;
108 maIntegerValues[Integer_ButtonBorder] = 4;
109 maIntegerValues[Integer_ButtonGap] = 0;
110 maIntegerValues[Integer_ButtonFadeInDelay] = 800;
111 maIntegerValues[Integer_ButtonFadeInDuration] = 100;
112 maIntegerValues[Integer_ButtonFadeOutDelay] = 0;
113 maIntegerValues[Integer_ButtonFadeOutDuration] = 100;
114 maIntegerValues[Integer_ToolTipDelay] = 1000;
115 maIntegerValues[Integer_FocusIndicatorWidth] = 3;
116 }
117
118 Update(rpProperties);
119 }
120
121
122
123
Update(const::boost::shared_ptr<controller::Properties> & rpProperties)124 void Theme::Update (const ::boost::shared_ptr<controller::Properties>& rpProperties)
125 {
126 const bool bSavedHighContrastMode (mbIsHighContrastMode);
127 mbIsHighContrastMode = rpProperties->IsHighContrastModeActive();
128
129 // Set up colors.
130 maBackgroundColor = rpProperties->GetBackgroundColor().GetColor();
131 maPageBackgroundColor = svtools::ColorConfig().GetColorValue(svtools::DOCCOLOR).nColor;
132
133 maColor[Color_Background] = maBackgroundColor;
134
135 maGradients.resize(_GradientColorType_Size_);
136
137 maColor[Color_Background] = maBackgroundColor;
138 const ColorData aSelectionColor (rpProperties->GetSelectionColor().GetColor());
139 maColor[Color_Selection] = aSelectionColor;
140 if (Color(aSelectionColor).IsBright())
141 maColor[Color_PageCountFontColor] = Black;
142 else
143 maColor[Color_PageCountFontColor] = White;
144
145 // Set up gradients.
146 SetGradient(Gradient_SelectedPage, aSelectionColor, 50, 50, +100,+100, +50,+25);
147 SetGradient(Gradient_MouseOverPage, aSelectionColor, 75, 75, +100,+100, +50,+25);
148 SetGradient(Gradient_SelectedAndFocusedPage, aSelectionColor, 50, 50, +100,+100, -50,-75);
149 SetGradient(Gradient_MouseOverSelectedAndFocusedPage, aSelectionColor, 75, 75, +100,+100, -50,-75);
150 SetGradient(Gradient_FocusedPage, aSelectionColor, -1,-1, 0,0, -50,-75);
151
152 SetGradient(Gradient_ButtonBackground, Black, -1,-1, 0,0, 0,0);
153 SetGradient(Gradient_NormalPage, maBackgroundColor, -1,-1, 0,0, 0,0);
154
155 // The focused gradient needs special handling because its fill color is
156 // like that of the NormalPage gradient.
157 GetGradient(Gradient_FocusedPage).maFillColor1 = GetGradient(Gradient_NormalPage).maFillColor1;
158 GetGradient(Gradient_FocusedPage).maFillColor2 = GetGradient(Gradient_NormalPage).maFillColor2;
159
160 // Set up icons.
161 if (bSavedHighContrastMode != mbIsHighContrastMode || maIcons.empty())
162 {
163 LocalResource aResource (RID_SLIDESORTER_ICONS);
164
165 maIcons.resize(_IconType_Size_);
166 if (mbIsHighContrastMode)
167 {
168 InitializeIcon(Icon_RawShadow, IMAGE_SHADOW);
169 InitializeIcon(Icon_RawInsertShadow, IMAGE_INSERT_SHADOW);
170 InitializeIcon(Icon_HideSlideOverlay, IMAGE_HIDE_SLIDE_OVERLAY);
171
172 InitializeIcon(Icon_ButtonBarLarge, IMAGE_BUTTONBAR_LARGE_HC);
173 InitializeIcon(Icon_ButtonBarMedium, IMAGE_BUTTONBAR_MEDIUM_HC);
174 InitializeIcon(Icon_ButtonBarSmall, IMAGE_BUTTONBAR_SMALL_HC);
175
176 InitializeIcon(Icon_Command1Large, IMAGE_COMMAND1_LARGE_HC);
177 InitializeIcon(Icon_Command1LargeHover, IMAGE_COMMAND1_LARGE_HOVER_HC);
178 InitializeIcon(Icon_Command1Medium, IMAGE_COMMAND1_MEDIUM_HC);
179 InitializeIcon(Icon_Command1MediumHover, IMAGE_COMMAND1_MEDIUM_HOVER_HC);
180 InitializeIcon(Icon_Command1Small, IMAGE_COMMAND1_SMALL_HC);
181 InitializeIcon(Icon_Command1SmallHover, IMAGE_COMMAND1_SMALL_HOVER_HC);
182
183 InitializeIcon(Icon_Command2Large, IMAGE_COMMAND2_LARGE_HC);
184 InitializeIcon(Icon_Command2LargeHover, IMAGE_COMMAND2_LARGE_HOVER_HC);
185 InitializeIcon(Icon_Command2Medium, IMAGE_COMMAND2_MEDIUM_HC);
186 InitializeIcon(Icon_Command2MediumHover, IMAGE_COMMAND2_MEDIUM_HOVER_HC);
187 InitializeIcon(Icon_Command2Small, IMAGE_COMMAND2_SMALL_HC);
188 InitializeIcon(Icon_Command2SmallHover, IMAGE_COMMAND2_SMALL_HOVER_HC);
189
190 InitializeIcon(Icon_Command2BLarge, IMAGE_COMMAND2B_LARGE_HC);
191 InitializeIcon(Icon_Command2BLargeHover, IMAGE_COMMAND2B_LARGE_HOVER_HC);
192 InitializeIcon(Icon_Command2BMedium, IMAGE_COMMAND2B_MEDIUM_HC);
193 InitializeIcon(Icon_Command2BMediumHover, IMAGE_COMMAND2B_MEDIUM_HOVER_HC);
194 InitializeIcon(Icon_Command2BSmall, IMAGE_COMMAND2B_SMALL_HC);
195 InitializeIcon(Icon_Command2BSmallHover, IMAGE_COMMAND2B_SMALL_HOVER_HC);
196
197 InitializeIcon(Icon_Command3Large, IMAGE_COMMAND3_LARGE_HC);
198 InitializeIcon(Icon_Command3LargeHover, IMAGE_COMMAND3_LARGE_HOVER_HC);
199 InitializeIcon(Icon_Command3Medium, IMAGE_COMMAND3_SMALL_HC);
200 InitializeIcon(Icon_Command3MediumHover, IMAGE_COMMAND3_SMALL_HOVER_HC);
201 InitializeIcon(Icon_Command3Small, IMAGE_COMMAND3_SMALL_HC);
202 InitializeIcon(Icon_Command3SmallHover, IMAGE_COMMAND3_SMALL_HOVER_HC);
203 }
204 else
205 {
206 InitializeIcon(Icon_RawShadow, IMAGE_SHADOW);
207 InitializeIcon(Icon_RawInsertShadow, IMAGE_INSERT_SHADOW);
208 InitializeIcon(Icon_HideSlideOverlay, IMAGE_HIDE_SLIDE_OVERLAY);
209
210 InitializeIcon(Icon_ButtonBarLarge, IMAGE_BUTTONBAR_LARGE);
211 InitializeIcon(Icon_ButtonBarMedium, IMAGE_BUTTONBAR_MEDIUM);
212 InitializeIcon(Icon_ButtonBarSmall, IMAGE_BUTTONBAR_SMALL);
213
214 InitializeIcon(Icon_Command1Large, IMAGE_COMMAND1_LARGE);
215 InitializeIcon(Icon_Command1LargeHover, IMAGE_COMMAND1_LARGE_HOVER);
216 InitializeIcon(Icon_Command1Medium, IMAGE_COMMAND1_MEDIUM);
217 InitializeIcon(Icon_Command1MediumHover, IMAGE_COMMAND1_MEDIUM_HOVER);
218 InitializeIcon(Icon_Command1Small, IMAGE_COMMAND1_SMALL);
219 InitializeIcon(Icon_Command1SmallHover, IMAGE_COMMAND1_SMALL_HOVER);
220
221 InitializeIcon(Icon_Command2Large, IMAGE_COMMAND2_LARGE);
222 InitializeIcon(Icon_Command2LargeHover, IMAGE_COMMAND2_LARGE_HOVER);
223 InitializeIcon(Icon_Command2Medium, IMAGE_COMMAND2_MEDIUM);
224 InitializeIcon(Icon_Command2MediumHover, IMAGE_COMMAND2_MEDIUM_HOVER);
225 InitializeIcon(Icon_Command2Small, IMAGE_COMMAND2_SMALL);
226 InitializeIcon(Icon_Command2SmallHover, IMAGE_COMMAND2_SMALL_HOVER);
227
228 InitializeIcon(Icon_Command2BLarge, IMAGE_COMMAND2B_LARGE);
229 InitializeIcon(Icon_Command2BLargeHover, IMAGE_COMMAND2B_LARGE_HOVER);
230 InitializeIcon(Icon_Command2BMedium, IMAGE_COMMAND2B_MEDIUM);
231 InitializeIcon(Icon_Command2BMediumHover, IMAGE_COMMAND2B_MEDIUM_HOVER);
232 InitializeIcon(Icon_Command2BSmall, IMAGE_COMMAND2B_SMALL);
233 InitializeIcon(Icon_Command2BSmallHover, IMAGE_COMMAND2B_SMALL_HOVER);
234
235 InitializeIcon(Icon_Command3Large, IMAGE_COMMAND3_LARGE);
236 InitializeIcon(Icon_Command3LargeHover, IMAGE_COMMAND3_LARGE_HOVER);
237 InitializeIcon(Icon_Command3Medium, IMAGE_COMMAND3_MEDIUM);
238 InitializeIcon(Icon_Command3MediumHover, IMAGE_COMMAND3_MEDIUM_HOVER);
239 InitializeIcon(Icon_Command3Small, IMAGE_COMMAND3_SMALL);
240 InitializeIcon(Icon_Command3SmallHover, IMAGE_COMMAND3_SMALL_HOVER);
241 }
242 InitializeIcon(Icon_FocusBorder, IMAGE_FOCUS_BORDER);
243 }
244 }
245
246
247
248
GetFont(const FontType eType,const OutputDevice & rDevice)249 ::boost::shared_ptr<Font> Theme::GetFont (
250 const FontType eType,
251 const OutputDevice& rDevice)
252 {
253 ::boost::shared_ptr<Font> pFont;
254
255 switch (eType)
256 {
257 case Font_PageNumber:
258 pFont.reset(new Font(Application::GetSettings().GetStyleSettings().GetAppFont()));
259 pFont->SetTransparent(sal_True);
260 pFont->SetWeight(WEIGHT_BOLD);
261 break;
262
263 case Font_PageCount:
264 pFont.reset(new Font(Application::GetSettings().GetStyleSettings().GetAppFont()));
265 pFont->SetTransparent(sal_True);
266 pFont->SetWeight(WEIGHT_NORMAL);
267 {
268 const Size aSize (pFont->GetSize());
269 pFont->SetSize(Size(aSize.Width()*5/3, aSize.Height()*5/3));
270 }
271 break;
272
273 case Font_Button:
274 pFont.reset(new Font(Application::GetSettings().GetStyleSettings().GetAppFont()));
275 pFont->SetTransparent(sal_True);
276 pFont->SetWeight(WEIGHT_BOLD);
277 {
278 const Size aSize (pFont->GetSize());
279 pFont->SetSize(Size(aSize.Width()*4/3, aSize.Height()*4/3));
280 }
281 break;
282 }
283
284 if (pFont)
285 {
286 // Transform the point size to pixel size.
287 const MapMode aFontMapMode (MAP_POINT);
288 const Size aFontSize (rDevice.LogicToPixel(pFont->GetSize(), aFontMapMode));
289
290 // Transform the font size to the logical coordinates of the device.
291 pFont->SetSize(rDevice.PixelToLogic(aFontSize));
292 }
293
294 return pFont;
295 }
296
297
298
299
GetColor(const ColorType eType)300 ColorData Theme::GetColor (const ColorType eType)
301 {
302 if (eType>=0 && sal_uInt32(eType)<maColor.size())
303 return maColor[eType];
304 else
305 return 0;
306 }
307
308
309
310
SetColor(const ColorType eType,const ColorData aData)311 void Theme::SetColor (
312 const ColorType eType,
313 const ColorData aData)
314 {
315 if (eType>=0 && sal_uInt32(eType)<maColor.size())
316 maColor[eType] = aData;
317 }
318
319
320
321
GetGradientColor(const GradientColorType eType,const GradientColorClass eClass)322 ColorData Theme::GetGradientColor (
323 const GradientColorType eType,
324 const GradientColorClass eClass)
325 {
326 GradientDescriptor& rDescriptor (GetGradient(eType));
327
328 switch (eClass)
329 {
330 case Border1: return rDescriptor.maBorderColor1;
331 case Border2: return rDescriptor.maBorderColor2;
332 case Fill1: return rDescriptor.maFillColor1;
333 case Fill2: return rDescriptor.maFillColor2;
334 default: OSL_ASSERT(false); // fall through
335 case Base: return rDescriptor.maBaseColor;
336 }
337 }
338
339
340
341
GetGradientOffset(const GradientColorType eType,const GradientColorClass eClass)342 sal_Int32 Theme::GetGradientOffset (
343 const GradientColorType eType,
344 const GradientColorClass eClass)
345 {
346 GradientDescriptor& rDescriptor (GetGradient(eType));
347
348 switch (eClass)
349 {
350 case Border1: return rDescriptor.mnBorderOffset1;
351 case Border2: return rDescriptor.mnBorderOffset2;
352 case Fill1: return rDescriptor.mnFillOffset1;
353 case Fill2: return rDescriptor.mnFillOffset2;
354 default: OSL_ASSERT(false); // fall through
355 case Base: return 0;
356 }
357 }
358
359
360
361
SetGradient(const GradientColorType eType,const ColorData aBaseColor,const sal_Int32 nSaturationOverride,const sal_Int32 nBrightnessOverride,const sal_Int32 nFillStartOffset,const sal_Int32 nFillEndOffset,const sal_Int32 nBorderStartOffset,const sal_Int32 nBorderEndOffset)362 void Theme::SetGradient (
363 const GradientColorType eType,
364 const ColorData aBaseColor,
365 const sal_Int32 nSaturationOverride,
366 const sal_Int32 nBrightnessOverride,
367 const sal_Int32 nFillStartOffset,
368 const sal_Int32 nFillEndOffset,
369 const sal_Int32 nBorderStartOffset,
370 const sal_Int32 nBorderEndOffset)
371 {
372 GradientDescriptor& rGradient (GetGradient(eType));
373
374 rGradient.maBaseColor = aBaseColor;
375
376 rGradient.mnSaturationOverride = nSaturationOverride;
377 rGradient.mnBrightnessOverride = nBrightnessOverride;
378 const ColorData aColor (nSaturationOverride>=0 || nBrightnessOverride>=0
379 ? HGBAdapt(aBaseColor, nSaturationOverride, nBrightnessOverride)
380 : aBaseColor);
381
382 rGradient.maFillColor1 = ChangeLuminance(aColor, nFillStartOffset);
383 rGradient.maFillColor2 = ChangeLuminance(aColor, nFillEndOffset);
384 rGradient.maBorderColor1 = ChangeLuminance(aColor, nBorderStartOffset);
385 rGradient.maBorderColor2 = ChangeLuminance(aColor, nBorderEndOffset);
386
387 rGradient.mnFillOffset1 = nFillStartOffset;
388 rGradient.mnFillOffset2 = nFillEndOffset;
389 rGradient.mnBorderOffset1 = nBorderStartOffset;
390 rGradient.mnBorderOffset2 = nBorderEndOffset;
391 }
392
393
394
395
GetGradientSaturationOverride(const GradientColorType eType)396 sal_Int32 Theme::GetGradientSaturationOverride (const GradientColorType eType)
397 {
398 GradientDescriptor& rGradient (GetGradient(eType));
399 return rGradient.mnSaturationOverride;
400 }
401
402
403
404
GetGradientBrightnessOverride(const GradientColorType eType)405 sal_Int32 Theme::GetGradientBrightnessOverride (const GradientColorType eType)
406 {
407 GradientDescriptor& rGradient (GetGradient(eType));
408 return rGradient.mnBrightnessOverride;
409 }
410
411
412
413
SetGradientSaturationOverride(const GradientColorType eType,const sal_Int32 nValue)414 void Theme::SetGradientSaturationOverride (const GradientColorType eType, const sal_Int32 nValue)
415 {
416 GradientDescriptor& rGradient (GetGradient(eType));
417 SetGradient(
418 eType,
419 rGradient.maBaseColor,
420 nValue,
421 rGradient.mnBrightnessOverride,
422 rGradient.mnFillOffset1,
423 rGradient.mnFillOffset2,
424 rGradient.mnBorderOffset1,
425 rGradient.mnBorderOffset2);
426 }
427
428
429
430
SetGradientBrightnessOverride(const GradientColorType eType,const sal_Int32 nValue)431 void Theme::SetGradientBrightnessOverride (const GradientColorType eType, const sal_Int32 nValue)
432 {
433 GradientDescriptor& rGradient (GetGradient(eType));
434 SetGradient(eType,
435 rGradient.maBaseColor,
436 rGradient.mnSaturationOverride,
437 nValue,
438 rGradient.mnFillOffset1,
439 rGradient.mnFillOffset2,
440 rGradient.mnBorderOffset1,
441 rGradient.mnBorderOffset2);
442 }
443
444
445
446
GetIcon(const IconType eType)447 const BitmapEx& Theme::GetIcon (const IconType eType)
448 {
449 if (eType>=0 && size_t(eType)<maIcons.size())
450 return maIcons[eType];
451 else
452 {
453 OSL_ASSERT(eType>=0 && size_t(eType)<maIcons.size());
454 return maIcons[0];
455 }
456 }
457
458
459
460
GetIntegerValue(const IntegerValueType eType) const461 sal_Int32 Theme::GetIntegerValue (const IntegerValueType eType) const
462 {
463 if (eType>=0 && size_t(eType)<maIntegerValues.size())
464 return maIntegerValues[eType];
465 else
466 {
467 OSL_ASSERT(eType>=0 && size_t(eType)<maIntegerValues.size());
468 return 0;
469 }
470 }
471
472
473
474
SetIntegerValue(const IntegerValueType eType,const sal_Int32 nValue)475 void Theme::SetIntegerValue (const IntegerValueType eType, const sal_Int32 nValue)
476 {
477 if (eType>=0 && size_t(eType)<maIntegerValues.size())
478 maIntegerValues[eType] = nValue;
479 else
480 {
481 OSL_ASSERT(eType>=0 && size_t(eType)<maIntegerValues.size());
482 }
483 }
484
485
486
487
GetString(const StringType eType) const488 ::rtl::OUString Theme::GetString (const StringType eType) const
489 {
490 if (eType>=0 && size_t(eType)<maStrings.size())
491 return maStrings[eType];
492 else
493 {
494 OSL_ASSERT(eType>=0 && size_t(eType)<maStrings.size());
495 return ::rtl::OUString();
496 }
497 }
498
499
500
501
GetGradient(const GradientColorType eType)502 Theme::GradientDescriptor& Theme::GetGradient (const GradientColorType eType)
503 {
504 if (eType>=0 && size_t(eType)<maGradients.size())
505 return maGradients[eType];
506 else
507 {
508 OSL_ASSERT(eType>=0 && size_t(eType)<maGradients.size());
509 return maGradients[0];
510 }
511 }
512
513
514
515
InitializeIcon(const IconType eType,sal_uInt16 nResourceId)516 void Theme::InitializeIcon (const IconType eType, sal_uInt16 nResourceId)
517 {
518 if (eType>=0 && size_t(eType)<maIcons.size())
519 {
520 const BitmapEx aIcon (Image(SdResId(nResourceId)).GetBitmapEx());
521 maIcons[eType] = aIcon;
522 }
523 else
524 {
525 OSL_ASSERT(eType>=0 && size_t(eType)<maIcons.size());
526 }
527 }
528
529
530
531
532 } } } // end of namespace ::sd::slidesorter::view
533