panel: add scrollable feature

This implements scrollable interface in elm_panel so that users can drag open/close panel.
Tap & hold on the edge and panel handler will appear.

Left scrollable panel is implemented in elementary_test > Panel Scrollable.

@feature
This commit is contained in:
Jaeun Choi 2014-06-25 23:43:18 +09:00
parent e2db16a8af
commit 3003957af8
8 changed files with 1432 additions and 27 deletions

View File

@ -1,3 +1,384 @@
group { name: "elm/scroller/panel/default";
data {
item: "handler_size" "30";
}
parts {
part { name: "elm.swallow.content";
type: SWALLOW;
description { state: "default" 0.0;
}
}
}
}
group { name: "elm/scroller/panel/left/default";
parts {
part { name: "panel_area";
type: SWALLOW;
description { state: "default" 0.0;
rel2.relative: 0.0 1.0;
align: 0.0 0.5;
fixed: 1 1;
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "event_area";
type: SWALLOW;
description { state: "default" 0.0;
rel1 {
relative: 1.0 0.0;
to: "panel_area";
}
rel2 {
relative: 1.0 1.0;
to: "panel_area";
}
align: 0.0 0.5;
fixed: 1 1;
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "access.outline";
type: RECT;
repeat_events: 1;
description { state: "default" 0.0;
rel1.to: "panel_area";
rel2.to: "panel_area";
color: 0 0 0 0;
}
}
part { name: "bg";
type: RECT;
description { state: "default" 0.0;
rel1.to: "panel_area";
rel2.to: "panel_area";
color: 64 64 64 255;
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "elm.swallow.content";
type: SWALLOW;
description { state: "default" 0.0;
rel1.to: "panel_area";
rel2.to: "panel_area";
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
}
programs {
program { name: "active";
signal: "elm,state,content,visible";
source: "elm";
action: STATE_SET "visible" 0.0;
target: "panel_area";
target: "event_area";
target: "bg";
target: "elm.swallow.content";
}
program { name: "inactive";
signal: "elm,state,content,hidden";
source: "elm";
action: STATE_SET "default" 0.0;
target: "panel_area";
target: "event_area";
target: "bg";
target: "elm.swallow.content";
}
}
}
group { name: "elm/scroller/panel/right/default";
parts {
part { name: "event_area";
type: SWALLOW;
description { state: "default" 0.0;
rel2.relative: 0.0 1.0;
align: 0.0 0.5;
fixed: 1 1;
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "panel_area";
type: SWALLOW;
description { state: "default" 0.0;
rel1 {
relative: 1.0 0.0;
to: "event_area";
}
rel2 {
relative: 1.0 1.0;
to: "event_area";
}
align: 0.0 0.5;
fixed: 1 1;
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "access.outline";
type: RECT;
repeat_events: 1;
description { state: "default" 0.0;
rel1.to: "panel_area";
rel2.to: "panel_area";
color: 0 0 0 0;
}
}
part { name: "bg";
type: RECT;
description { state: "default" 0.0;
rel1.to: "panel_area";
rel2.to: "panel_area";
color: 64 64 64 255;
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "elm.swallow.content";
type: SWALLOW;
description { state: "default" 0.0;
rel1.to: "panel_area";
rel2.to: "panel_area";
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
}
programs {
program { name: "active";
signal: "elm,state,content,visible";
source: "elm";
action: STATE_SET "visible" 0.0;
target: "panel_area";
target: "event_area";
target: "bg";
target: "elm.swallow.content";
}
program { name: "inactive";
signal: "elm,state,content,hidden";
source: "elm";
action: STATE_SET "default" 0.0;
target: "panel_area";
target: "event_area";
target: "bg";
target: "elm.swallow.content";
}
}
}
group { name: "elm/scroller/panel/top/default";
parts {
part { name: "panel_area";
type: SWALLOW;
description { state: "default" 0.0;
rel2.relative: 1.0 0.0;
align: 0.5 0.0;
fixed: 1 1;
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "event_area";
type: SWALLOW;
description { state: "default" 0.0;
rel1 {
relative: 0.0 1.0;
to: "panel_area";
}
rel2 {
relative: 1.0 1.0;
to: "panel_area";
}
align: 0.5 0.0;
fixed: 1 1;
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "access.outline";
type: RECT;
repeat_events: 1;
description { state: "default" 0.0;
rel1.to: "panel_area";
rel2.to: "panel_area";
color: 0 0 0 0;
}
}
part { name: "bg";
type: RECT;
description { state: "default" 0.0;
rel1.to: "panel_area";
rel2.to: "panel_area";
color: 64 64 64 255;
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "elm.swallow.content";
type: SWALLOW;
description { state: "default" 0.0;
rel1.to: "panel_area";
rel2.to: "panel_area";
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
}
programs {
program { name: "active";
signal: "elm,state,content,visible";
source: "elm";
action: STATE_SET "visible" 0.0;
target: "panel_area";
target: "event_area";
target: "bg";
target: "elm.swallow.content";
}
program { name: "inactive";
signal: "elm,state,content,hidden";
source: "elm";
action: STATE_SET "default" 0.0;
target: "panel_area";
target: "event_area";
target: "bg";
target: "elm.swallow.content";
}
}
}
group { name: "elm/scroller/panel/bottom/default";
parts {
part { name: "event_area";
type: SWALLOW;
description { state: "default" 0.0;
rel2.relative: 1.0 0.0;
align: 0.5 0.0;
fixed: 1 1;
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "panel_area";
type: SWALLOW;
description { state: "default" 0.0;
rel1 {
relative: 0.0 1.0;
to: "event_area";
}
rel2 {
relative: 1.0 1.0;
to: "event_area";
}
align: 0.5 0.0;
fixed: 1 1;
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "access.outline";
type: RECT;
repeat_events: 1;
description { state: "default" 0.0;
rel1.to: "panel_area";
rel2.to: "panel_area";
color: 0 0 0 0;
}
}
part { name: "bg";
type: RECT;
description { state: "default" 0.0;
rel1.to: "panel_area";
rel2.to: "panel_area";
color: 64 64 64 255;
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
part { name: "elm.swallow.content";
type: SWALLOW;
description { state: "default" 0.0;
rel1.to: "panel_area";
rel2.to: "panel_area";
visible: 0;
}
description { state: "visible" 0.0;
inherit: "default" 0.0;
visible: 1;
}
}
}
programs {
program { name: "active";
signal: "elm,state,content,visible";
source: "elm";
action: STATE_SET "visible" 0.0;
target: "panel_area";
target: "event_area";
target: "bg";
target: "elm.swallow.content";
}
program { name: "inactive";
signal: "elm,state,content,hidden";
source: "elm";
action: STATE_SET "default" 0.0;
target: "panel_area";
target: "event_area";
target: "bg";
target: "elm.swallow.content";
}
}
}
group { name: "elm/panel/left/default";
images.image: "bevel_out.png" COMP;
images.image: "shine.png" COMP;

View File

@ -158,6 +158,7 @@ void test_slideshow(void *data, Evas_Object *obj, void *event_info);
void test_menu(void *data, Evas_Object *obj, void *event_info);
void test_menu2(void *data, Evas_Object *obj, void *event_info);
void test_panel(void *data, Evas_Object *obj, void *event_info);
void test_panel2(void *data, Evas_Object *obj, void *event_info);
void test_panes(void *data, Evas_Object *obj, void *event_info);
void test_calendar(void *data, Evas_Object *obj, void *event_info);
void test_calendar2(void *data, Evas_Object *obj, void *event_info);
@ -785,6 +786,7 @@ add_tests:
//------------------------------//
ADD_TEST(NULL, "Dividers", "Panel", test_panel);
ADD_TEST(NULL, "Dividers", "Panel Scrollable", test_panel2);
ADD_TEST(NULL, "Dividers", "Panes", test_panes);
//------------------------------//

View File

@ -270,3 +270,76 @@ test_panel(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_inf
evas_object_resize(win, 320, 400);
evas_object_show(win);
}
static void
_clicked_cb(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
Evas_Object *panel = data;
elm_panel_toggle(panel);
}
void
test_panel2(void *data EINA_UNUSED,
Evas_Object *obj EINA_UNUSED,
void *event_info EINA_UNUSED)
{
Evas_Object *win, *box, *table, *panel, *list, *button;
int i;
// Left Panel
win = elm_win_util_standard_add("panel", "Left Panel");
elm_win_autodel_set(win, EINA_TRUE);
evas_object_resize(win, 320, 400);
evas_object_show(win);
// box for button and table
box = elm_box_add(win);
evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_show(box);
elm_win_resize_object_add(win, box);
// toggle button
button = elm_button_add(box);
evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, 0);
evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(button);
elm_object_text_set(button, "Toggle");
elm_box_pack_end(box, button);
// table for panel and center content
table = elm_table_add(win);
evas_object_size_hint_weight_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(table, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(table);
elm_box_pack_end(box, table);
// center content
list = elm_list_add(table);
evas_object_size_hint_weight_set(list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(list, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(list);
for (i = 0; i < 20; i++)
elm_list_item_append(list, "center list item", NULL, NULL, NULL, NULL);
elm_table_pack(table, list, 0, 0, 1, 1);
// panel
panel = elm_panel_add(table);
evas_object_size_hint_weight_set(panel, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(panel, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(panel);
elm_table_pack(table, panel, 0, 0, 1, 1);
elm_panel_scrollable_set(panel, EINA_TRUE);
elm_panel_orient_set(panel, ELM_PANEL_ORIENT_LEFT);
elm_panel_hidden_set(panel, EINA_TRUE);
elm_panel_scrollable_content_size_set(panel, 0.75);
list = elm_list_add(panel);
evas_object_size_hint_weight_set(list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(list, EVAS_HINT_FILL, EVAS_HINT_FILL);
for (i = 0; i < 7; i++)
elm_list_item_append(list, "panel list item", NULL, NULL, NULL, NULL);
elm_object_content_set(panel, list);
evas_object_smart_callback_add(button, "clicked", _clicked_cb, panel);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
class Elm_Panel (Elm_Layout)
class Elm_Panel (Elm_Layout, Elm_Interface_Scrollable)
{
eo_prefix: elm_obj_panel;
properties {
@ -45,6 +45,28 @@ class Elm_Panel (Elm_Layout)
Eina_Bool hidden; /*@ If true, the panel will run the animation to disappear. */
}
}
scrollable {
set {
/*@
@brief Set the scrollability of the panel.
@ingroup Panel */
}
values {
Eina_Bool scrollable;
}
}
scrollable_content_size {
set {
/*@
@brief Set the size of the scrollable panel.
@ingroup Panel */
}
values {
double ratio;
}
}
}
methods {
toggle {
@ -59,12 +81,17 @@ class Elm_Panel (Elm_Layout)
class.constructor;
Eo_Base.constructor;
Evas_Object_Smart.add;
Evas_Object_Smart.member_add;
Evas_Object_Smart.del;
Evas_Object_Smart.resize;
Evas_Object_Smart.move;
Elm_Widget.theme_apply;
Elm_Widget.focus_next_manager_is;
Elm_Widget.focus_next;
Elm_Widget.disable;
Elm_Widget.access;
Elm_Widget.event;
Elm_Widget.on_focus_region;
Elm_Container.content_get;
Elm_Container.content_unset;
Elm_Container.content_set;

View File

@ -23,6 +23,9 @@
*
* This widget emits the following signals, besides the ones sent from
* @ref Layout:
* @li @c "scroll" : When the content has been scrolled (moved). (since 1.10)
* This signal is emitted only when the panel is scrollable.
* Elm_Panel_Scroll_Info will be passed by @c event_info argument.
* @li @c "focused" : When the panel has received focus. (since 1.8)
* @li @c "unfocused" : When the panel has lost focus. (since 1.8)
*

View File

@ -6,3 +6,9 @@ typedef enum
ELM_PANEL_ORIENT_RIGHT, /**< Panel (dis)appears from the right */
} Elm_Panel_Orient;
typedef struct _Elm_Panel_Scroll_Info
{
double rel_x; /**<content scrolled position (0.0 ~ 1.0) in the panel>*/
double rel_y; /**<content scrolled position (0.0 ~ 1.0) in the panel>*/
} Elm_Panel_Scroll_Info;

View File

@ -1,6 +1,7 @@
#ifndef ELM_WIDGET_PANEL_H
#define ELM_WIDGET_PANEL_H
#include "elm_interface_scrollable.h"
#include "elm_widget_layout.h"
/**
@ -22,11 +23,22 @@ struct _Elm_Panel_Data
{
Evas_Object *bx, *content;
Evas_Object *event;
Evas_Object *scr_ly;
Evas_Object *hit_rect, *panel_edje, *scr_edje;
Evas_Object *scr_panel, *scr_event;
Elm_Panel_Orient orient;
double content_size_ratio;
Evas_Coord down_x, down_y;
Evas_Coord handler_size;
Ecore_Timer *timer;
Eina_Bool hidden : 1;
Eina_Bool delete_me : 1;
Eina_Bool scrollable : 1;
Eina_Bool freeze: 1;
};
/**