Home | History | Annotate | Download | only in efl
      1 /*
      2  *  Copyright (C) 2007 Holger Hans Peter Freyther zecke (at) selfish.org
      3  *            (C) 2009 Kenneth Rohde Christiansen
      4  *            (C) 2009 INdT, Instituto Nokia de Technologia
      5  *            (C) 2009-2010 ProFUSION embedded systems
      6  *            (C) 2009-2010 Samsung Electronics
      7  *
      8  *  This library is free software; you can redistribute it and/or
      9  *  modify it under the terms of the GNU Lesser General Public
     10  *  License as published by the Free Software Foundation; either
     11  *  version 2 of the License, or (at your option) any later version.
     12  *
     13  *  This library is distributed in the hope that it will be useful,
     14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     16  *  Lesser General Public License for more details.
     17  *
     18  *  You should have received a copy of the GNU Lesser General Public
     19  *  License along with this library; if not, write to the Free Software
     20  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     21  */
     22 
     23 #include "config.h"
     24 #include "ScrollbarEfl.h"
     25 
     26 #include "ChromeClient.h"
     27 #include "Frame.h"
     28 #include "FrameView.h"
     29 #include "GraphicsContext.h"
     30 #include "HostWindow.h"
     31 #include "IntRect.h"
     32 #include "NotImplemented.h"
     33 #include "Page.h"
     34 #include "ScrollbarTheme.h"
     35 
     36 #include <Ecore.h>
     37 #include <Edje.h>
     38 #include <Evas.h>
     39 #include <string>
     40 #include <wtf/text/CString.h>
     41 
     42 using namespace std;
     43 using namespace WebCore;
     44 
     45 PassRefPtr<Scrollbar> Scrollbar::createNativeScrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, ScrollbarControlSize size)
     46 {
     47     return adoptRef(new ScrollbarEfl(scrollableArea, orientation, size));
     48 }
     49 
     50 ScrollbarEfl::ScrollbarEfl(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, ScrollbarControlSize controlSize)
     51     : Scrollbar(scrollableArea, orientation, controlSize)
     52     , m_lastPos(0)
     53     , m_lastTotalSize(0)
     54     , m_lastVisibleSize(0)
     55 {
     56     Widget::setFrameRect(IntRect(0, 0, 0, 0));
     57 }
     58 
     59 ScrollbarEfl::~ScrollbarEfl()
     60 {
     61     if (!evasObject())
     62         return;
     63     evas_object_del(evasObject());
     64     setEvasObject(0);
     65 }
     66 
     67 static void scrollbarEflEdjeMessage(void* data, Evas_Object* object, Edje_Message_Type messageType, int id, void* message)
     68 {
     69     ScrollbarEfl* that = static_cast<ScrollbarEfl*>(data);
     70     Edje_Message_Float* messageFloat;
     71     int value;
     72 
     73     if (!id) {
     74         EINA_LOG_ERR("Unknown message id '%d' from scroll bar theme.", id);
     75         return;
     76     }
     77 
     78     if (messageType != EDJE_MESSAGE_FLOAT) {
     79         EINA_LOG_ERR("Message id '%d' of incorrect type from scroll bar theme. "
     80                      "Expected '%d', got '%d'.",
     81                      id, EDJE_MESSAGE_FLOAT, messageType);
     82         return;
     83     }
     84 
     85     messageFloat = static_cast<Edje_Message_Float*>(message);
     86     value = messageFloat->val * (that->totalSize() - that->visibleSize());
     87     that->scrollableArea()->scrollToOffsetWithoutAnimation(that->orientation(), value);
     88 }
     89 
     90 void ScrollbarEfl::setParent(ScrollView* view)
     91 {
     92     Evas_Object* object = evasObject();
     93     Evas_Coord w, h;
     94 
     95     Widget::setParent(view);
     96 
     97     if (!object) {
     98         if (!view)
     99             return;
    100 
    101         object = edje_object_add(view->evas());
    102         if (!object) {
    103             EINA_LOG_ERR("Could not create edje object for view=%p (evas=%p)",
    104                          view, view->evas());
    105             return;
    106         }
    107         edje_object_message_handler_set(object, scrollbarEflEdjeMessage, this);
    108         setEvasObject(object);
    109     } else if (!view) {
    110         evas_object_hide(object);
    111         return;
    112     }
    113 
    114     const char* group = (orientation() == HorizontalScrollbar)
    115         ? "scrollbar.horizontal" : "scrollbar.vertical";
    116     String theme(edjeThemeRecursive());
    117 
    118     if (theme.isEmpty()) {
    119         EINA_LOG_ERR("Could not load theme '%s': no theme path set.", group);
    120         evas_object_hide(object);
    121         return;
    122     }
    123 
    124     if (!edje_object_file_set(object, theme.utf8().data(), group)) {
    125         Edje_Load_Error err = edje_object_load_error_get(object);
    126         const char* errmessage = edje_load_error_str(err);
    127         EINA_LOG_ERR("Could not load theme '%s' from file '%s': #%d '%s'",
    128                      group, theme.utf8().data(), err, errmessage);
    129         return;
    130     }
    131 
    132     setPlatformWidget(object);
    133     evas_object_smart_member_add(object, view->evasObject());
    134     evas_object_show(object);
    135 
    136     edje_object_size_min_get(object, &w, &h);
    137 
    138     IntRect rect = frameRect();
    139     rect.setSize(IntSize(w, h));
    140     setFrameRect(rect);
    141 }
    142 
    143 void ScrollbarEfl::updateThumbPosition()
    144 {
    145     updateThumbPositionAndProportion();
    146 }
    147 
    148 void ScrollbarEfl::updateThumbProportion()
    149 {
    150     updateThumbPositionAndProportion();
    151 }
    152 
    153 void ScrollbarEfl::updateThumbPositionAndProportion()
    154 {
    155     if (!platformWidget())
    156         return;
    157 
    158     int pos = currentPos();
    159     int tSize = totalSize();
    160     int vSize = visibleSize();
    161 
    162     if (m_lastPos == pos
    163         && m_lastTotalSize == tSize
    164         && m_lastVisibleSize == vSize)
    165         return;
    166 
    167     m_lastPos = pos;
    168     m_lastTotalSize = tSize;
    169     m_lastVisibleSize = vSize;
    170 
    171     Edje_Message_Float_Set* message = static_cast<Edje_Message_Float_Set*>
    172         (alloca(sizeof(Edje_Message_Float_Set) + sizeof(float)));
    173     message->count = 2;
    174 
    175     if (tSize - vSize > 0)
    176         message->val[0] = pos / static_cast<float>(tSize - vSize);
    177     else
    178         message->val[0] = 0.0;
    179 
    180     if (tSize > 0)
    181         message->val[1] = vSize / static_cast<float>(tSize);
    182     else
    183         message->val[1] = 0.0;
    184 
    185     edje_object_message_send(platformWidget(), EDJE_MESSAGE_FLOAT_SET, 0, message);
    186 }
    187 
    188 void ScrollbarEfl::setFrameRect(const IntRect& rect)
    189 {
    190     Widget::setFrameRect(rect);
    191     frameRectsChanged();
    192 }
    193 
    194 void ScrollbarEfl::frameRectsChanged()
    195 {
    196     Evas_Object* object = platformWidget();
    197     Evas_Coord x, y;
    198 
    199     if (!parent() || !object)
    200         return;
    201 
    202     IntRect rect = frameRect();
    203     if (parent()->isScrollViewScrollbar(this))
    204         rect.setLocation(parent()->convertToContainingWindow(rect.location()));
    205     else
    206         rect.setLocation(parent()->contentsToWindow(rect.location()));
    207 
    208     evas_object_geometry_get(root()->evasObject(), &x, &y, 0, 0);
    209     evas_object_move(object, x + rect.x(), y + rect.y());
    210     evas_object_resize(object, rect.width(), rect.height());
    211 }
    212 
    213 void ScrollbarEfl::paint(GraphicsContext* graphicsContext, const IntRect& damageRect)
    214 {
    215 }
    216 
    217