Changeset 127786 in webkit


Ignore:
Timestamp:
Sep 6, 2012 2:41:34 PM (12 years ago)
Author:
kenneth@webkit.org
Message:

[EFL] Fuzzy load the Edje theme for HTML forms
https://bugs.webkit.org/show_bug.cgi?id=95832

Reviewed by Antonio Gomes.

Change the theme so that it is first loaded when actually used.
This also fixed the case that it was impossible to change theme
a second time.

Tested by current tests. API unit test coming in separate patch.

  • platform/efl/RenderThemeEfl.cpp:

(WebCore):

Add some convenience macros.

(WebCore::applyColorCallback):

Use just one callback from the edje theme, which just calls
setColorFromThemeClass.

(WebCore::fillColorsFromEdjeClass):

Add convenience method for receiving colors from Edje and
storing them in Color's.

(WebCore::RenderThemeEfl::setColorFromThemeClass):

Set the class Color variabled with the values from the theme
color class.

(WebCore::RenderThemeEfl::setThemePath):

Don't apply the theme immediately.

(WebCore::RenderThemeEfl::loadTheme):

Load the new theme and free the current one. If it fails,
it will continue using the old one, if exists.

(WebCore::RenderThemeEfl::adjustSizeConstraints):
(WebCore::RenderThemeEfl::themePartCacheEntryReset):
(WebCore::RenderThemeEfl::cacheThemePartNew):
(WebCore::RenderThemeEfl::paintThemePart):
(WebCore::RenderThemeEfl::applyPartDescriptionsFrom):
(WebCore::RenderThemeEfl::platformActiveSelectionBackgroundColor):
(WebCore::RenderThemeEfl::platformInactiveSelectionBackgroundColor):
(WebCore::RenderThemeEfl::platformActiveSelectionForegroundColor):
(WebCore::RenderThemeEfl::platformInactiveSelectionForegroundColor):
(WebCore::RenderThemeEfl::platformFocusRingColor):

Ensure the theme is loaded.

(WebCore::RenderThemeEfl::adjustCheckboxStyle):
(WebCore::RenderThemeEfl::adjustRadioStyle):
(WebCore::RenderThemeEfl::emitMediaButtonSignal):

Ensure the theme is loaded.

  • platform/efl/RenderThemeEfl.h:

(RenderThemeEfl):
(WebCore::RenderThemeEfl::loadThemeIfNeeded):

