editable textblocks... a start (definitely not there yet)

SVN revision: 36611
This commit is contained in:
Carsten Haitzler 2008-10-13 09:19:04 +00:00
parent c30004b6c9
commit ce0d40cae7
9 changed files with 780 additions and 23 deletions

View File

@ -91,10 +91,15 @@ static void st_collections_group_parts_part_precise_is_inside(void);
static void st_collections_group_parts_part_use_alternate_font_metrics(void);
static void st_collections_group_parts_part_clip_to_id(void);
static void st_collections_group_parts_part_source(void);
static void st_collections_group_parts_part_source2(void);
static void st_collections_group_parts_part_source3(void);
static void st_collections_group_parts_part_source4(void);
static void st_collections_group_parts_part_dragable_x(void);
static void st_collections_group_parts_part_dragable_y(void);
static void st_collections_group_parts_part_dragable_confine(void);
static void st_collections_group_parts_part_dragable_events(void);
static void st_collections_group_parts_part_entry_mode(void);
static void st_collections_group_parts_part_multiline(void);
static void ob_collections_group_parts_part_description(void);
static void st_collections_group_parts_part_description_inherit(void);
@ -233,10 +238,15 @@ New_Statement_Handler statement_handlers[] =
{"collections.group.parts.part.use_alternate_font_metrics", st_collections_group_parts_part_use_alternate_font_metrics},
{"collections.group.parts.part.clip_to", st_collections_group_parts_part_clip_to_id},
{"collections.group.parts.part.source", st_collections_group_parts_part_source},
{"collections.group.parts.part.source2", st_collections_group_parts_part_source2},
{"collections.group.parts.part.source3", st_collections_group_parts_part_source3},
{"collections.group.parts.part.source4", st_collections_group_parts_part_source4},
{"collections.group.parts.part.dragable.x", st_collections_group_parts_part_dragable_x},
{"collections.group.parts.part.dragable.y", st_collections_group_parts_part_dragable_y},
{"collections.group.parts.part.dragable.confine", st_collections_group_parts_part_dragable_confine},
{"collections.group.parts.part.dragable.events", st_collections_group_parts_part_dragable_events},
{"collections.group.parts.part.entry_mode", st_collections_group_parts_part_entry_mode},
{"collections.group.parts.part.multiline", st_collections_group_parts_part_multiline},
{"collections.group.parts.part.image", st_images_image}, /* dup */
{"collections.group.parts.part.images.image", st_images_image}, /* dup */
{"collections.group.parts.part.font", st_fonts_font}, /* dup */
@ -1797,8 +1807,11 @@ st_collections_group_parts_part_clip_to_id(void)
@parameters
[another group's name]
@effect
Only available to GROUP parts. Swallows the specified group into the
part's container.
Only available to GROUP or TEXTBLOCK parts. Swallows the specified
group into the part's container if a GROUP. If TEXTBLOCK it is used
for the group to be loaded and used for selection display UNDER the
selected text. source2 is used for on top of the selected text, if
source2 is specified.
@endproperty
*/
static void
@ -1812,18 +1825,91 @@ st_collections_group_parts_part_source(void)
pc = evas_list_data(evas_list_last(edje_collections));
ep = evas_list_data(evas_list_last(pc->parts));
if (ep->type != EDJE_PART_TYPE_GROUP)
{
fprintf(stderr, "%s: Error. parse error %s:%i. "
"source attribute in non-GROUP part.\n",
progname, file_in, line - 1);
exit(-1);
}
//XXX validate this somehow (need to decide on the format also)
//FIXME: validate this somehow (need to decide on the format also)
ep->source = parse_str(0);
}
/**
@page edcref
@property
source2
@parameters
[another group's name]
@effect
Only available to TEXTBLOCK parts. It is used for the group to be
loaded and used for selection display OVER the selected text. source
is used for under of the selected text, if source is specified.
@endproperty
*/
static void
st_collections_group_parts_part_source2(void)
{
Edje_Part_Collection *pc;
Edje_Part *ep;
check_arg_count(1);
pc = evas_list_data(evas_list_last(edje_collections));
ep = evas_list_data(evas_list_last(pc->parts));
//FIXME: validate this somehow (need to decide on the format also)
ep->source2 = parse_str(0);
}
/**
@page edcref
@property
source3
@parameters
[another group's name]
@effect
Only available to TEXTBLOCK parts. It is used for the group to be
loaded and used for cursor display UNDER the cursor position. source4
is used for over the cursor text, if source4 is specified.
@endproperty
*/
static void
st_collections_group_parts_part_source3(void)
{
Edje_Part_Collection *pc;
Edje_Part *ep;
check_arg_count(1);
pc = evas_list_data(evas_list_last(edje_collections));
ep = evas_list_data(evas_list_last(pc->parts));
//FIXME: validate this somehow (need to decide on the format also)
ep->source3 = parse_str(0);
}
/**
@page edcref
@property
source4
@parameters
[another group's name]
@effect
Only available to TEXTBLOCK parts. It is used for the group to be
loaded and used for cursor display OVER the cursor position. source3
is used for under the cursor text, if source4 is specified.
@endproperty
*/
static void
st_collections_group_parts_part_source4(void)
{
Edje_Part_Collection *pc;
Edje_Part *ep;
check_arg_count(1);
pc = evas_list_data(evas_list_last(edje_collections));
ep = evas_list_data(evas_list_last(pc->parts));
//FIXME: validate this somehow (need to decide on the format also)
ep->source4 = parse_str(0);
}
/**
@page edcref
@ -2013,6 +2099,66 @@ st_collections_group_parts_part_dragable_events(void)
}
}
/**
@page edcref
@property
entry_mode
@parameters
Sets the edit mode for a textblock part to one of:
@li NONE
@li SELECTABLE
@li EDITABLE
@li PASSWORD
@effect
It causes the part be editable if the edje object has the keyboard
focus AND the part has the edje focus (or selectable always
regardless of focus) and in the event of password mode, not
selectable and all text chars replaced with *'s but editable and
pastable.
@endproperty
*/
static void
st_collections_group_parts_part_entry_mode(void)
{
Edje_Part_Collection *pc;
Edje_Part *ep;
check_arg_count(1);
pc = evas_list_data(evas_list_last(edje_collections));
ep = evas_list_data(evas_list_last(pc->parts));
ep->entry_mode = parse_enum(0,
"NONE", EDJE_ENTRY_EDIT_MODE_NONE,
"PLAIN", EDJE_ENTRY_EDIT_MODE_SELECTABLE,
"EDITABLE", EDJE_ENTRY_EDIT_MODE_EDITABLE,
"PASSOWRD", EDJE_ENTRY_EDIT_MODE_PASSWORD,
NULL);
}
/**
@page edcref
@property
multiline
@parameters
0 or 1 (boolean) off/on
@effect
It causes a textblock that is editable to allow multiple lines for
editing.
@endproperty
*/
static void
st_collections_group_parts_part_multiline(void)
{
Edje_Part_Collection *pc;
Edje_Part *ep;
check_arg_count(1);
pc = evas_list_data(evas_list_last(edje_collections));
ep = evas_list_data(evas_list_last(pc->parts));
ep->multiline = parse_bool(0);
}
/**
@page edcref
@block
@ -4400,7 +4546,8 @@ st_collections_group_programs_program_in(void)
[type] [param1] [param2]
@effect
Action to be performed by the program. Valid actions are: STATE_SET,
ACTION_STOP, SIGNAL_EMIT, DRAG_VAL_SET, DRAG_VAL_STEP and DRAG_VAL_PAGE.
ACTION_STOP, SIGNAL_EMIT, DRAG_VAL_SET, DRAG_VAL_STEP, DRAG_VAL_PAGE,
FOCUS_SET.
Only one action can be specified per program. Examples:\n
action: STATE_SET "statename" 0.5;\n
action: ACTION_STOP "programname";\n
@ -4423,6 +4570,7 @@ st_collections_group_programs_program_action(void)
"DRAG_VAL_STEP", EDJE_ACTION_TYPE_DRAG_VAL_STEP,
"DRAG_VAL_PAGE", EDJE_ACTION_TYPE_DRAG_VAL_PAGE,
"SCRIPT", EDJE_ACTION_TYPE_SCRIPT,
"FOCUS_SET", EDJE_ACTION_TYPE_FOCUS_SET,
NULL);
if (ep->action == EDJE_ACTION_TYPE_STATE_SET)
{
@ -4449,17 +4597,22 @@ st_collections_group_programs_program_action(void)
ep->value = parse_float(1);
ep->value2 = parse_float(2);
}
switch (ep->action) {
switch (ep->action)
{
case EDJE_ACTION_TYPE_ACTION_STOP:
check_arg_count(1);
break;
check_arg_count(1);
break;
case EDJE_ACTION_TYPE_SCRIPT:
/* FIXME: what's this? people usually just use script{}, no? */
break;
/* this is implicitly set by script {} so this is here just for
* completeness */
break;
case EDJE_ACTION_TYPE_FOCUS_SET:
check_arg_count(1);
break;
default:
check_arg_count(3);
}
check_arg_count(3);
}
}
/**
@ -4534,6 +4687,8 @@ st_collections_group_programs_program_target(void)
data_queue_part_lookup(pc, name, &(et->id));
else if (ep->action == EDJE_ACTION_TYPE_DRAG_VAL_PAGE)
data_queue_part_lookup(pc, name, &(et->id));
else if (ep->action == EDJE_ACTION_TYPE_FOCUS_SET)
data_queue_part_lookup(pc, name, &(et->id));
else
{
fprintf(stderr, "%s: Error. parse error %s:%i. "

View File

@ -40,7 +40,8 @@ edje_cache.c \
edje_match.c \
edje_textblock_styles.c \
edje_edit.c \
edje_script_only.c
edje_script_only.c \
edje_entry.c
libedje_la_CFLAGS = @WIN32_CFLAGS@
libedje_la_LIBADD = @EDJE_LIBS@ -lm

View File

@ -1533,6 +1533,8 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags)
/* visibility and color have no meaning on SWALLOW and GROUP part. */
evas_object_move(ep->object, ed->x + pf->x, ed->y + pf->y);
evas_object_resize(ep->object, pf->w, pf->h);
if (ep->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
_edje_entry_real_part_configure(ep);
break;
case EDJE_PART_TYPE_TEXT:
/* This is correctly handle in _edje_text_recalc_apply at the moment. */

View File

@ -377,7 +377,12 @@ _edje_edd_setup(void)
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "dragable.count_y", dragable.count_y, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "dragable.counfine_id", dragable.confine_id, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "dragable.events_id", dragable.events_id, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "entry_mode", entry_mode, EET_T_UCHAR);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "multiline", multiline, EET_T_UCHAR);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "source", source, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "source2", source2, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "source3", source3, EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part, Edje_Part, "source4", source4, EET_T_STRING);
NEWD("Edje_Part_Collection",
Edje_Part_Collection);

