2 * Copyright (C) 2007 Apple Inc.
3 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
4 * Copyright (C) 2008 Collabora Ltd.
5 * Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia
6 * Copyright (C) 2009-2010 ProFUSION embedded systems
7 * Copyright (C) 2009-2011 Samsung Electronics
8 * Copyright (c) 2012 Intel Corporation. All rights reserved.
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details.
20 * You should have received a copy of the GNU Library General Public License
21 * along with this library; see the file COPYING.LIB. If not, write to
22 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
28 #include "RenderThemeEfl.h"
30 #include "CSSValueKeywords.h"
31 #include "CairoUtilitiesEfl.h"
32 #include "GraphicsContext.h"
33 #include "HTMLInputElement.h"
34 #include "NotImplemented.h"
36 #include "PaintInfo.h"
37 #include "PlatformContextCairo.h"
38 #include "RenderBox.h"
39 #include "RenderObject.h"
40 #include "RenderProgress.h"
41 #include "RenderSlider.h"
42 #include "UserAgentStyleSheets.h"
44 #include <Ecore_Evas.h>
46 #include <wtf/text/CString.h>
47 #include <wtf/text/WTFString.h>
50 #include "HTMLMediaElement.h"
51 #include "HTMLNames.h"
52 #include "TimeRanges.h"
57 using namespace HTMLNames;
60 // TODO: change from object count to ecore_evas size (bytes)
61 // TODO: as objects are webpage/user defined and they can be very large.
62 #define RENDER_THEME_EFL_PART_CACHE_MAX 32
64 #if ENABLE(TIZEN_THEME_STYLE_WORKAROUND)
65 //EFL theme should set control font sizes, in case the font size goes beyond certain value.
66 #define RENDER_THEME_EFL_CONTROL_FONT_SIZE 12
69 // Initialize default font size.
70 #if ENABLE(TIZEN_SYSTEM_FONT)
71 float RenderThemeEfl::defaultFontSize = 13.0f;
73 float RenderThemeEfl::defaultFontSize = 16.0f;
76 static const float minCancelButtonSize = 5;
77 static const float maxCancelButtonSize = 21;
79 // Constants for progress tag animation.
80 // These values have been copied from RenderThemeGtk.cpp
81 static const int progressAnimationFrames = 10;
82 static const double progressAnimationInterval = 0.125;
84 static const int sliderThumbWidth = 29;
85 static const int sliderThumbHeight = 11;
88 #if ENABLE(TIZEN_GSTREAMER_VIDEO)
89 static const int mediaSliderThumbWidth = 14;
90 static const int mediaSliderThumbHeight = 14;
91 static const int mediaSliderFullScreenThumbWidth = 30;
92 static const int mediaSliderFullScreenThumbHeight = 30;
93 static const int mediaSliderHeight = 4;
95 static const int mediaSliderThumbWidth = 12;
96 static const int mediaSliderThumbHeight = 12;
97 static const int mediaSliderHeight = 14;
101 void RenderThemeEfl::adjustSizeConstraints(RenderStyle* style, FormType type) const
103 const struct ThemePartDesc* desc = m_partDescs + (size_t)type;
105 if (style->minWidth().isIntrinsic())
106 style->setMinWidth(desc->min.width());
107 if (style->minHeight().isIntrinsic())
108 style->setMinHeight(desc->min.height());
110 if (desc->max.width().value() > 0 && style->maxWidth().isIntrinsicOrAuto())
111 style->setMaxWidth(desc->max.width());
112 if (desc->max.height().value() > 0 && style->maxHeight().isIntrinsicOrAuto())
113 style->setMaxHeight(desc->max.height());
115 style->setPaddingTop(desc->padding.top());
116 style->setPaddingBottom(desc->padding.bottom());
117 style->setPaddingLeft(desc->padding.left());
118 style->setPaddingRight(desc->padding.right());
121 bool RenderThemeEfl::themePartCacheEntryReset(struct ThemePartCacheEntry* entry, FormType type)
123 const char *file, *group;
128 edje_object_file_get(m_edje, &file, 0);
129 group = edjeGroupFromFormType(type);
133 if (!edje_object_file_set(entry->o, file, group)) {
134 Edje_Load_Error err = edje_object_load_error_get(entry->o);
135 const char *errmsg = edje_load_error_str(err);
136 EINA_LOG_ERR("Could not load '%s' from theme %s: %s",
137 group, file, errmsg);
143 bool RenderThemeEfl::themePartCacheEntrySurfaceCreate(struct ThemePartCacheEntry* entry)
146 cairo_status_t status;
151 ecore_evas_geometry_get(entry->ee, 0, 0, &w, &h);
155 entry->surface = cairo_image_surface_create_for_data((unsigned char *)ecore_evas_buffer_pixels_get(entry->ee),
156 CAIRO_FORMAT_ARGB32, w, h, w * 4);
157 status = cairo_surface_status(entry->surface);
158 if (status != CAIRO_STATUS_SUCCESS) {
159 EINA_LOG_ERR("Could not create cairo surface: %s",
160 cairo_status_to_string(status));
167 bool RenderThemeEfl::isFormElementTooLargeToDisplay(const IntSize& elementSize)
169 // This limit of 20000 pixels is hardcoded inside edje -- anything above this size
170 // will be clipped. This value seems to be reasonable enough so that hardcoding it
171 // here won't be a problem.
172 static const int maxEdjeDimension = 20000;
174 return elementSize.width() > maxEdjeDimension || elementSize.height() > maxEdjeDimension;
177 // allocate a new entry and fill it with edje group
178 struct RenderThemeEfl::ThemePartCacheEntry* RenderThemeEfl::cacheThemePartNew(FormType type, const IntSize& size)
180 if (isFormElementTooLargeToDisplay(size)) {
181 EINA_LOG_ERR("cannot render an element of size %dx%d", size.width(), size.height());
185 ThemePartCacheEntry* entry = new ThemePartCacheEntry;
187 EINA_LOG_ERR("could not allocate ThemePartCacheEntry.");
191 entry->ee = ecore_evas_buffer_new(size.width(), size.height());
193 EINA_LOG_ERR("ecore_evas_buffer_new(%d, %d) failed.",
194 size.width(), size.height());
199 // By default EFL creates buffers without alpha.
200 ecore_evas_alpha_set(entry->ee, EINA_TRUE);
202 entry->o = edje_object_add(ecore_evas_get(entry->ee));
204 if (!themePartCacheEntryReset(entry, type)) {
205 evas_object_del(entry->o);
206 ecore_evas_free(entry->ee);
211 if (!themePartCacheEntrySurfaceCreate(entry)) {
212 evas_object_del(entry->o);
213 ecore_evas_free(entry->ee);
218 evas_object_resize(entry->o, size.width(), size.height());
219 evas_object_show(entry->o);
224 m_partCache.prepend(entry);
228 // just change the edje group and return the same entry
229 struct RenderThemeEfl::ThemePartCacheEntry* RenderThemeEfl::cacheThemePartReset(FormType type, struct RenderThemeEfl::ThemePartCacheEntry* entry)
231 if (!themePartCacheEntryReset(entry, type)) {
232 entry->type = FormTypeLast; // invalidate
233 m_partCache.append(entry);
237 m_partCache.prepend(entry);
241 // resize entry and reset it
242 struct RenderThemeEfl::ThemePartCacheEntry* RenderThemeEfl::cacheThemePartResizeAndReset(FormType type, const IntSize& size, struct RenderThemeEfl::ThemePartCacheEntry* entry)
244 cairo_surface_finish(entry->surface);
247 ecore_evas_resize(entry->ee, size.width(), size.height());
248 evas_object_resize(entry->o, size.width(), size.height());
250 if (!themePartCacheEntrySurfaceCreate(entry)) {
251 evas_object_del(entry->o);
252 ecore_evas_free(entry->ee);
257 return cacheThemePartReset(type, entry);
260 // general purpose get (will create, reuse and all)
261 struct RenderThemeEfl::ThemePartCacheEntry* RenderThemeEfl::cacheThemePartGet(FormType type, const IntSize& size)
263 Vector<struct ThemePartCacheEntry *>::iterator itr, end;
264 struct ThemePartCacheEntry *ce_last_size = 0;
265 int i, idxLastSize = -1;
267 itr = m_partCache.begin();
268 end = m_partCache.end();
269 for (i = 0; itr != end; i++, itr++) {
270 struct ThemePartCacheEntry *entry = *itr;
271 if (entry->size == size) {
272 if (entry->type == type)
274 ce_last_size = entry;
279 if (m_partCache.size() < RENDER_THEME_EFL_PART_CACHE_MAX)
280 return cacheThemePartNew(type, size);
282 if (ce_last_size && ce_last_size != m_partCache.first()) {
283 m_partCache.remove(idxLastSize);
284 return cacheThemePartReset(type, ce_last_size);
287 ThemePartCacheEntry* entry = m_partCache.last();
288 m_partCache.removeLast();
289 return cacheThemePartResizeAndReset(type, size, entry);
292 void RenderThemeEfl::cacheThemePartFlush()
294 Vector<struct ThemePartCacheEntry *>::iterator itr, end;
296 itr = m_partCache.begin();
297 end = m_partCache.end();
298 for (; itr != end; itr++) {
299 struct ThemePartCacheEntry *entry = *itr;
300 cairo_surface_destroy(entry->surface);
301 evas_object_del(entry->o);
302 ecore_evas_free(entry->ee);
308 void RenderThemeEfl::applyEdjeStateFromForm(Evas_Object* object, ControlStates states)
310 const char *signals[] = { // keep in sync with WebCore/platform/ThemeTypes.h
323 edje_object_signal_emit(object, "reset", "");
325 for (size_t i = 0; i < WTF_ARRAY_LENGTH(signals); ++i) {
326 if (states & (1 << i))
327 edje_object_signal_emit(object, signals[i], "");
331 bool RenderThemeEfl::paintThemePart(RenderObject* object, FormType type, const PaintInfo& info, const IntRect& rect)
333 ThemePartCacheEntry* entry;
340 #if ENABLE(TIZEN_THEME_SCALE_SUPPORT)
341 float themeScaleValue = m_partDescs[type].scale;
342 IntSize scaledEntrySize(rect.size());
343 scaledEntrySize.scale(themeScaleValue);
344 entry = cacheThemePartGet(type, scaledEntrySize);
346 entry = cacheThemePartGet(type, rect.size());
351 applyEdjeStateFromForm(entry->o, controlStatesForRenderer(object));
352 if (object && object->hasBackground() && object->style()->visitedDependentColor(CSSPropertyBackgroundColor) != Color::white)
353 edje_object_signal_emit(entry->o, "bg_styled", "");
354 cairo = info.context->platformContext()->cr();
357 // Currently, only sliders needs this message; if other widget ever needs special
358 // treatment, move them to special functions.
359 if (type == SliderVertical || type == SliderHorizontal) {
360 RenderSlider* renderSlider = toRenderSlider(object);
361 HTMLInputElement* input = renderSlider->node()->toInputElement();
364 double valueRange = input->maximum() - input->minimum();
366 OwnArrayPtr<char> buffer = adoptArrayPtr(new char[sizeof(Edje_Message_Float_Set) + sizeof(double)]);
367 Edje_Message_Float_Set* msg = new(buffer.get()) Edje_Message_Float_Set;
370 // The first parameter of the message decides if the progress bar
371 // grows from the end of the slider or from the beginning. On vertical
372 // sliders, it should always be the same and will not be affected by
373 // text direction settings.
374 if (object->style()->direction() == RTL || type == SliderVertical)
379 msg->val[1] = (input->valueAsNumber() - input->minimum()) / valueRange;
380 edje_object_message_send(entry->o, EDJE_MESSAGE_FLOAT_SET, 0, msg);
381 #if ENABLE(PROGRESS_ELEMENT)
382 } else if (type == ProgressBar) {
383 RenderProgress* renderProgress = toRenderProgress(object);
388 value = renderProgress->position();
390 OwnArrayPtr<char> buffer = adoptArrayPtr(new char[sizeof(Edje_Message_Float_Set) + sizeof(double)]);
391 Edje_Message_Float_Set* msg = new(buffer.get()) Edje_Message_Float_Set;
393 if (object->style()->direction() == RTL)
394 msg->val[0] = (1.0 - value) * max;
398 edje_object_message_send(entry->o, EDJE_MESSAGE_FLOAT_SET, 0, msg);
402 edje_object_calc_force(entry->o);
403 edje_object_message_signal_process(entry->o);
404 updates = evas_render_updates(ecore_evas_get(entry->ee));
405 evas_render_updates_free(updates);
409 #if ENABLE(TIZEN_THEME_SCALE_SUPPORT)
410 cairo_matrix_t matrix;
411 cairo_get_matrix(cairo, &matrix);
412 matrix.xx = matrix.xx / themeScaleValue;
413 matrix.yy = matrix.yy / themeScaleValue;
414 cairo_set_matrix(cairo, &matrix);
416 cairo_set_source_surface(cairo, entry->surface, rect.x() * themeScaleValue, rect.y() * themeScaleValue);
418 cairo_set_source_surface(cairo, entry->surface, rect.x(), rect.y());
420 cairo_paint_with_alpha(cairo, 1.0);
421 cairo_restore(cairo);
426 PassRefPtr<RenderTheme> RenderThemeEfl::create(Page* page)
428 return adoptRef(new RenderThemeEfl(page));
431 PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page)
434 return RenderThemeEfl::create(page);
436 static RenderTheme* fallback = RenderThemeEfl::create(0).leakRef();
440 static void renderThemeEflColorClassSelectionForeground(void* data, Evas_Object* object, const char* signal, const char* source)
442 RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data);
443 int fr, fg, fb, fa, br, bg, bb, ba;
445 if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0))
448 that->setSelectionForegroundColor(fr, fg, fb, fa, br, bg, bb, ba);
451 static void renderThemeEflColorClassSelectionBackground(void* data, Evas_Object* object, const char* signal, const char* source)
453 RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data);
454 int fr, fg, fb, fa, br, bg, bb, ba;
456 if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0))
459 that->setSelectionBackgroundColor(fr, fg, fb, fa, br, bg, bb, ba);
462 static void renderThemeEflColorClassFocusRing(void* data, Evas_Object* object, const char* signal, const char* source)
464 RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data);
467 if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, 0, 0, 0, 0, 0, 0, 0, 0))
470 that->setFocusRingColor(fr, fg, fb, fa);
473 void RenderThemeEfl::setThemePath(const String& path)
475 if (path == m_themePath)
482 void RenderThemeEfl::createCanvas()
485 m_canvas = ecore_evas_buffer_new(1, 1);
489 void RenderThemeEfl::createEdje()
492 if (m_themePath.isEmpty())
493 EINA_LOG_ERR("No theme defined, unable to set RenderThemeEfl.");
495 m_edje = edje_object_add(ecore_evas_get(m_canvas));
497 EINA_LOG_ERR("Could not create base edje object.");
498 else if (!edje_object_file_set(m_edje, m_themePath.utf8().data(), "webkit/base")) {
499 Edje_Load_Error err = edje_object_load_error_get(m_edje);
500 const char* errmsg = edje_load_error_str(err);
501 EINA_LOG_ERR("Could not load 'webkit/base' from theme %s: %s",
502 m_themePath.utf8().data(), errmsg);
503 evas_object_del(m_edje);
506 #define CONNECT(cc, func) \
507 edje_object_signal_callback_add(m_edje, "color_class,set", \
508 "webkit/"cc, func, this)
510 CONNECT("selection/foreground",
511 renderThemeEflColorClassSelectionForeground);
512 CONNECT("selection/background",
513 renderThemeEflColorClassSelectionBackground);
514 CONNECT("focus_ring", renderThemeEflColorClassFocusRing);
520 void RenderThemeEfl::applyEdjeColors()
522 int fr, fg, fb, fa, br, bg, bb, ba;
524 #define COLOR_GET(cls) \
525 edje_object_color_class_get(m_edje, "webkit/"cls, \
526 &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, \
529 if (COLOR_GET("selection/foreground")) {
530 m_supportsSelectionForegroundColors = true;
531 m_activeSelectionForegroundColor = Color(fr, fg, fb, fa);
532 m_inactiveSelectionForegroundColor = Color(br, bg, bb, ba);
534 if (COLOR_GET("selection/background")) {
535 m_inactiveSelectionBackgroundColor = Color(fr, fg, fb, fa);
536 m_activeSelectionBackgroundColor = Color(br, bg, bb, ba);
538 if (COLOR_GET("focus_ring")) {
539 m_focusRingColor = Color(fr, fg, fb, fa);
540 // webkit just use platformFocusRingColor() for default theme (without page)
541 // this is ugly, but no other way to do it unless we change
542 // it to use page themes as much as possible.
543 RenderTheme::setCustomFocusRingColor(m_focusRingColor);
546 platformColorsDidChange();
549 void RenderThemeEfl::applyPartDescriptionFallback(struct ThemePartDesc* desc)
551 desc->min.setWidth(Length(0, Fixed));
552 desc->min.setHeight(Length(0, Fixed));
554 desc->max.setWidth(Length(0, Fixed));
555 desc->max.setHeight(Length(0, Fixed));
557 desc->padding = LengthBox(0, 0, 0, 0);
560 void RenderThemeEfl::applyPartDescription(Evas_Object* object, struct ThemePartDesc* desc)
562 Evas_Coord minw, minh, maxw, maxh;
564 #if ENABLE(TIZEN_THEME_SCALE_SUPPORT)
565 const char* scale = edje_object_data_get(object, "scale");
568 desc->scale = atof(scale);
573 edje_object_size_min_get(object, &minw, &minh);
575 edje_object_size_min_calc(object, &minw, &minh);
577 #if ENABLE(TIZEN_THEME_SCALE_SUPPORT)
581 desc->min.setWidth(Length(minw, Fixed));
582 desc->min.setHeight(Length(minh, Fixed));
584 #if ENABLE(TIZEN_THEME_SCALE_SUPPORT)
588 edje_object_size_max_get(object, &maxw, &maxh);
589 desc->max.setWidth(Length(maxw, Fixed));
590 desc->max.setHeight(Length(maxh, Fixed));
592 if (!edje_object_part_exists(object, "text_confinement"))
593 desc->padding = LengthBox(0, 0, 0, 0);
595 Evas_Coord px, py, pw, ph;
596 Evas_Coord ox = 0, oy = 0, ow = 0, oh = 0;
607 if (maxw > 0 && ow > maxw)
609 if (maxh > 0 && oh > maxh)
612 evas_object_move(object, ox, oy);
613 evas_object_resize(object, ow, oh);
614 edje_object_calc_force(object);
615 edje_object_message_signal_process(object);
616 edje_object_part_geometry_get(object, "text_confinement", &px, &py, &pw, &ph);
619 b = (oh + oy) - (ph + py);
622 r = (ow + ox) - (pw + px);
624 desc->padding = LengthBox(t, r, b, l);
628 const char* RenderThemeEfl::edjeGroupFromFormType(FormType type) const
630 static const char* groups[] = {
631 #define W(n) "webkit/widget/"n
637 #if ENABLE(PROGRESS_ELEMENT)
641 W("search/decoration"),
642 W("search/results_button"),
643 W("search/results_decoration"),
644 W("search/cancel_button"),
645 W("slider/vertical"),
646 W("slider/horizontal"),
647 W("slider/thumb_vertical"),
648 W("slider/thumb_horizontal"),
650 W("mediacontrol/playpause_button"),
651 W("mediacontrol/mute_button"),
652 W("mediacontrol/seekforward_button"),
653 W("mediacontrol/seekbackward_button"),
654 W("mediacontrol/fullscreen_button"),
655 #if ENABLE(TIZEN_GSTREAMER_VIDEO)
656 W("mediacontrol/slider_thumb"),
664 ASSERT((size_t)type < sizeof(groups) / sizeof(groups[0])); // out of sync?
668 void RenderThemeEfl::applyPartDescriptions()
677 edje_object_file_get(m_edje, &file, 0);
680 object = edje_object_add(ecore_evas_get(m_canvas));
682 EINA_LOG_ERR("Could not create Edje object.");
686 for (i = 0; i < FormTypeLast; i++) {
687 FormType type = static_cast<FormType>(i);
688 const char* group = edjeGroupFromFormType(type);
689 m_partDescs[i].type = type;
690 if (!edje_object_file_set(object, file, group)) {
691 Edje_Load_Error err = edje_object_load_error_get(object);
692 const char* errmsg = edje_load_error_str(err);
693 EINA_LOG_ERR("Could not set theme group '%s' of file '%s': %s",
694 group, file, errmsg);
696 applyPartDescriptionFallback(m_partDescs + i);
698 applyPartDescription(object, m_partDescs + i);
700 evas_object_del(object);
703 void RenderThemeEfl::themeChanged()
705 cacheThemePartFlush();
720 applyPartDescriptions();
723 RenderThemeEfl::RenderThemeEfl(Page* page)
726 , m_activeSelectionBackgroundColor(0, 0, 255)
727 , m_activeSelectionForegroundColor(Color::white)
728 , m_inactiveSelectionBackgroundColor(0, 0, 128)
729 , m_inactiveSelectionForegroundColor(200, 200, 200)
730 , m_focusRingColor(32, 32, 224, 224)
731 #if ENABLE(TIZEN_GSTREAMER_VIDEO)
732 , m_sliderThumbColor(0xee, 0xee, 0xee)
734 , m_sliderThumbColor(Color::darkGray)
737 #if ENABLE(TIZEN_GSTREAMER_VIDEO)
738 , m_mediaPanelColor(0, 0, 0, 0)
739 , m_mediaSliderColor(0xDC, 0xDC, 0xDC, 0x80)
740 , m_mediaBufferingColor(0x96, 0x96, 0x96)
741 , m_mediaPlayingColor(0x36, 0x8A, 0xFF)
743 , m_mediaPanelColor(220, 220, 195) // light tannish color.
744 , m_mediaSliderColor(Color::white)
749 , m_supportsSelectionForegroundColors(false)
753 RenderThemeEfl::~RenderThemeEfl()
755 cacheThemePartFlush();
759 evas_object_del(m_edje);
760 ecore_evas_free(m_canvas);
764 void RenderThemeEfl::setSelectionForegroundColor(int foreR, int foreG, int foreB, int foreA, int backR, int backG, int backB, int backA)
766 m_activeSelectionForegroundColor = Color(foreR, foreG, foreB, foreA);
767 m_inactiveSelectionForegroundColor = Color(backR, backG, backB, backA);
768 m_supportsSelectionForegroundColors = true;
769 platformColorsDidChange();
772 void RenderThemeEfl::setSelectionBackgroundColor(int foreR, int foreG, int foreB, int foreA, int backR, int backG, int backB, int backA)
774 m_activeSelectionBackgroundColor = Color(foreR, foreG, foreB, foreA);
775 m_inactiveSelectionBackgroundColor = Color(backR, backG, backB, backA);
776 platformColorsDidChange();
779 void RenderThemeEfl::setFocusRingColor(int r, int g, int b, int a)
781 m_focusRingColor = Color(r, g, b, a);
782 // webkit just use platformFocusRingColor() for default theme (without page)
783 // this is ugly, but no other way to do it unless we change
784 // it to use page themes as much as possible.
785 RenderTheme::setCustomFocusRingColor(m_focusRingColor);
786 platformColorsDidChange();
789 static bool supportsFocus(ControlPart appearance)
791 switch (appearance) {
796 case SearchFieldPart:
800 case SliderVerticalPart:
801 case SliderHorizontalPart:
808 bool RenderThemeEfl::supportsFocusRing(const RenderStyle* style) const
810 return supportsFocus(style->appearance());
813 bool RenderThemeEfl::controlSupportsTints(const RenderObject* object) const
815 return isEnabled(object);
818 LayoutUnit RenderThemeEfl::baselinePosition(const RenderObject* object) const
820 if (!object->isBox())
823 if (object->style()->appearance() == CheckboxPart
824 || object->style()->appearance() == RadioPart)
825 return toRenderBox(object)->marginTop() + toRenderBox(object)->height() - 3;
827 return RenderTheme::baselinePosition(object);
830 bool RenderThemeEfl::paintSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect)
832 if (object->style()->appearance() == SliderHorizontalPart)
833 return paintThemePart(object, SliderHorizontal, info, rect);
834 return paintThemePart(object, SliderVertical, info, rect);
837 void RenderThemeEfl::adjustSliderTrackStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
839 style->setBoxShadow(nullptr);
842 void RenderThemeEfl::adjustSliderThumbStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
844 RenderTheme::adjustSliderThumbStyle(styleResolver, style, element);
845 style->setBoxShadow(nullptr);
848 #if ENABLE(TIZEN_GSTREAMER_VIDEO)
849 void RenderThemeEfl::adjustSliderThumbSize(RenderStyle* style, Element* element) const
851 void RenderThemeEfl::adjustSliderThumbSize(RenderStyle* style, Element*) const
854 ControlPart part = style->appearance();
855 if (part == SliderThumbVerticalPart) {
856 style->setWidth(Length(sliderThumbHeight, Fixed));
857 style->setHeight(Length(sliderThumbWidth, Fixed));
858 } else if (part == SliderThumbHorizontalPart) {
859 style->setWidth(Length(sliderThumbWidth, Fixed));
860 style->setHeight(Length(sliderThumbHeight, Fixed));
862 } else if (part == MediaSliderThumbPart) {
863 #if ENABLE(TIZEN_GSTREAMER_VIDEO)
864 if(element && (element->document()->webkitIsFullScreen() ||element->document()->isMediaDocument())){
865 style->setWidth(Length(mediaSliderFullScreenThumbWidth, Fixed));
866 style->setHeight(Length(mediaSliderFullScreenThumbWidth, Fixed));
870 style->setWidth(Length(mediaSliderThumbWidth, Fixed));
871 style->setHeight(Length(mediaSliderThumbHeight, Fixed));
876 #if ENABLE(DATALIST_ELEMENT)
877 IntSize RenderThemeEfl::sliderTickSize() const
879 // FIXME: We need to set this to the size of one tick mark.
880 return IntSize(0, 0);
883 int RenderThemeEfl::sliderTickOffsetFromTrackCenter() const
885 // FIXME: We need to set this to the position of the tick marks.
890 bool RenderThemeEfl::paintSliderThumb(RenderObject* object, const PaintInfo& info, const IntRect& rect)
892 if (object->style()->appearance() == SliderThumbHorizontalPart)
893 paintThemePart(object, SliderThumbHorizontal, info, rect);
895 paintThemePart(object, SliderThumbVertical, info, rect);
900 void RenderThemeEfl::adjustCheckboxStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
902 if (!m_page && element && element->document()->page()) {
903 static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustCheckboxStyle(styleResolver, style, element);
906 adjustSizeConstraints(style, CheckBox);
907 style->resetBorder();
909 const struct ThemePartDesc *desc = m_partDescs + (size_t)CheckBox;
910 if (style->width().value() < desc->min.width().value())
911 style->setWidth(desc->min.width());
912 if (style->height().value() < desc->min.height().value())
913 style->setHeight(desc->min.height());
916 bool RenderThemeEfl::paintCheckbox(RenderObject* object, const PaintInfo& info, const IntRect& rect)
918 return paintThemePart(object, CheckBox, info, rect);
921 void RenderThemeEfl::adjustRadioStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
923 if (!m_page && element && element->document()->page()) {
924 static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustRadioStyle(styleResolver, style, element);
927 adjustSizeConstraints(style, RadioButton);
928 style->resetBorder();
930 const struct ThemePartDesc *desc = m_partDescs + (size_t)RadioButton;
931 if (style->width().value() < desc->min.width().value())
932 style->setWidth(desc->min.width());
933 if (style->height().value() < desc->min.height().value())
934 style->setHeight(desc->min.height());
937 bool RenderThemeEfl::paintRadio(RenderObject* object, const PaintInfo& info, const IntRect& rect)
939 return paintThemePart(object, RadioButton, info, rect);
942 void RenderThemeEfl::adjustButtonStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
944 if (!m_page && element && element->document()->page()) {
945 static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustButtonStyle(styleResolver, style, element);
949 // adjustSizeConstrains can make SquareButtonPart's size wrong (by adjusting paddings), so call it only for PushButtonPart and ButtonPart
950 if (style->appearance() == PushButtonPart || style->appearance() == ButtonPart)
951 adjustSizeConstraints(style, Button);
954 bool RenderThemeEfl::paintButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
956 return paintThemePart(object, Button, info, rect);
959 void RenderThemeEfl::adjustMenuListStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
961 if (!m_page && element && element->document()->page()) {
962 static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustMenuListStyle(styleResolver, style, element);
965 #if ENABLE(TIZEN_THEME_STYLE_WORKAROUND)
966 /*If the computed height becomes greater than 12px, applying top padding causes the clipping of the text
967 This is just a workaround patch,this needs to be fixed with customized padding for different scenarios
968 like other ports win/safari do,as part of EFL Rendertheme refactoring. */
970 if(style->fontMetrics().height() >= RENDER_THEME_EFL_CONTROL_FONT_SIZE || style->appearance() == MenulistPart)
972 const struct ThemePartDesc* desc = m_partDescs + (size_t)ComboBox;
973 style->setPaddingTop(Length(0,Fixed));
974 style->setPaddingLeft(style->paddingLeft());
975 //We need some amount of Right padding so that combo box arrow doesnt overlap the text
976 //if content doesnt set any right padding set EFL theme padding.
977 //Calculate the minimum right padding to avoid arrow overlapping with text.
978 int stylePaddingRight = style->paddingRight().intValue();
979 int themePaddingRight = desc->padding.right().intValue();
980 if(stylePaddingRight > themePaddingRight)
981 style->setPaddingRight(style->paddingRight());
983 style->setPaddingRight(desc->padding.right());
984 style->setPaddingBottom(Length(1,Fixed));
988 adjustSizeConstraints(style, ComboBox);
989 style->resetBorder();
990 style->setWhiteSpace(PRE);
993 bool RenderThemeEfl::paintMenuList(RenderObject* object, const PaintInfo& info, const IntRect& rect)
995 return paintThemePart(object, ComboBox, info, rect);
998 void RenderThemeEfl::adjustMenuListButtonStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
1000 adjustMenuListStyle(styleResolver, style, element);
1003 bool RenderThemeEfl::paintMenuListButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1005 return paintMenuList(object, info, rect);
1008 void RenderThemeEfl::adjustTextFieldStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
1010 #if !ENABLE(TIZEN_THEME_STYLE_WORKAROUND)
1011 if (!m_page && element && element->document()->page()) {
1012 static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustTextFieldStyle(styleResolver, style, element);
1015 adjustSizeConstraints(style, TextField);
1016 style->resetBorder();
1020 bool RenderThemeEfl::paintTextField(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1022 return paintThemePart(object, TextField, info, rect);
1025 void RenderThemeEfl::adjustTextAreaStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
1027 adjustTextFieldStyle(styleResolver, style, element);
1030 bool RenderThemeEfl::paintTextArea(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1032 return paintTextField(object, info, rect);
1035 void RenderThemeEfl::adjustSearchFieldDecorationStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
1037 if (!m_page && element && element->document()->page()) {
1038 static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustSearchFieldDecorationStyle(styleResolver, style, element);
1041 adjustSizeConstraints(style, SearchFieldDecoration);
1042 style->resetBorder();
1043 style->setWhiteSpace(PRE);
1046 bool RenderThemeEfl::paintSearchFieldDecoration(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1048 return paintThemePart(object, SearchFieldDecoration, info, rect);
1051 void RenderThemeEfl::adjustSearchFieldResultsButtonStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
1053 if (!m_page && element && element->document()->page()) {
1054 static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustSearchFieldResultsButtonStyle(styleResolver, style, element);
1057 adjustSizeConstraints(style, SearchFieldResultsButton);
1058 style->resetBorder();
1059 style->setWhiteSpace(PRE);
1062 bool RenderThemeEfl::paintSearchFieldResultsButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1064 return paintThemePart(object, SearchFieldResultsButton, info, rect);
1067 void RenderThemeEfl::adjustSearchFieldResultsDecorationStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
1069 if (!m_page && element && element->document()->page()) {
1070 static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustSearchFieldResultsDecorationStyle(styleResolver, style, element);
1073 adjustSizeConstraints(style, SearchFieldResultsDecoration);
1074 style->resetBorder();
1075 style->setWhiteSpace(PRE);
1078 bool RenderThemeEfl::paintSearchFieldResultsDecoration(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1080 return paintThemePart(object, SearchFieldResultsDecoration, info, rect);
1083 void RenderThemeEfl::adjustSearchFieldCancelButtonStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
1085 if (!m_page && element && element->document()->page()) {
1086 static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustSearchFieldCancelButtonStyle(styleResolver, style, element);
1089 adjustSizeConstraints(style, SearchFieldCancelButton);
1090 style->resetBorder();
1091 style->setWhiteSpace(PRE);
1093 // Logic taken from RenderThemeChromium.cpp.
1094 // Scale the button size based on the font size.
1095 float fontScale = style->fontSize() / defaultFontSize;
1096 int cancelButtonSize = lroundf(std::min(std::max(minCancelButtonSize, defaultFontSize * fontScale), maxCancelButtonSize));
1098 style->setWidth(Length(cancelButtonSize, Fixed));
1099 style->setHeight(Length(cancelButtonSize, Fixed));
1102 bool RenderThemeEfl::paintSearchFieldCancelButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1104 return paintThemePart(object, SearchFieldCancelButton, info, rect);
1107 void RenderThemeEfl::adjustSearchFieldStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
1109 if (!m_page && element && element->document()->page()) {
1110 static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustSearchFieldStyle(styleResolver, style, element);
1113 adjustSizeConstraints(style, SearchField);
1114 style->resetBorder();
1115 style->setWhiteSpace(PRE);
1118 bool RenderThemeEfl::paintSearchField(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1120 return paintThemePart(object, SearchField, info, rect);
1122 #if !ENABLE(TIZEN_INPUTTYPE_NUMBER)
1123 void RenderThemeEfl::adjustInnerSpinButtonStyle(StyleResolver* styleResolver, RenderStyle* style, Element* element) const
1125 if (!m_page && element && element->document()->page()) {
1126 static_cast<RenderThemeEfl*>(element->document()->page()->theme())->adjustInnerSpinButtonStyle(styleResolver, style, element);
1129 adjustSizeConstraints(style, Spinner);
1132 bool RenderThemeEfl::paintInnerSpinButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1134 return paintThemePart(object, Spinner, info, rect);
1137 void RenderThemeEfl::setDefaultFontSize(int size)
1139 defaultFontSize = size;
1142 void RenderThemeEfl::systemFont(int propId, FontDescription& fontDescription) const
1144 // It was called by RenderEmbeddedObject::paintReplaced to render alternative string.
1145 // To avoid cairo_error while rendering, fontDescription should be passed.
1146 #if ENABLE(TIZEN_SYSTEM_FONT)
1147 DEFINE_STATIC_LOCAL(String, fontFace, ("Arial"));
1149 DEFINE_STATIC_LOCAL(String, fontFace, ("Sans"));
1151 float fontSize = defaultFontSize;
1153 fontDescription.firstFamily().setFamily(fontFace);
1154 fontDescription.setSpecifiedSize(fontSize);
1155 fontDescription.setIsAbsoluteSize(true);
1156 fontDescription.setGenericFamily(FontDescription::NoFamily);
1157 fontDescription.setWeight(FontWeightNormal);
1158 fontDescription.setItalic(false);
1161 #if ENABLE(PROGRESS_ELEMENT)
1162 void RenderThemeEfl::adjustProgressBarStyle(StyleResolver*, RenderStyle* style, Element*) const
1164 style->setBoxShadow(nullptr);
1167 double RenderThemeEfl::animationRepeatIntervalForProgressBar(RenderProgress*) const
1169 return progressAnimationInterval;
1172 double RenderThemeEfl::animationDurationForProgressBar(RenderProgress*) const
1174 return progressAnimationInterval * progressAnimationFrames * 2; // "2" for back and forth;
1177 bool RenderThemeEfl::paintProgressBar(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1179 return paintThemePart(object, ProgressBar, info, rect);
1184 bool RenderThemeEfl::emitMediaButtonSignal(FormType formType, MediaControlElementType mediaElementType, const IntRect& rect)
1186 ThemePartCacheEntry* entry;
1188 entry = cacheThemePartGet(formType, rect.size());
1193 if (mediaElementType == MediaPlayButton)
1194 edje_object_signal_emit(entry->o, "play", "");
1195 else if (mediaElementType == MediaPauseButton)
1196 edje_object_signal_emit(entry->o, "pause", "");
1197 else if (mediaElementType == MediaMuteButton)
1198 edje_object_signal_emit(entry->o, "mute", "");
1199 else if (mediaElementType == MediaUnMuteButton)
1200 edje_object_signal_emit(entry->o, "sound", "");
1201 else if (mediaElementType == MediaSeekForwardButton)
1202 edje_object_signal_emit(entry->o, "seekforward", "");
1203 else if (mediaElementType == MediaSeekBackButton)
1204 edje_object_signal_emit(entry->o, "seekbackward", "");
1205 else if (mediaElementType == MediaEnterFullscreenButton)
1206 edje_object_signal_emit(entry->o, "fullscreen", "");
1207 else if (mediaElementType == MediaExitFullscreenButton)
1208 edje_object_signal_emit(entry->o, "normalscreen", "");
1215 String RenderThemeEfl::extraMediaControlsStyleSheet()
1217 #if ENABLE(TIZEN_MEDIA_CONTROL_USER_AGENT_SHEET)
1218 return String(mediaControlsTizenUserAgentStyleSheet, sizeof(mediaControlsTizenUserAgentStyleSheet));
1220 return String(mediaControlsEflUserAgentStyleSheet, sizeof(mediaControlsEflUserAgentStyleSheet));
1224 #if ENABLE(FULLSCREEN_API)
1225 #if ENABLE(TIZEN_MEDIA_CONTROL_USER_AGENT_SHEET)
1226 String RenderThemeEfl::extraFullScreenHorizontalStyleSheet()
1228 return String(mediaControlsTizenFullscreenHorizontalUserAgentStyleSheet, sizeof(mediaControlsTizenFullscreenHorizontalUserAgentStyleSheet));
1231 String RenderThemeEfl::extraFullScreenVerticalStyleSheet()
1233 return String(mediaControlsTizenFullscreenVerticalUserAgentStyleSheet, sizeof(mediaControlsTizenFullscreenVerticalUserAgentStyleSheet));
1236 String RenderThemeEfl::extraFullScreenStyleSheet()
1238 return String(mediaControlsEflFullscreenUserAgentStyleSheet, sizeof(mediaControlsEflFullscreenUserAgentStyleSheet));
1243 String RenderThemeEfl::formatMediaControlsCurrentTime(float currentTime, float duration) const
1245 #if ENABLE(TIZEN_GSTREAMER_VIDEO)
1246 return formatMediaControlsTime(currentTime); // show current time only
1248 return formatMediaControlsTime(currentTime) + " / " + formatMediaControlsTime(duration);
1252 bool RenderThemeEfl::paintMediaFullscreenButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1254 Node* mediaNode = object->node() ? object->node()->shadowHost() : 0;
1256 mediaNode = object->node();
1257 if (!mediaNode || (!mediaNode->hasTagName(videoTag)))
1260 if (!emitMediaButtonSignal(FullScreenButton, mediaControlElementType(object->node()), rect))
1263 return paintThemePart(object, FullScreenButton, info, rect);
1266 bool RenderThemeEfl::paintMediaMuteButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1268 Node* mediaNode = object->node() ? object->node()->shadowHost() : 0;
1270 mediaNode = object->node();
1271 if (!mediaNode || !mediaNode->isElementNode() || !static_cast<Element*>(mediaNode)->isMediaElement())
1274 HTMLMediaElement* mediaElement = static_cast<HTMLMediaElement*>(mediaNode);
1276 if (!emitMediaButtonSignal(MuteUnMuteButton, mediaElement->muted() ? MediaMuteButton : MediaUnMuteButton, rect))
1279 return paintThemePart(object, MuteUnMuteButton, info, rect);
1282 bool RenderThemeEfl::paintMediaPlayButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1284 Node* node = object->node();
1285 if (!node || !node->isMediaControlElement())
1288 if (!emitMediaButtonSignal(PlayPauseButton, mediaControlElementType(node), rect))
1291 return paintThemePart(object, PlayPauseButton, info, rect);
1294 bool RenderThemeEfl::paintMediaSeekBackButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1296 Node* node = object->node();
1297 if (!node || !node->isMediaControlElement())
1300 if (!emitMediaButtonSignal(SeekBackwardButton, mediaControlElementType(node), rect))
1303 return paintThemePart(object, SeekBackwardButton, info, rect);
1306 bool RenderThemeEfl::paintMediaSeekForwardButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1308 Node* node = object->node();
1309 if (!node || !node->isMediaControlElement())
1312 if (!emitMediaButtonSignal(SeekForwardButton, mediaControlElementType(node), rect))
1315 return paintThemePart(object, SeekForwardButton, info, rect);
1318 bool RenderThemeEfl::paintMediaSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1320 GraphicsContext* context = info.context;
1322 #if !ENABLE(TIZEN_GSTREAMER_VIDEO)
1323 context->fillRect(FloatRect(rect), m_mediaPanelColor, ColorSpaceDeviceRGB);
1324 context->fillRect(FloatRect(IntRect(rect.x(), rect.y() + (rect.height() - mediaSliderHeight) / 2,
1325 rect.width(), mediaSliderHeight)), m_mediaSliderColor, ColorSpaceDeviceRGB);
1328 RenderStyle* style = object->style();
1329 HTMLMediaElement* mediaElement = toParentMediaElement(object);
1334 #if ENABLE(TIZEN_GSTREAMER_VIDEO)
1336 if (mediaElement->isFullscreen() || mediaElement->ownerDocument()->isMediaDocument())
1337 thumbWidth = mediaSliderFullScreenThumbWidth;
1339 thumbWidth = mediaSliderThumbWidth;
1341 context->setLineCap(RoundCap);
1342 context->setStrokeStyle(SolidStroke);
1343 context->setStrokeColor(m_mediaSliderColor, ColorSpaceDeviceRGB);
1344 context->setStrokeThickness(rect.height());
1345 context->drawLine(IntPoint(rect.x() + thumbWidth / 2 , rect.y() + rect.height() / 2), IntPoint(rect.x() + rect.width() - thumbWidth / 2, rect.y() + rect.height() / 2));
1346 #endif // ENABLE(TIZEN_GSTREAMER_VIDEO)
1348 // Draw the buffered ranges. This code is highly inspired from
1349 // Chrome for the gradient code.
1350 float mediaDuration = mediaElement->duration();
1351 RefPtr<TimeRanges> timeRanges = mediaElement->buffered();
1352 IntRect trackRect = rect;
1353 int totalWidth = trackRect.width();
1355 trackRect.inflate(-style->borderLeftWidth());
1356 #if ENABLE(TIZEN_GSTREAMER_VIDEO)
1357 trackRect.setX(rect.x() + thumbWidth/2);
1358 totalWidth = trackRect.width() - thumbWidth;
1359 trackRect.setY(rect.y() + rect.height() / 2);
1362 context->setStrokeStyle(NoStroke);
1364 #if ENABLE(TIZEN_GSTREAMER_VIDEO)
1365 float suspendedPoint = 0;
1367 for (unsigned index = 0; index < timeRanges->length(); ++index) {
1368 ExceptionCode ignoredException;
1369 float start = timeRanges->start(index, ignoredException);
1370 float end = timeRanges->end(index, ignoredException);
1371 int width = ((end - start) * totalWidth) / mediaDuration;
1374 rangeRect = trackRect;
1375 rangeRect.setWidth(width);
1377 #if ENABLE(TIZEN_GSTREAMER_VIDEO)
1378 if (suspendedPoint != start) {
1379 start = suspendedPoint;
1380 width = ((end - start) * totalWidth) / mediaDuration;
1383 rangeRect.setLocation(IntPoint(trackRect.x() + start / mediaDuration* totalWidth, trackRect.y()));
1384 rangeRect.setSize(IntSize(width, trackRect.height()));
1386 #if ENABLE(TIZEN_GSTREAMER_VIDEO)
1387 suspendedPoint = timeRanges->end(index, ignoredException);
1390 // Don't bother drawing empty range.
1391 if (rangeRect.isEmpty())
1394 IntPoint sliderTopLeft = rangeRect.location();
1395 IntPoint sliderTopRight = sliderTopLeft;
1396 sliderTopRight.move(0, rangeRect.height());
1398 #if ENABLE(TIZEN_GSTREAMER_VIDEO)
1399 // In case of some files, metadata is positioned at end of file.
1401 if (timeRanges->length() > 1 && index == timeRanges->length() - 1)
1404 context->setLineCap(RoundCap);
1405 context->setStrokeStyle(SolidStroke);
1406 context->setStrokeColor(m_mediaBufferingColor, ColorSpaceDeviceRGB);
1407 context->setStrokeThickness(rangeRect.height());
1408 context->drawLine(IntPoint(rangeRect.x(), rangeRect.y()), IntPoint(rangeRect.x() + rangeRect.width(), rangeRect.y()));
1410 context->fillRect(FloatRect(rect), m_mediaPanelColor, ColorSpaceDeviceRGB);
1414 #if ENABLE(TIZEN_GSTREAMER_VIDEO)
1415 float currentTime = mediaElement->currentTime();
1416 if (currentTime > mediaDuration)
1417 currentTime = mediaDuration;
1419 int width = (currentTime * totalWidth) / mediaDuration;
1422 context->setLineCap(RoundCap);
1423 context->setStrokeStyle(SolidStroke);
1424 context->setStrokeColor(m_mediaPlayingColor, ColorSpaceDeviceRGB);
1425 context->setStrokeThickness(trackRect.height());
1426 context->drawLine(IntPoint(trackRect.x(), trackRect.y()), IntPoint(trackRect.x() + width, trackRect.y()));
1434 bool RenderThemeEfl::paintMediaSliderThumb(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1436 #if ENABLE(TIZEN_GSTREAMER_VIDEO)
1437 if (object->style()->appearance() == MediaSliderThumbPart)
1438 return paintThemePart(object, SliderThumb, info, rect);
1442 IntSize thumbRect(3, 3);
1443 info.context->fillRoundedRect(rect, thumbRect, thumbRect, thumbRect, thumbRect, m_sliderThumbColor, ColorSpaceDeviceRGB);
1448 bool RenderThemeEfl::paintMediaVolumeSliderContainer(RenderObject*, const PaintInfo& info, const IntRect& rect)
1454 bool RenderThemeEfl::paintMediaVolumeSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1460 bool RenderThemeEfl::paintMediaVolumeSliderThumb(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1466 bool RenderThemeEfl::paintMediaCurrentTime(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1468 info.context->fillRect(FloatRect(rect), m_mediaPanelColor, ColorSpaceDeviceRGB);
1472 #if ENABLE(TIZEN_GSTREAMER_VIDEO)
1473 bool RenderThemeEfl::paintMediaTimeRemaining(RenderObject* object, const PaintInfo& info, const IntRect& rect)
1475 info.context->fillRect(FloatRect(rect), m_mediaPanelColor, ColorSpaceDeviceRGB);