Remove unneeded methods and add a method for loading a theme
in the case it is not loaded yet.

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r127783 r127786  
     12012-09-06  Kenneth Rohde Christiansen  <kenneth@webkit.org>
     2
     3        [EFL] Fuzzy load the Edje theme for HTML forms
     4        https://bugs.webkit.org/show_bug.cgi?id=95832
     5
     6        Reviewed by Antonio Gomes.
     7
     8        Change the theme so that it is first loaded when actually used.
     9        This also fixed the case that it was impossible to change theme
     10        a second time.
     11
     12        Tested by current tests. API unit test coming in separate patch.
     13
     14        * platform/efl/RenderThemeEfl.cpp:
     15        (WebCore):
     16
     17            Add some convenience macros.
     18
     19       (WebCore::applyColorCallback):
     20
     21            Use just one callback from the edje theme, which just calls
     22            setColorFromThemeClass.
     23
     24        (WebCore::fillColorsFromEdjeClass):
     25
     26            Add convenience method for receiving colors from Edje and
     27            storing them in Color's.
     28
     29        (WebCore::RenderThemeEfl::setColorFromThemeClass):
     30
     31            Set the class Color variabled with the values from the theme
     32            color class.
     33
     34        (WebCore::RenderThemeEfl::setThemePath):
     35
     36            Don't apply the theme immediately.
     37
     38        (WebCore::RenderThemeEfl::loadTheme):
     39
     40            Load the new theme and free the current one. If it fails,
     41            it will continue using the old one, if exists.
     42
     43        (WebCore::RenderThemeEfl::adjustSizeConstraints):
     44        (WebCore::RenderThemeEfl::themePartCacheEntryReset):
     45        (WebCore::RenderThemeEfl::cacheThemePartNew):
     46        (WebCore::RenderThemeEfl::paintThemePart):
     47        (WebCore::RenderThemeEfl::applyPartDescriptionsFrom):
     48        (WebCore::RenderThemeEfl::platformActiveSelectionBackgroundColor):
     49        (WebCore::RenderThemeEfl::platformInactiveSelectionBackgroundColor):
     50        (WebCore::RenderThemeEfl::platformActiveSelectionForegroundColor):
     51        (WebCore::RenderThemeEfl::platformInactiveSelectionForegroundColor):
     52        (WebCore::RenderThemeEfl::platformFocusRingColor):
     53
     54            Ensure the theme is loaded.
     55
     56        (WebCore::RenderThemeEfl::adjustCheckboxStyle):
     57        (WebCore::RenderThemeEfl::adjustRadioStyle):
     58        (WebCore::RenderThemeEfl::emitMediaButtonSignal):
     59
     60            Ensure the theme is loaded.
     61
     62        * platform/efl/RenderThemeEfl.h:
     63        (RenderThemeEfl):
     64        (WebCore::RenderThemeEfl::loadThemeIfNeeded):
     65
     66            Remove unneeded methods and add a method for loading a theme
     67            in the case it is not loaded yet.
     68
    1692012-09-06  Simon Fraser  <simon.fraser@apple.com>
    270
  • trunk/Source/WebCore/platform/efl/RenderThemeEfl.cpp

    r127626 r127786  
    8080#endif
    8181
     82#define _ASSERT_ON_RELEASE_RETURN(o, fmt, ...) \
     83    do { if (!o) { EINA_LOG_CRIT(fmt, ## __VA_ARGS__); ASSERT(o); return; } } while (0)
     84#define _ASSERT_ON_RELEASE_RETURN_VAL(o, val, fmt, ...) \
     85    do { if (!o) { EINA_LOG_CRIT(fmt, ## __VA_ARGS__); ASSERT(o); return val; } } while (0)
     86
    8287void RenderThemeEfl::adjustSizeConstraints(RenderStyle* style, FormType type) const
    8388{
     89    loadThemeIfNeeded();
     90    _ASSERT_ON_RELEASE_RETURN(m_edje, "Could not paint native HTML part due to missing theme.");
     91
    8492    const struct ThemePartDesc* desc = m_partDescs + (size_t)type;
    8593
     
    115123        Edje_Load_Error err = edje_object_load_error_get(entry->o);
    116124        const char *errmsg = edje_load_error_str(err);
    117         EINA_LOG_ERR("Could not load '%s' from theme %s: %s",
    118                      group, file, errmsg);
     125        EINA_LOG_ERR("Could not load '%s' from theme %s: %s", group, file, errmsg);
    119126        return false;
    120127    }
     
    160167{
    161168    if (isFormElementTooLargeToDisplay(size)) {
    162         EINA_LOG_ERR("cannot render an element of size %dx%d", size.width(), size.height());
     169        EINA_LOG_ERR("Cannot render an element of size %dx%d.", size.width(), size.height());
    163170        return 0;
    164171    }
     
    312319bool RenderThemeEfl::paintThemePart(RenderObject* object, FormType type, const PaintInfo& info, const IntRect& rect)
    313320{
     321    loadThemeIfNeeded();
     322    _ASSERT_ON_RELEASE_RETURN_VAL(m_edje, false, "Could not paint native HTML part due to missing theme.");
     323
    314324    ThemePartCacheEntry* entry;
    315325    Eina_List* updates;
    316326    cairo_t* cairo;
    317 
    318     ASSERT(m_canvas);
    319     ASSERT(m_edje);
    320327
    321328    entry = cacheThemePartGet(type, rect.size());
     
    400407}
    401408
    402 static void renderThemeEflColorClassSelectionActive(void* data, Evas_Object* object, const char* signal, const char* source)
    403 {
    404     RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data);
    405     int fr, fg, fb, fa, br, bg, bb, ba;
    406 
    407     if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0))
    408         return;
    409 
    410     that->setActiveSelectionColor(fr, fg, fb, fa, br, bg, bb, ba);
    411 }
    412 
    413 static void renderThemeEflColorClassSelectionInactive(void* data, Evas_Object* object, const char* signal, const char* source)
    414 {
    415     RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data);
    416     int fr, fg, fb, fa, br, bg, bb, ba;
    417 
    418     if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, 0, 0, 0, 0))
    419         return;
    420 
    421     that->setInactiveSelectionColor(fr, fg, fb, fa, br, bg, bb, ba);
    422 }
    423 
    424 static void renderThemeEflColorClassFocusRing(void* data, Evas_Object* object, const char* signal, const char* source)
    425 {
    426     RenderThemeEfl* that = static_cast<RenderThemeEfl *>(data);
    427     int fr, fg, fb, fa;
    428 
    429     if (!edje_object_color_class_get(object, source, &fr, &fg, &fb, &fa, 0, 0, 0, 0, 0, 0, 0, 0))
    430         return;
    431 
    432     that->setFocusRingColor(fr, fg, fb, fa);
     409static void applyColorCallback(void* data, Evas_Object*, const char* /* signal */, const char* colorClass)
     410{
     411    RenderThemeEfl* that = static_cast<RenderThemeEfl*>(data);
     412    that->setColorFromThemeClass(colorClass);
     413    that->platformColorsDidChange(); // Triggers relayout.
     414}
     415
     416static void fillColorsFromEdjeClass(Evas_Object* o, const char* colorClass, Color* color1, Color* color2 = 0, Color* color3 = 0)
     417{
     418    int r1, g1, b1, a1;
     419    int r2, g2, b2, a2;
     420    int r3, g3, b3, a3;
     421
     422    bool ok = edje_object_color_class_get(o, colorClass, &r1, &g1, &b1, &a1, &r2, &g2, &b2, &a2, &r3, &g3, &b3, &a3);
     423    _ASSERT_ON_RELEASE_RETURN(ok, "Could not get color class '%s'\n", colorClass);
     424
     425    if (color1)
     426        color1->setRGB(makeRGBA(r1, g1, b1, a1));
     427    if (color2)
     428        color2->setRGB(makeRGBA(r2, g2, b2, a2));
     429    if (color3)
     430        color3->setRGB(makeRGBA(r3, g3, b3, a3));
     431}
     432
     433void RenderThemeEfl::setColorFromThemeClass(const char* colorClass)
     434{
     435    ASSERT(m_edje);
     436
     437    if (!strcmp("webkit/selection/active", colorClass))
     438        fillColorsFromEdjeClass(m_edje, colorClass, &m_activeSelectionForegroundColor, &m_activeSelectionBackgroundColor);
     439    else if (!strcmp("webkit/selection/inactive", colorClass))
     440        fillColorsFromEdjeClass(m_edje, colorClass, &m_inactiveSelectionForegroundColor, &m_inactiveSelectionBackgroundColor);
     441    else if (!strcmp("webkit/focus_ring", colorClass)) {
     442        fillColorsFromEdjeClass(m_edje, colorClass, &m_focusRingColor);
     443        // platformFocusRingColor() is only used for the default theme (without page)
     444        // The following is ugly, but no other way to do it unless we change it to use page themes as much as possible.
     445        RenderTheme::setCustomFocusRingColor(m_focusRingColor);
     446    }
    433447}
    434448
     
    439453
    440454    m_themePath = path;
    441     themeChanged();
    442 }
    443 
    444 void RenderThemeEfl::createCanvas()
    445 {
    446     ASSERT(!m_canvas);
    447     m_canvas = ecore_evas_buffer_new(1, 1);
    448     ASSERT(m_canvas);
    449 }
    450 
    451 void RenderThemeEfl::createEdje()
    452 {
    453     ASSERT(!m_edje);
    454     if (m_themePath.isEmpty())
    455         EINA_LOG_ERR("No theme defined, unable to set RenderThemeEfl.");
    456     else {
    457         m_edje = edje_object_add(ecore_evas_get(m_canvas));
    458         if (!m_edje)
    459             EINA_LOG_ERR("Could not create base edje object.");
    460         else if (!edje_object_file_set(m_edje, m_themePath.utf8().data(), "webkit/base")) {
    461             Edje_Load_Error err = edje_object_load_error_get(m_edje);
    462             const char* errmsg = edje_load_error_str(err);
    463             EINA_LOG_ERR("Could not set file: %s", errmsg);
    464             evas_object_del(m_edje);
    465             m_edje = 0;
    466         } else {
    467 #define CONNECT(cc, func)                                               \
    468             edje_object_signal_callback_add(m_edje, "color_class,set",  \
    469                                             "webkit/"cc, func, this)
    470 
    471             CONNECT("selection/active",
    472                     renderThemeEflColorClassSelectionActive);
    473             CONNECT("selection/inactive",
    474                     renderThemeEflColorClassSelectionInactive);
    475             CONNECT("focus_ring", renderThemeEflColorClassFocusRing);
    476 #undef CONNECT
    477         }
    478     }
    479 }
    480 
    481 void RenderThemeEfl::applyEdjeColors()
    482 {
    483     int fr, fg, fb, fa, br, bg, bb, ba;
    484     ASSERT(m_edje);
    485 #define COLOR_GET(cls)                                                  \
    486     edje_object_color_class_get(m_edje, "webkit/"cls,                   \
    487                                 &fr, &fg, &fb, &fa, &br, &bg, &bb, &ba, \
    488                                 0, 0, 0, 0)
    489 
    490     if (COLOR_GET("selection/active")) {
    491         m_activeSelectionForegroundColor = Color(fr, fg, fb, fa);
    492         m_activeSelectionBackgroundColor = Color(br, bg, bb, ba);
    493     }
    494     if (COLOR_GET("selection/inactive")) {
    495         m_inactiveSelectionForegroundColor = Color(fr, fg, fb, fa);
    496         m_inactiveSelectionBackgroundColor = Color(br, bg, bb, ba);
    497     }
    498     if (COLOR_GET("focus_ring")) {
    499         m_focusRingColor = Color(fr, fg, fb, fa);
    500         // webkit just use platformFocusRingColor() for default theme (without page)
    501         // this is ugly, but no other way to do it unless we change
    502         // it to use page themes as much as possible.
    503         RenderTheme::setCustomFocusRingColor(m_focusRingColor);
    504     }
    505 #undef COLOR_GET
    506     platformColorsDidChange();
     455
     456    if (m_themePath.isEmpty()) {
     457        EINA_LOG_ERR("No theme defined, unable to set theme for HTML Forms.");
     458        return;
     459    }
     460
     461    if (!m_canvas) {
     462        m_canvas = ecore_evas_buffer_new(1, 1);
     463        if (!m_canvas)
     464            EINA_LOG_ERR("Could not create canvas.");
     465    }
     466
     467    loadTheme();
     468}
     469
     470bool RenderThemeEfl::loadTheme()
     471{
     472    Evas_Object* o = edje_object_add(ecore_evas_get(m_canvas));
     473    _ASSERT_ON_RELEASE_RETURN_VAL(o, false, "Could not create new base Edje object.");
     474
     475    if (!edje_object_file_set(o, m_themePath.utf8().data(), "webkit/base")) {
     476        Edje_Load_Error err = edje_object_load_error_get(o);
     477        const char* errmsg = edje_load_error_str(err);
     478        EINA_LOG_ERR("Could not set file '%s': %s", m_themePath.utf8().data(),  errmsg);
     479        evas_object_del(o);
     480        return false; // Keep current theme.
     481    }
     482
     483    // Get rid of existing theme.
     484    if (m_edje) {
     485        cacheThemePartFlush();
     486        evas_object_del(m_edje);
     487    }
     488
     489    // Set new loaded theme, and apply it.
     490    m_edje = o;
     491
     492    edje_object_signal_callback_add(m_edje, "color_class,set", "webkit/selection/active", applyColorCallback, this);
     493    edje_object_signal_callback_add(m_edje, "color_class,set", "webkit/selection/inactive", applyColorCallback, this);
     494    edje_object_signal_callback_add(m_edje, "color_class,set", "webkit/focus_ring", applyColorCallback, this);
     495
     496    applyPartDescriptionsFrom(m_edje);
     497
     498    setColorFromThemeClass("webkit/selection/active");
     499    setColorFromThemeClass("webkit/selection/inactive");
     500    setColorFromThemeClass("webkit/focus_ring");
     501
     502    platformColorsDidChange(); // Schedules a relayout, do last.
     503
     504    return true;
    507505}
    508506
     
    606604}
    607605
    608 void RenderThemeEfl::applyPartDescriptions()
     606void RenderThemeEfl::applyPartDescriptionsFrom(Evas_Object* o)
    609607{
    610608    Evas_Object* object;
     
    612610    const char* file;
    613611
    614     ASSERT(m_canvas);
    615     ASSERT(m_edje);
    616 
    617     edje_object_file_get(m_edje, &file, 0);
     612    ASSERT(o);
     613
     614    edje_object_file_get(o, &file, 0);
    618615    ASSERT(file);
     616    if (!file) {
     617        EINA_LOG_ERR("Could not retrieve Edje theme file.");
     618        return;
     619    }
    619620
    620621    object = edje_object_add(ecore_evas_get(m_canvas));
     
    639640    }
    640641    evas_object_del(object);
    641 }
    642 
    643 void RenderThemeEfl::themeChanged()
    644 {
    645     cacheThemePartFlush();
    646 
    647     if (!m_canvas) {
    648         createCanvas();
    649         if (!m_canvas)
    650             return;
    651     }
    652 
    653     if (!m_edje) {
    654         createEdje();
    655         if (!m_edje)
    656             return;
    657     }
    658 
    659     applyEdjeColors();
    660     applyPartDescriptions();
    661642}
    662643
     
    688669        ecore_evas_free(m_canvas);
    689670    }
    690 }
    691 
    692 void RenderThemeEfl::setActiveSelectionColor(int foreR, int foreG, int foreB, int foreA, int backR, int backG, int backB, int backA)
    693 {
    694     m_activeSelectionForegroundColor = Color(foreR, foreG, foreB, foreA);
    695     m_activeSelectionBackgroundColor = Color(backR, backG, backB, backA);
    696     platformColorsDidChange();
    697 }
    698 
    699 void RenderThemeEfl::setInactiveSelectionColor(int foreR, int foreG, int foreB, int foreA, int backR, int backG, int backB, int backA)
    700 {
    701     m_inactiveSelectionForegroundColor = Color(foreR, foreG, foreB, foreA);
    702     m_inactiveSelectionBackgroundColor = Color(backR, backG, backB, backA);
    703     platformColorsDidChange();
    704 }
    705 
    706 void RenderThemeEfl::setFocusRingColor(int r, int g, int b, int a)
    707 {
    708     m_focusRingColor = Color(r, g, b, a);
    709     // webkit just use platformFocusRingColor() for default theme (without page)
    710     // this is ugly, but no other way to do it unless we change
    711     // it to use page themes as much as possible.
    712     RenderTheme::setCustomFocusRingColor(m_focusRingColor);
    713     platformColorsDidChange();
    714671}
    715672
     
    755712}
    756713
     714Color RenderThemeEfl::platformActiveSelectionBackgroundColor() const
     715{
     716    loadThemeIfNeeded();
     717    return m_activeSelectionBackgroundColor;
     718}
     719
     720Color RenderThemeEfl::platformInactiveSelectionBackgroundColor() const
     721{
     722    loadThemeIfNeeded();
     723    return m_inactiveSelectionBackgroundColor;
     724}
     725
     726Color RenderThemeEfl::platformActiveSelectionForegroundColor() const
     727{
     728    loadThemeIfNeeded();
     729    return m_activeSelectionForegroundColor;
     730}
     731
     732Color RenderThemeEfl::platformInactiveSelectionForegroundColor() const
     733{
     734    loadThemeIfNeeded();
     735    return m_inactiveSelectionForegroundColor;
     736}
     737
     738Color RenderThemeEfl::platformFocusRingColor() const
     739{
     740    loadThemeIfNeeded();
     741    return m_focusRingColor;
     742}
     743
    757744bool RenderThemeEfl::paintSliderTrack(RenderObject* object, const PaintInfo& info, const IntRect& rect)
    758745{
     
    843830        return;
    844831    }
     832
    845833    adjustSizeConstraints(style, CheckBox);
     834    ASSERT(m_edje);
     835
    846836    style->resetBorder();
    847837
     
    864854        return;
    865855    }
     856
    866857    adjustSizeConstraints(style, RadioButton);
     858    ASSERT(m_edje);
     859
    867860    style->resetBorder();
    868861
     
    10871080bool RenderThemeEfl::emitMediaButtonSignal(FormType formType, MediaControlElementType mediaElementType, const IntRect& rect)
    10881081{
     1082    loadThemeIfNeeded();
     1083    _ASSERT_ON_RELEASE_RETURN_VAL(m_edje, false, "Could not paint native HTML part due to missing theme.");
     1084
    10891085    ThemePartCacheEntry* entry;
    10901086
    10911087    entry = cacheThemePartGet(formType, rect.size());
    1092     ASSERT(entry);
    1093     if (!entry)
    1094         return false;
     1088    _ASSERT_ON_RELEASE_RETURN_VAL(entry, false, "Could not paint native HTML part due to missing theme part.");
    10951089
    10961090    if (mediaElementType == MediaPlayButton)
     
    12811275}
    12821276#endif
    1283 }
     1277
     1278#undef _ASSERT_ON_RELEASE_RETURN
     1279#undef _ASSERT_ON_RELEASE_RETURN_VAL
     1280
     1281}
  • trunk/Source/WebCore/platform/efl/RenderThemeEfl.h

    r127723 r127786  
    9797    virtual LayoutUnit baselinePosition(const RenderObject*) const;
    9898
    99     virtual Color platformActiveSelectionBackgroundColor() const { return m_activeSelectionBackgroundColor; }
    100     virtual Color platformInactiveSelectionBackgroundColor() const { return m_inactiveSelectionBackgroundColor; }
    101     virtual Color platformActiveSelectionForegroundColor() const { return m_activeSelectionForegroundColor; }
    102     virtual Color platformInactiveSelectionForegroundColor() const { return m_inactiveSelectionForegroundColor; }
    103     virtual Color platformFocusRingColor() const { return m_focusRingColor; }
    104 
    105     virtual void themeChanged();
    106 
    107     // Set platform colors and notify they changed
    108     void setActiveSelectionColor(int foreR, int foreG, int foreB, int foreA, int backR, int backG, int backB, int backA);
    109     void setInactiveSelectionColor(int foreR, int foreG, int foreB, int foreA, int backR, int backG, int backB, int backA);
    110     void setFocusRingColor(int r, int g, int b, int a);
     99    virtual Color platformActiveSelectionBackgroundColor() const;
     100    virtual Color platformInactiveSelectionBackgroundColor() const;
     101    virtual Color platformActiveSelectionForegroundColor() const;
     102    virtual Color platformInactiveSelectionForegroundColor() const;
     103    virtual Color platformFocusRingColor() const;
     104
     105    // Set platform colors; remember to call platformColorDidChange after.
     106    void setColorFromThemeClass(const char* colorClass);
    111107
    112108    void setButtonTextColor(int foreR, int foreG, int foreB, int foreA, int backR, int backG, int backB, int backA);
     
    116112
    117113    void adjustSizeConstraints(RenderStyle*, FormType) const;
    118 
    119114
    120115    // System fonts.
     
    210205    void setThemePath(const String&);
    211206    String themePath() { return m_themePath; }
     207
    212208protected:
    213209    static float defaultFontSize;
    214210
    215211private:
    216     void createCanvas();
    217     void createEdje();
    218     void applyEdjeColors();
    219     void applyPartDescriptions();
     212    bool loadTheme();
     213    ALWAYS_INLINE bool loadThemeIfNeeded() const
     214    {
     215        return m_edje || const_cast<RenderThemeEfl*>(this)->loadTheme();
     216    }
     217
     218    void applyPartDescriptionsFrom(Evas_Object*);
     219
    220220    const char* edjeGroupFromFormType(FormType) const;
    221221    void applyEdjeStateFromForm(Evas_Object*, ControlStates);
Note: See TracChangeset for help on using the changeset viewer.