View File

@ -0,0 +1,535 @@
/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#include "edje_private.h"
typedef struct _Entry Entry;
struct _Entry
{
Evas_Coord cx, cy;
Evas_Object *cursor_bg;
Evas_Object *cursor_fg;
Evas_Textblock_Cursor *cursor;
Evas_Textblock_Cursor *sel_start, *sel_end;
Evas_List *sel;
Evas_Bool have_selection : 1;
};
// FIXME: this has to emit signals for "request selection", "set selection"
// so copy & paste work, need api calls to insert text, insert format,
// get text (with markup) delete text, etc. etc. etc.
//
// FIXME: cursor when at end of text doesnt display right
static void
_edje_focus_in_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
Edje *ed = data;
_edje_emit(ed, "focus,in", "");
}
static void
_edje_focus_out_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
Edje *ed = data;
_edje_emit(ed, "focus,out", "");
}
static void
_edje_key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
Edje *ed = data;
Evas_Event_Key_Down *ev = event_info;
Edje_Real_Part *rp = ed->focused_part;
Entry *en = rp->entry_data;
Evas_Bool control, alt, shift;
if ((!rp) || (!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
return;
if (!ev->key) return;
printf("editable: '%s' '%s' '%s'\n", ev->key, ev->string, ev->compose);
control = evas_key_modifier_is_set(ev->modifiers, "Control");
alt = evas_key_modifier_is_set(ev->modifiers, "Alt");
shift = evas_key_modifier_is_set(ev->modifiers, "Shift");
if (!strcmp(ev->key, "Escape"))
{
// dead keys here. Escape for now (shoudl emit these)
}
else if (!strcmp(ev->key, "Up"))
{
Evas_Coord lx, ly, lw, lh, cx, cy, cw, ch;
int line_num;
if (shift)
{
// if no selection, start one
}
line_num = evas_textblock_cursor_line_geometry_get(en->cursor, NULL, NULL, NULL, NULL);
line_num--;
if (evas_object_textblock_line_number_geometry_get(rp->object, line_num, &lx, &ly, &lw, &lh))
{
evas_textblock_cursor_char_geometry_get(en->cursor, &cx, &cy, &cw, &ch);
evas_textblock_cursor_char_coord_set(en->cursor, cx + (cw / 2), ly + (lh / 2));
}
if (shift)
{
// also extend selection
}
}
else if (!strcmp(ev->key, "Down"))
{
Evas_Coord lx, ly, lw, lh, cx, cy, cw, ch;
int line_num;
if (shift)
{
// if no selection, start one
}
line_num = evas_textblock_cursor_line_geometry_get(en->cursor, NULL, NULL, NULL, NULL);
line_num++;
if (evas_object_textblock_line_number_geometry_get(rp->object, line_num, &lx, &ly, &lw, &lh))
{
evas_textblock_cursor_char_geometry_get(en->cursor, &cx, &cy, &cw, &ch);
evas_textblock_cursor_char_coord_set(en->cursor, cx + (cw / 2), ly + (lh / 2));
}
if (shift)
{
// also extend selection
}
}
else if (!strcmp(ev->key, "Left"))
{
if (shift)
{
// if no selection, start one
}
if (!evas_textblock_cursor_char_prev(en->cursor))
{
evas_textblock_cursor_node_prev(en->cursor);
}
if (shift)
{
// also extend selection
}
}
else if (!strcmp(ev->key, "Right"))
{
if (shift)
{
// if no selection, start one
}
if (!evas_textblock_cursor_char_next(en->cursor))
{
evas_textblock_cursor_node_next(en->cursor);
}
if (shift)
{
// also extend selection
}
}
else if (!strcmp(ev->key, "BackSpace"))
{
if (control)
{
// if ctrl pressed del to start of previois word
}
else if ((alt) && (shift))
{
// FIXME: undo last action
}
else
{
if ((en->sel_start) && (en->sel_end) && (en->have_selection))
{
evas_textblock_cursor_range_delete(en->sel_start, en->sel_end);
}
else
{
evas_textblock_cursor_node_prev(en->cursor);
evas_textblock_cursor_char_delete(en->cursor);
}
}
if ((en->sel_start) && (en->sel_end))
{
// FIXME: func
evas_textblock_cursor_free(en->sel_start);
en->sel_start = NULL;
evas_textblock_cursor_free(en->sel_end);
en->sel_end = NULL;
}
}
else if (!strcmp(ev->key, "Delete"))
{
if (control)
{
// if ctrl pressed del to end of next word
}
else if (shift)
{
// cut
}
else
{
if ((en->sel_start) && (en->sel_end) && (en->have_selection))
{
evas_textblock_cursor_range_delete(en->sel_start, en->sel_end);
}
else
{
evas_textblock_cursor_char_delete(en->cursor);
}
}
if ((en->sel_start) && (en->sel_end))
{
// FIXME: func
evas_textblock_cursor_free(en->sel_start);
en->sel_start = NULL;
evas_textblock_cursor_free(en->sel_end);
en->sel_end = NULL;
}
}
else if (!strcmp(ev->key, "Home"))
{
if (shift)
{
// if no selection, start one
}
if (control)
{
// goto start of text
}
else
{
evas_textblock_cursor_line_first(en->cursor);
}
if (shift)
{
// also extend selection
}
}
else if (!strcmp(ev->key, "End"))
{
if (shift)
{
// if no selection, start one
}
if (control)
{
// goto end of text
}
else
{
evas_textblock_cursor_line_last(en->cursor);
}
if (shift)
{
// also extend selection
}
}
else if ((control) && (!strcmp(ev->key, "v")))
{
// paste
}
else if ((control) && ((!strcmp(ev->key, "c") || (!strcmp(ev->key, "Insert")))))
{
// copy
}
else if ((control) && ((!strcmp(ev->key, "x") || (!strcmp(ev->key, "m")))))
{
// cut
}
else if ((control) && (!strcmp(ev->key, "z")))
{
if (shift)
{
// FIXME: redo
}
else
{
// FIXME: undo
}
}
else if ((control) && (!strcmp(ev->key, "y")))
{
// FIXME: redo
}
else if ((control) && (!strcmp(ev->key, "w")))
{
// select current word
}
else if (!strcmp(ev->key, "Tab"))
{
if (shift)
{
// remove a tab
}
else
{
// add a tab
}
}
else if (!strcmp(ev->key, "ISO_Left_Tab"))
{
// remove a tab
}
else if (!strcmp(ev->key, "Prior"))
{
// pgup
}
else if (!strcmp(ev->key, "Next"))
{
// pgdn
}
else if ((!strcmp(ev->key, "Return")) || (!strcmp(ev->key, "KP_Enter")))
{
// newline
}
else if ((!strcmp(ev->key, "Multi_key")))
{
// FIXME: compose next 2 keystrokes (Examples):
// a " -> ä
// o / -> ø
// a e -> æ
// e ' -> é
// s s -> ß
// etc.
}
// FIXME: other input methods? (xim, scim, uim etc.)...
else
{
// FIXME: if composing.. store 2 keys
if (ev->string)
evas_textblock_cursor_text_prepend(en->cursor, ev->string);
}
_edje_entry_real_part_configure(rp);
}
static void
_edje_key_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
Edje *ed = data;
Evas_Event_Key_Up *ev = event_info;
Edje_Real_Part *rp = ed->focused_part;
Entry *en = rp->entry_data;
if ((!rp) || (!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
return;
}
static void
_edje_part_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
Edje_Real_Part *rp = data;
Evas_Event_Mouse_Down *ev = event_info;
Entry *en = rp->entry_data;
Evas_Coord x, y, w, h;
if ((!rp) || (!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
return;
evas_object_geometry_get(rp->object, &x, &y, &w, &h);
en->cx = ev->canvas.x - x;
en->cy = ev->canvas.y - y;
if (!evas_textblock_cursor_char_coord_set(en->cursor, en->cx, en->cy))
{
Evas_Coord lx, ly, lw, lh;
evas_textblock_cursor_line_coord_set(en->cursor, en->cy);
evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
if (en->cx <= lx)
evas_textblock_cursor_line_first(en->cursor);
else
evas_textblock_cursor_line_last(en->cursor);
}
en->sel_start = evas_object_textblock_cursor_new(rp->object);
evas_textblock_cursor_copy(en->cursor, en->sel_start);
en->sel_end = evas_object_textblock_cursor_new(rp->object);
evas_textblock_cursor_copy(en->cursor, en->sel_start);
en->have_selection = 0;
while (en->sel)
{
evas_object_del(en->sel->data);
en->sel = evas_list_remove_list(en->sel, en->sel);
}
// FIXME: emit "selection cleared"
_edje_entry_real_part_configure(rp);
}
static void
_edje_part_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
Edje_Real_Part *rp = data;
Evas_Event_Mouse_Up *ev = event_info;
Entry *en = rp->entry_data;
Evas_Coord x, y, w, h;
if ((!rp) || (!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
return;
evas_object_geometry_get(rp->object, &x, &y, &w, &h);
en->cx = ev->canvas.x - x;
en->cy = ev->canvas.y - y;
if (!evas_textblock_cursor_char_coord_set(en->cursor, en->cx, en->cy))
{
Evas_Coord lx, ly, lw, lh;
evas_textblock_cursor_line_coord_set(en->cursor, en->cy);
evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
if (en->cx <= lx)
evas_textblock_cursor_line_first(en->cursor);
else
evas_textblock_cursor_line_last(en->cursor);
}
evas_textblock_cursor_copy(en->cursor, en->sel_end);
// FIXME: emit "selection ended"
evas_textblock_cursor_free(en->sel_start);
en->sel_start = NULL;
evas_textblock_cursor_free(en->sel_end);
en->sel_end = NULL;
_edje_entry_real_part_configure(rp);
}
static void
_edje_part_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
Edje_Real_Part *rp = data;
Evas_Event_Mouse_Move *ev = event_info;
Entry *en = rp->entry_data;
Evas_Coord x, y, w, h;
if ((!rp) || (!en) || (rp->part->type != EDJE_PART_TYPE_TEXTBLOCK) ||
(rp->part->entry_mode < EDJE_ENTRY_EDIT_MODE_EDITABLE))
return;
if (!en->sel_start) return;
evas_object_geometry_get(rp->object, &x, &y, &w, &h);
en->cx = ev->cur.canvas.x - x;
en->cy = ev->cur.canvas.y - y;
if (!evas_textblock_cursor_char_coord_set(en->cursor, en->cx, en->cy))
{
Evas_Coord lx, ly, lw, lh;
evas_textblock_cursor_line_coord_set(en->cursor, en->cy);
evas_textblock_cursor_line_geometry_get(en->cursor, &lx, &ly, &lw, &lh);
if (en->cx <= lx)
evas_textblock_cursor_line_first(en->cursor);
else
evas_textblock_cursor_line_last(en->cursor);
}
evas_textblock_cursor_copy(en->cursor, en->sel_end);
if (evas_textblock_cursor_compare(en->sel_start, en->sel_end) != 0)
{
en->have_selection = 1;
// FIXME: emit "selection started"
}
if (en->have_selection)
{
Evas_List *range;
printf("update sel\n");
range = evas_textblock_cursor_range_geometry_get(en->sel_start, en->sel_end);
while (en->sel)
{
evas_object_del(en->sel->data);
en->sel = evas_list_remove_list(en->sel, en->sel);
}
while (range)
{
Evas_Textblock_Rectangle *r;
Evas_Object *o;
r = range->data;
o = evas_object_rectangle_add(evas_object_evas_get(rp->object));
evas_object_smart_member_add(o, rp->edje->obj);
evas_object_stack_below(o, rp->object);
evas_object_clip_set(o, evas_object_clip_get(rp->object));
evas_object_color_set(o, 20, 20, 255, 150);
evas_object_pass_events_set(o, 1);
evas_object_show(o);
evas_object_move(o, x + r->x, y + r->y);
evas_object_resize(o, r->w, r->h);
en->sel = evas_list_append(en->sel, o);
range = evas_list_remove_list(range, range);
free(r);
}
// FIXME: emit "selection changed"
}
_edje_entry_real_part_configure(rp);
}
/***************************************************************/
void
_edje_entry_init(Edje *ed)
{
evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_FOCUS_IN, _edje_focus_in_cb, ed);
evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_FOCUS_OUT, _edje_focus_out_cb, ed);
evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_KEY_DOWN, _edje_key_down_cb, ed);
evas_object_event_callback_add(ed->obj, EVAS_CALLBACK_KEY_UP, _edje_key_up_cb, ed);
}
void
_edje_entry_shutdown(Edje *ed)
{
}
void
_edje_entry_real_part_init(Edje_Real_Part *rp)
{
Entry *en;
en = calloc(1, sizeof(Entry));
if (!en) return;
rp->entry_data = en;
evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_DOWN, _edje_part_mouse_down_cb, rp);
evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_UP, _edje_part_mouse_up_cb, rp);
evas_object_event_callback_add(rp->object, EVAS_CALLBACK_MOUSE_MOVE, _edje_part_mouse_move_cb, rp);
// FIXME: make cursor object correct
en->cursor_bg = evas_object_rectangle_add(evas_object_evas_get(rp->object));
evas_object_smart_member_add(en->cursor_bg, rp->edje->obj);
evas_object_stack_below(en->cursor_bg, rp->object);
evas_object_clip_set(en->cursor_bg, evas_object_clip_get(rp->object));
evas_object_color_set(en->cursor_bg, 255, 20, 20, 150);
evas_object_pass_events_set(en->cursor_bg, 1);
evas_object_show(en->cursor_bg);
en->cursor = evas_object_textblock_cursor_get(rp->object);
}
void
_edje_entry_real_part_shutdown(Edje_Real_Part *rp)
{
Entry *en = rp->entry_data;
if (!en) return;
rp->entry_data = NULL;
// FIXME: delete cursor objects, sel cursors and en->sel's undo buffer copy/cut buffer
free(en);
}
void
_edje_entry_real_part_configure(Edje_Real_Part *rp)
{
Evas_Coord x, y, w, h, xx, yy, ww, hh;
Entry *en = rp->entry_data;
if (!en) return;
evas_object_geometry_get(rp->object, &x, &y, &w, &h);
// move cursor/selections etc.
evas_textblock_cursor_char_geometry_get(en->cursor, &xx, &yy, &ww, &hh);
evas_object_move(en->cursor_bg, x + xx, y + yy);
if (ww < 1) ww = 1;
if (hh < 1) ww = 1;
evas_object_resize(en->cursor_bg, ww, hh);
// FIXME: move/resize en->sel (record the sels and intended geom)
}
// FIXME: need to implement
// get text
// insert text
// delete selected text
// get selection
//

