}
static void
+_zoom_out_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Web_Test *wt = data;
+ double zoom;
+
+ zoom = elm_web_zoom_get(wt->web);
+ if (zoom > 1)
+ zoom -= .5;
+ else
+ zoom /= 2;
+ if (zoom < .05)
+ zoom = .05;
+ elm_web_zoom_set(wt->web, zoom);
+}
+
+static void
+_zoom_in_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Web_Test *wt = data;
+ double zoom;
+
+ zoom = elm_web_zoom_get(wt->web);
+
+ if (zoom < 1)
+ zoom *= 2;
+ else
+ zoom += .5;
+ if (zoom > 4)
+ zoom = 4;
+ elm_web_zoom_set(wt->web, zoom);
+}
+
+static void
+_zoom_mode_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Web_Test *wt = data;
+ Elm_Hoversel_Item *it = event_info;
+ const char *lbl = elm_hoversel_item_label_get(it);
+
+ if (!strcmp(lbl, "Manual"))
+ elm_web_zoom_mode_set(wt->web, ELM_WEB_ZOOM_MODE_MANUAL);
+ else if (!strcmp(lbl, "Fit"))
+ elm_web_zoom_mode_set(wt->web, ELM_WEB_ZOOM_MODE_AUTO_FIT);
+ else
+ elm_web_zoom_mode_set(wt->web, ELM_WEB_ZOOM_MODE_AUTO_FILL);
+}
+
+static void
+_show_region_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Web_Test *wt = data;
+ elm_web_region_show(wt->web, 300, 300, 1, 1);
+}
+
+static void
+_bring_in_region_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Web_Test *wt = data;
+ elm_web_region_bring_in(wt->web, 50, 0, 1, 1);
+}
+
+static void
_main_web_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
Web_Test *wt = data;
evas_object_smart_callback_add(bt, "clicked", _js_popup_hooks_set, wt);
+ bt = elm_button_add(win);
+ elm_object_text_set(bt, "-");
+ elm_box_pack_end(bx2, bt);
+ evas_object_show(bt);
+
+ evas_object_smart_callback_add(bt, "clicked", _zoom_out_cb, wt);
+
+ bt = elm_button_add(win);
+ elm_object_text_set(bt, "+");
+ elm_box_pack_end(bx2, bt);
+ evas_object_show(bt);
+
+ evas_object_smart_callback_add(bt, "clicked", _zoom_in_cb, wt);
+
+ bt = elm_hoversel_add(win);
+ elm_object_text_set(bt, "Zoom Mode");
+ elm_box_pack_end(bx2, bt);
+ evas_object_show(bt);
+
+ elm_hoversel_item_add(bt, "Manual", NULL, ELM_ICON_NONE, _zoom_mode_cb, wt);
+ elm_hoversel_item_add(bt, "Fit", NULL, ELM_ICON_NONE, _zoom_mode_cb, wt);
+ elm_hoversel_item_add(bt, "Fill", NULL, ELM_ICON_NONE, _zoom_mode_cb, wt);
+
+ bx2 = elm_box_add(win);
+ elm_box_horizontal_set(bx2, EINA_TRUE);
+ evas_object_size_hint_weight_set(bx2, EVAS_HINT_EXPAND, 0);
+ evas_object_size_hint_align_set(bx2, EVAS_HINT_FILL, 0);
+ elm_box_pack_end(bx, bx2);
+ evas_object_show(bx2);
+
+ bt = elm_button_add(win);
+ elm_object_text_set(bt, "Show 300, 300");
+ elm_box_pack_end(bx2, bt);
+ evas_object_show(bt);
+
+ evas_object_smart_callback_add(bt, "clicked", _show_region_cb, wt);
+
+ bt = elm_button_add(win);
+ elm_object_text_set(bt, "Bring in 50, 0");
+ elm_box_pack_end(bx2, bt);
+ evas_object_show(bt);
+
+ evas_object_smart_callback_add(bt, "clicked", _bring_in_region_cb, wt);
+
evas_object_smart_callback_add(web, "title,changed", _title_changed_cb, win);
evas_object_smart_callback_add(web, "uri,changed", _uri_changed_cb, wt);
};
/**
+ * Types of zoom available.
+ */
+ typedef enum _Elm_Web_Zoom_Mode
+ {
+ ELM_WEB_ZOOM_MODE_MANUAL = 0, /**< Zoom controled normally by elm_web_zoom_set */
+ ELM_WEB_ZOOM_MODE_AUTO_FIT, /**< Zoom until content fits in web object */
+ ELM_WEB_ZOOM_MODE_AUTO_FILL, /**< Zoom until content fills web object */
+ ELM_WEB_ZOOM_MODE_LAST
+ } Elm_Web_Zoom_Mode;
+ /**
* Opaque handler containing the features (such as statusbar, menubar, etc)
* that are to be set on a newly requested window.
*/
*/
EAPI void elm_web_history_enable_set(Evas_Object *obj, Eina_Bool enable);
/**
+ * Sets the zoom level of the web object
+ *
+ * Zoom level matches the Webkit API, so 1.0 means normal zoom, with higher
+ * values meaning zoom in and lower meaning zoom out. This function will
+ * only affect the zoom level if the mode set with elm_web_zoom_mode_set()
+ * is ::ELM_WEB_ZOOM_MODE_MANUAL.
+ *
+ * @param obj The web object
+ * @param zoom The zoom level to set
+ */
+ EAPI void elm_web_zoom_set(Evas_Object *obj, double zoom);
+ /**
+ * Gets the current zoom level set on the web object
+ *
+ * Note that this is the zoom level set on the web object and not that
+ * of the underlying Webkit one. In the ::ELM_WEB_ZOOM_MODE_MANUAL mode,
+ * the two zoom levels should match, but for the other two modes the
+ * Webkit zoom is calculated internally to match the chosen mode without
+ * changing the zoom level set for the web object.
+ *
+ * @param obj The web object
+ *
+ * @return The zoom level set on the object
+ */
+ EAPI double elm_web_zoom_get(const Evas_Object *obj);
+ /**
+ * Sets the zoom mode to use
+ *
+ * The modes can be any of those defined in ::Elm_Web_Zoom_Mode, except
+ * ::ELM_WEB_ZOOM_MODE_LAST. The default is ::ELM_WEB_ZOOM_MODE_MANUAL.
+ *
+ * ::ELM_WEB_ZOOM_MODE_MANUAL means the zoom level will be controlled
+ * with the elm_web_zoom_set() function.
+ * ::ELM_WEB_ZOOM_MODE_AUTO_FIT will calculate the needed zoom level to
+ * make sure the entirety of the web object's contents are shown.
+ * ::ELM_WEB_ZOOM_MODE_AUTO_FILL will calculate the needed zoom level to
+ * fit the contents in the web object's size, without leaving any space
+ * unused.
+ *
+ * @param obj The web object
+ * @param mode The mode to set
+ */
+ EAPI void elm_web_zoom_mode_set(Evas_Object *obj, Elm_Web_Zoom_Mode mode);
+ /**
+ * Gets the currently set zoom mode
+ *
+ * @param obj The web object
+ *
+ * @return The current zoom mode set for the object, or
+ * ::ELM_WEB_ZOOM_MODE_LAST on error
+ */
+ EAPI Elm_Web_Zoom_Mode elm_web_zoom_mode_get(const Evas_Object *obj);
+ /**
* Gets whether text-only zoom is set
*
* @param obj The web object
*/
EAPI void elm_web_zoom_text_only_set(Evas_Object *obj, Eina_Bool setting);
/**
+ * Shows the given region in the web object
+ *
+ * @param obj The web object
+ * @param x The x coordinate of the region to show
+ * @param y The y coordinate of the region to show
+ * @param w The width of the region to show
+ * @param h The height of the region to show
+ */
+ EAPI void elm_web_region_show(Evas_Object *obj, int x, int y, int w, int h);
+ /**
+ * Brings in the region to the visible area
+ *
+ * Like elm_web_region_show(), but it animates the scrolling of the object
+ * to show the area
+ *
+ * @param obj The web object
+ * @param x The x coordinate of the region to show
+ * @param y The y coordinate of the region to show
+ * @param w The width of the region to show
+ * @param h The height of the region to show
+ */
+ EAPI void elm_web_region_bring_in(Evas_Object *obj, int x, int y, int w, int h);
+ /**
* Sets the default dialogs to use an Inwin instead of a normal window
*
* If set, then the default implementation for the JavaScript dialogs and
void *console_message_data;
} hook;
Elm_Win_Keyboard_Mode input_method;
+ struct {
+ Elm_Web_Zoom_Mode mode;
+ float current;
+ float min, max;
+ Eina_Bool no_anim;
+ Ecore_Timer *timer;
+ } zoom;
+ struct {
+ struct {
+ int x, y;
+ } start, end;
+ Ecore_Animator *animator;
+ } bring_in;
Eina_Bool tab_propagate : 1;
Eina_Bool inwin_mode : 1;
#else
}
static void
+_ewk_view_load_finished_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info)
+{
+ Widget_Data *wd = data;
+
+ if (event_info)
+ return;
+
+ if (wd->zoom.mode != ELM_WEB_ZOOM_MODE_MANUAL)
+ {
+ float tz = wd->zoom.current;
+ wd->zoom.current = 0.0;
+ elm_web_zoom_set(wd->self, tz);
+ }
+}
+
+static void
+_ewk_view_viewport_changed_cb(void *data, Evas_Object *obj, void *event_info __UNUSED__)
+{
+ Widget_Data *wd = data;
+
+ if (wd->zoom.mode != ELM_WEB_ZOOM_MODE_MANUAL)
+ {
+ ewk_view_zoom_set(obj, 1.0, 0, 0);
+ wd->zoom.no_anim = EINA_TRUE;
+ }
+}
+
+static Eina_Bool
+_restore_zoom_mode_timer_cb(void *data)
+{
+ Widget_Data *wd = data;
+ float tz = wd->zoom.current;
+ wd->zoom.timer = NULL;
+ wd->zoom.current = 0.0;
+ wd->zoom.no_anim = EINA_TRUE;
+ elm_web_zoom_set(wd->self, tz);
+ return EINA_FALSE;
+}
+
+static Eina_Bool
+_reset_zoom_timer_cb(void *data)
+{
+ Widget_Data *wd = data;
+ wd->zoom.timer = ecore_timer_add(0.0, _restore_zoom_mode_timer_cb, wd);
+ ewk_view_zoom_set(wd->ewk_view, 1.0, 0, 0);
+ return EINA_FALSE;
+}
+
+static void
+_ewk_view_resized_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+ Widget_Data *wd = data;
+ if (!(wd->zoom.mode != ELM_WEB_ZOOM_MODE_MANUAL))
+ return;
+ if (wd->zoom.timer)
+ ecore_timer_del(wd->zoom.timer);
+ wd->zoom.timer = ecore_timer_add(0.5, _reset_zoom_timer_cb, wd);
+}
+
+static void
_popup_del_job(void *data)
{
evas_object_del(data);
_view_smart_callback_proxy_cb, ctxt);
}
}
+
+static Eina_Bool
+_bring_in_anim_cb(void *data, double pos)
+{
+ Widget_Data *wd = data;
+ Evas_Object *frame = ewk_view_frame_main_get(wd->ewk_view);
+ int sx, sy, rx, ry;
+
+ sx = wd->bring_in.start.x;
+ sy = wd->bring_in.start.y;
+ rx = (wd->bring_in.end.x - sx) * pos;
+ ry = (wd->bring_in.end.y - sy) * pos;
+
+ ewk_frame_scroll_set(frame, rx + sx, ry + sy);
+
+ if (pos == 1.0)
+ {
+ wd->bring_in.end.x = wd->bring_in.end.y = wd->bring_in.start.x =
+ wd->bring_in.start.y = 0;
+ wd->bring_in.animator = NULL;
+ }
+
+ return EINA_TRUE;
+}
#endif
#ifdef HAVE_ELEMENTARY_WEB
_ewk_view_load_started_cb, wd);
evas_object_smart_callback_add(wd->ewk_view, "popup,create",
_ewk_view_popup_create_cb, wd);
+ evas_object_smart_callback_add(wd->ewk_view, "load,finished",
+ _ewk_view_load_finished_cb, wd);
+ evas_object_smart_callback_add(wd->ewk_view, "viewport,changed",
+ _ewk_view_viewport_changed_cb, wd);
+ evas_object_smart_callback_add(wd->ewk_view, "view,resized",
+ _ewk_view_resized_cb, wd);
elm_widget_resize_object_set(obj, wd->ewk_view);
wd->tab_propagate = EINA_FALSE;
wd->inwin_mode = _elm_config->inwin_dialogs_enable;
+ wd->zoom.min = ewk_view_zoom_range_min_get(wd->ewk_view);
+ wd->zoom.max = ewk_view_zoom_range_max_get(wd->ewk_view);
+ wd->zoom.current = 1.0;
_view_smart_callback_proxy(wd->ewk_view, wd->self);
evas_object_smart_callbacks_descriptions_set(obj, _elm_web_callback_names);
//EAPI Ewk_History *ewk_view_history_get(const Evas_Object *obj); // TODO:
+EAPI void
+elm_web_zoom_set(Evas_Object *obj, double zoom)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+#ifdef HAVE_ELEMENTARY_WEB
+ Widget_Data *wd = elm_widget_data_get(obj);
+ int vw, vh, cx, cy;
+ float z = 1.0;
+ evas_object_geometry_get(wd->ewk_view, NULL, NULL, &vw, &vh);
+ cx = vw / 2;
+ cy = vh / 2;
+ if (zoom > wd->zoom.max)
+ zoom = wd->zoom.max;
+ else if (zoom < wd->zoom.min)
+ zoom = wd->zoom.min;
+ if (zoom == wd->zoom.current) return;
+ wd->zoom.current = zoom;
+ if (wd->zoom.mode == ELM_WEB_ZOOM_MODE_MANUAL)
+ z = zoom;
+ else if (wd->zoom.mode == ELM_WEB_ZOOM_MODE_AUTO_FIT)
+ {
+ Evas_Object *frame = ewk_view_frame_main_get(wd->ewk_view);
+ Evas_Coord fw, fh, pw, ph;
+ if (!ewk_frame_contents_size_get(frame, &fw, &fh))
+ return;
+ z = ewk_frame_zoom_get(frame);
+ fw /= z;
+ fh /= z;
+ if ((fw > 0) && (fh > 0))
+ {
+ ph = (fh * vw) / fw;
+ if (ph > vh)
+ {
+ pw = (fw * vh) / fh;
+ ph = vh;
+ }
+ else
+ pw = vw;
+ if (fw > fh)
+ z = (float)pw / fw;
+ else
+ z = (float)ph / fh;
+ }
+ }
+ else if (wd->zoom.mode == ELM_WEB_ZOOM_MODE_AUTO_FILL)
+ {
+ Evas_Object *frame = ewk_view_frame_main_get(wd->ewk_view);
+ Evas_Coord fw, fh, pw, ph;
+ if (!ewk_frame_contents_size_get(frame, &fw, &fh))
+ return;
+ z = ewk_frame_zoom_get(frame);
+ fw /= z;
+ fh /= z;
+ if ((fw > 0) && (fh > 0))
+ {
+ ph = (fh * vw) / fw;
+ if (ph < vh)
+ {
+ pw = (fw * vh) / fh;
+ ph = vh;
+ }
+ else
+ pw = vw;
+ if (fw > fh)
+ z = (float)pw / fw;
+ else
+ z = (float)ph / fh;
+ }
+ }
+ if (wd->zoom.no_anim)
+ ewk_view_zoom_set(wd->ewk_view, z, cx, cy);
+ else
+ ewk_view_zoom_animated_set(wd->ewk_view, z, _elm_config->zoom_friction,
+ cx, cy);
+ wd->zoom.no_anim = EINA_FALSE;
+#else
+ (void)zoom;
+#endif
+}
+
+EAPI double
+elm_web_zoom_get(const Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) -1.0;
+#ifdef HAVE_ELEMENTARY_WEB
+ Widget_Data *wd = elm_widget_data_get(obj);
+ return wd->zoom.current;
+#else
+ return -1.0;
+#endif
+}
+
+EAPI void
+elm_web_zoom_mode_set(Evas_Object *obj, Elm_Web_Zoom_Mode mode)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+#ifdef HAVE_ELEMENTARY_WEB
+ Widget_Data *wd = elm_widget_data_get(obj);
+ float tz;
+ if (mode >= ELM_WEB_ZOOM_MODE_LAST)
+ return;
+ if (mode == wd->zoom.mode)
+ return;
+ wd->zoom.mode = mode;
+ tz = wd->zoom.current;
+ wd->zoom.current = 0.0;
+ elm_web_zoom_set(obj, tz);
+#else
+ (void)mode;
+#endif
+}
+
+EAPI Elm_Web_Zoom_Mode
+elm_web_zoom_mode_get(const Evas_Object *obj)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype) ELM_WEB_ZOOM_MODE_LAST;
+#ifdef HAVE_ELEMENTARY_WEB
+ Widget_Data *wd = elm_widget_data_get(obj);
+ return wd->zoom.mode;
+#else
+ return ELM_WEB_ZOOM_MODE_LAST;
+#endif
+}
+
EAPI Eina_Bool
elm_web_zoom_text_only_get(const Evas_Object *obj)
{
}
EAPI void
+elm_web_region_show(Evas_Object *obj, int x, int y, int w __UNUSED__, int h __UNUSED__)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+#ifdef HAVE_ELEMENTARY_WEB
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Evas_Object *frame = ewk_view_frame_main_get(wd->ewk_view);
+ int fw, fh, zw, zh, rx, ry;
+ float zoom;
+ ewk_frame_contents_size_get(frame, &fw, &fh);
+ zoom = ewk_frame_zoom_get(frame);
+ zw = fw / zoom;
+ zh = fh / zoom;
+ rx = (x * fw) / zw;
+ ry = (y * fh) / zh;
+ if (wd->bring_in.animator)
+ {
+ ecore_animator_del(wd->bring_in.animator);
+ wd->bring_in.animator = NULL;
+ }
+ ewk_frame_scroll_set(frame, rx, ry);
+#else
+ (void)x;
+ (void)y;
+#endif
+}
+
+EAPI void
+elm_web_region_bring_in(Evas_Object *obj, int x, int y, int w __UNUSED__, int h __UNUSED__)
+{
+ ELM_CHECK_WIDTYPE(obj, widtype);
+#ifdef HAVE_ELEMENTARY_WEB
+ Widget_Data *wd = elm_widget_data_get(obj);
+ Evas_Object *frame = ewk_view_frame_main_get(wd->ewk_view);
+ int fw, fh, zw, zh, rx, ry, sx, sy;
+ float zoom;
+ ewk_frame_contents_size_get(frame, &fw, &fh);
+ ewk_frame_scroll_pos_get(frame, &sx, &sy);
+ zoom = ewk_frame_zoom_get(frame);
+ zw = fw / zoom;
+ zh = fh / zoom;
+ rx = (x * fw) / zw;
+ ry = (y * fh) / zh;
+ if ((wd->bring_in.end.x == rx) && (wd->bring_in.end.y == ry))
+ return;
+ wd->bring_in.start.x = sx;
+ wd->bring_in.start.y = sy;
+ wd->bring_in.end.x = rx;
+ wd->bring_in.end.y = ry;
+ if (wd->bring_in.animator)
+ ecore_animator_del(wd->bring_in.animator);
+ wd->bring_in.animator = ecore_animator_timeline_add(
+ _elm_config->bring_in_scroll_friction, _bring_in_anim_cb, wd);
+#else
+ (void)x;
+ (void)y;
+#endif
+}
+
+EAPI void
elm_web_inwin_mode_set(Evas_Object *obj, Eina_Bool value)
{
ELM_CHECK_WIDTYPE(obj, widtype);