• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (C) 2007 Holger Hans Peter Freyther zecke@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 
createNativeScrollbar(ScrollableArea * scrollableArea,ScrollbarOrientation orientation,ScrollbarControlSize size)45 PassRefPtr<Scrollbar> Scrollbar::createNativeScrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, ScrollbarControlSize size)
46 {
47     return adoptRef(new ScrollbarEfl(scrollableArea, orientation, size));
48 }
49 
ScrollbarEfl(ScrollableArea * scrollableArea,ScrollbarOrientation orientation,ScrollbarControlSize controlSize)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 
~ScrollbarEfl()59 ScrollbarEfl::~ScrollbarEfl()
60 {
61     if (!evasObject())
62         return;
63     evas_object_del(evasObject());
64     setEvasObject(0);
65 }
66 
scrollbarEflEdjeMessage(void * data,Evas_Object * object,Edje_Message_Type messageType,int id,void * message)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 
setParent(ScrollView * view)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 
updateThumbPosition()143 void ScrollbarEfl::updateThumbPosition()
144 {
145     updateThumbPositionAndProportion();
146 }
147 
updateThumbProportion()148 void ScrollbarEfl::updateThumbProportion()
149 {
150     updateThumbPositionAndProportion();
151 }
152 
updateThumbPositionAndProportion()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 
setFrameRect(const IntRect & rect)188 void ScrollbarEfl::setFrameRect(const IntRect& rect)
189 {
190     Widget::setFrameRect(rect);
191     frameRectsChanged();
192 }
193 
frameRectsChanged()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 
paint(GraphicsContext * graphicsContext,const IntRect & damageRect)213 void ScrollbarEfl::paint(GraphicsContext* graphicsContext, const IntRect& damageRect)
214 {
215 }
216 
217