View File

@ -434,6 +434,8 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
rp->text.source = ed->table_parts[rp->param1.description->text.id_source % ed->table_parts_size];
if (rp->param1.description->text.id_text_source >= 0)
rp->text.text_source = ed->table_parts[rp->param1.description->text.id_text_source % ed->table_parts_size];
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
_edje_entry_real_part_init(rp);
}
}
@ -659,6 +661,8 @@ _edje_file_del(Edje *ed)
Edje_Real_Part *rp;
rp = ed->table_parts[i];
if (rp->part->entry_mode > EDJE_ENTRY_EDIT_MODE_NONE)
_edje_entry_real_part_shutdown(rp);
if (rp->object)
{
_edje_text_real_part_on_del(ed, rp);

View File

@ -207,7 +207,8 @@ typedef struct _Edje_Patterns Edje_Patterns;
#define EDJE_ACTION_TYPE_DRAG_VAL_STEP 5
#define EDJE_ACTION_TYPE_DRAG_VAL_PAGE 6
#define EDJE_ACTION_TYPE_SCRIPT 7
#define EDJE_ACTION_TYPE_LAST 8
#define EDJE_ACTION_TYPE_FOCUS_SET 8
#define EDJE_ACTION_TYPE_LAST 9
#define EDJE_TWEEN_MODE_NONE 0
#define EDJE_TWEEN_MODE_LINEAR 1
@ -259,6 +260,12 @@ typedef struct _Edje_Patterns Edje_Patterns;
#define EDJE_STATE_PARAM_VISIBLE 31
#define EDJE_STATE_PARAM_LAST 32
// FIXME: doing
#define EDJE_ENTRY_EDIT_MODE_NONE 0
#define EDJE_ENTRY_EDIT_MODE_SELECTABLE 1
#define EDJE_ENTRY_EDIT_MODE_EDITABLE 2
#define EDJE_ENTRY_EDIT_MODE_PASSWORD 3
#define EDJE_PART_PATH_SEPARATOR ':'
#define EDJE_PART_PATH_SEPARATOR_STRING ":"
/*----------*/
@ -456,7 +463,7 @@ struct _Edje_Part
const char *name; /* the name if any of the part */
Edje_Part_Description *default_desc; /* the part descriptor for default */
Evas_List *other_desc; /* other possible descriptors */
const char *source;
const char *source, *source2, *source3, *source4;
int id; /* its id number */
int clip_to_id; /* the part id to clip this one to */
struct {
@ -483,6 +490,8 @@ struct _Edje_Part
unsigned char precise_is_inside;
unsigned char use_alternate_font_metrics;
unsigned char pointer_mode;
unsigned char entry_mode;
unsigned char multiline;
};
struct _Edje_Part_Image_Id
@ -638,6 +647,7 @@ struct _Edje
/* for faster lookups to avoid nth list walks */
Edje_Real_Part **table_parts;
Edje_Program **table_programs;
Edje_Real_Part *focused_part;
void *script_only_data;
int table_programs_size;
int table_parts_size;
@ -684,6 +694,10 @@ struct _Edje_Real_Part
Evas_Object *object;
Evas_List *extra_objects;
Evas_Object *swallowed_object;
void *entry_data;
Evas_Object *cursorbg_object;
Evas_Object *cursorfg_object;
// FIXME: add selection objects
Edje_Part *part;
int x, y, w, h;
Edje_Rectangle req;
@ -1217,5 +1231,11 @@ void _edje_script_only_hide(Edje *ed);
void _edje_script_only_move(Edje *ed);
void _edje_script_only_resize(Edje *ed);
void _edje_script_only_message(Edje *ed, Edje_Message *em);
void _edje_entry_init(Edje *ed);
void _edje_entry_shutdown(Edje *ed);
void _edje_entry_real_part_init(Edje_Real_Part *rp);
void _edje_entry_real_part_shutdown(Edje_Real_Part *rp);
void _edje_entry_real_part_configure(Edje_Real_Part *rp);
#endif

View File

@ -785,6 +785,39 @@ _edje_program_run(Edje *ed, Edje_Program *pr, int force, const char *ssig, const
if (_edje_block_break(ed)) goto break_prog;
_edje_recalc(ed);
}
else if (pr->action == EDJE_ACTION_TYPE_FOCUS_SET)
{
if (!pr->targets)
{
ed->focused_part = NULL;
}
else
{
for (l = pr->targets; l; l = l->next)
{
Edje_Real_Part *rp;
Edje_Program_Target *pt;
pt = l->data;
if (pt->id >= 0)
{
rp = ed->table_parts[pt->id % ed->table_parts_size];
if (rp)
{
if (ed->focused_part != rp)
{
if (ed->focused_part)
_edje_emit(ed, "focus,part,out",
ed->focused_part->part->name);
ed->focused_part = rp;
_edje_emit(ed, "focus,part,in",
ed->focused_part->part->name);
}
}
}
}
}
}
else
{
// _edje_emit(ed, "program,start", pr->name);

View File

@ -65,6 +65,7 @@ _edje_smart_add(Evas_Object *obj)
evas_object_geometry_get(obj, &(ed->x), &(ed->y), &(ed->w), &(ed->h));
ed->obj = obj;
_edje_edjes = evas_list_append(_edje_edjes, obj);
_edje_entry_init(ed);
/*
{
Evas_List *l;
@ -88,6 +89,7 @@ _edje_smart_del(Evas_Object * obj)
ed = evas_object_smart_data_get(obj);
if (!ed) return;
_edje_block_violate(ed);
_edje_entry_shutdown(ed);
ed->delete_me = 1;
_edje_clean_objects(ed);
_edje_edjes = evas_list_remove(_edje_edjes, obj);