const Rect Text::getCharacterCoordinates(const Point &pos) const { Evas_Coord cx, cy, cw, ch; // TODO: what to do with 'ret'? int ret = evas_object_text_char_coords_get (o, pos.x (), pos.y (), &cx, &cy, &cw, &ch); return Rect (cx, cy, cw, ch); }
/** * Gets the cursor position at the coords ( @a x, @a y ). It's used to know * where to place the cursor or the selection bound on mouse evevents. * * @param editable an editable object * @param x the x coord, relative to the editable object * @param y the y coord, relative to the editable object * @return Returns the position where to place the cursor according to the * given coords */ EAPI int e_editable_pos_get_from_coords(Evas_Object *editable, Evas_Coord x, Evas_Coord y) { E_Editable_Smart_Data *sd; const Evas_Object *text_obj; Evas_Coord ox, oy; Evas_Coord tx, ty, tw, th; Evas_Coord cx, cw; Evas_Coord canvas_x, canvas_y; int index, pos, i, j; const char *text; if (evas_object_smart_smart_get(editable) != _e_editable_smart) SMARTERR(0); if ((!editable) || (!(sd = evas_object_smart_data_get(editable)))) return 0; if (!(text_obj = edje_object_part_object_get(sd->text_object, "e.text.text"))) return 0; evas_object_geometry_get(editable, &ox, &oy, NULL, NULL); evas_object_geometry_get(text_obj, &tx, &ty, &tw, &th); canvas_x = ox + x; canvas_y = oy + y; if ((canvas_y < ty) || (canvas_x < tx)) pos = 0; else if ((canvas_y > (ty + th)) || (canvas_x > (tx + tw))) pos = sd->unicode_length; else { index = evas_object_text_char_coords_get(text_obj, canvas_x - tx, canvas_y - ty, &cx, NULL, &cw, NULL); text = evas_object_text_text_get(text_obj); if ((index >= 0) && (text)) { if ((canvas_x - tx) > (cx + (cw / 2))) index++; i = 0; j = -1; pos = 0; while ((i < index) && (j != i)) { pos++; j = i; i = evas_string_char_next_get(text, i, NULL); } if (pos > sd->unicode_length) pos = sd->unicode_length; } else pos = 0; } return pos; }
/* kjb - share code between down and med */ void med_e_entry_down_internal(Evas * _e, E_Entry *entry, int _b, int _x, int _y, int key) { int pos; /* kjb - clear prior focus if needed */ if( has_focus && has_focus != entry ) { e_entry_clear_current_focus(); } has_focus = entry; entry->focused = 1; if(key) { /* kjb - set cursor at end of text */ entry->cursor_pos = strlen(entry->buffer); } else { double ex, ey; double tw; evas_object_geometry_get(entry->text, &ex, &ey, &tw, NULL); pos = evas_object_text_char_coords_get(entry->text, _x-ex, _y-ey, NULL, NULL, NULL, NULL); if (pos < 0) { if (_x > entry->x + tw) { entry->cursor_pos = strlen(entry->buffer); } else if (_x < entry->x) { entry->cursor_pos = 0; } } else { entry->cursor_pos = pos; } } entry->mouse_down = _b; entry->select.start = -1; e_entry_configure(entry); }
END_TEST /* Various text related geometries */ START_TEST(evas_text_geometries) { START_TEXT_TEST(); const char *buf = "Tests"; const char *font = TEST_FONT_NAME; Evas_Font_Size size = 14; Evas_Coord prev; int i; Evas_Coord x, y, w, h, px; evas_object_text_text_set(to, buf); /* All should be 0 without a font set */ fail_if(evas_object_text_ascent_get(to) != 0); fail_if(evas_object_text_descent_get(to) != 0); fail_if(evas_object_text_max_ascent_get(to) != 0); fail_if(evas_object_text_max_descent_get(to) != 0); fail_if(evas_object_text_horiz_advance_get(to) != 0); fail_if(evas_object_text_vert_advance_get(to) != 0); evas_object_text_font_set(to, font, size); /* Check that they are bigger than 0. */ fail_if(evas_object_text_ascent_get(to) <= 0); fail_if(evas_object_text_descent_get(to) <= 0); fail_if(evas_object_text_max_ascent_get(to) <= 0); fail_if(evas_object_text_max_descent_get(to) <= 0); fail_if(evas_object_text_horiz_advance_get(to) <= 0); fail_if(evas_object_text_vert_advance_get(to) <= 0); /* Check that expanding the text does what we expect it */ evas_object_text_text_set(to, "Test"); prev = evas_object_text_ascent_get(to); evas_object_text_text_set(to, "Testing"); fail_if(evas_object_text_ascent_get(to) != prev); evas_object_text_text_set(to, "Test"); prev = evas_object_text_descent_get(to); evas_object_text_text_set(to, "Testing"); fail_if(evas_object_text_descent_get(to) != prev); evas_object_text_text_set(to, "Test"); prev = evas_object_text_max_ascent_get(to); evas_object_text_text_set(to, "Testing"); fail_if(evas_object_text_max_ascent_get(to) != prev); evas_object_text_text_set(to, "Test"); prev = evas_object_text_max_descent_get(to); evas_object_text_text_set(to, "Testing"); fail_if(evas_object_text_max_descent_get(to) != prev); evas_object_text_text_set(to, "Test"); prev = evas_object_text_horiz_advance_get(to); evas_object_text_text_set(to, "Testing"); fail_if(evas_object_text_horiz_advance_get(to) <= prev); evas_object_text_text_set(to, "Test"); prev = evas_object_text_vert_advance_get(to); evas_object_text_text_set(to, "Testing"); fail_if(evas_object_text_vert_advance_get(to) != prev); /* Go through all the characters, making sure the geometries we get * are in a monotonically increasing order and that all sizes are * bigger than 0. */ evas_object_text_text_set(to, "Testing..."); x = 0; px = -100; for (i = 0 ; i < eina_unicode_utf8_get_len("Testing...") ; i++) { fail_if(!evas_object_text_char_pos_get(to, i, &x, &y, &w, &h)); fail_if(x <= px); px = x; /* Get back the coords */ fail_if(i != evas_object_text_char_coords_get(to, x + (w / 4), y + (h / 2), NULL, NULL, NULL, NULL)); /* Get back cursor position, if click on right half of char. */ fail_if((i + 1) != evas_object_text_char_coords_get(to, x + ((3 * w) / 4), y + (h / 2), &x, &y, &w, &h)); } /* Last up to pos */ Evas_Coord adv; int pos, prev_pos; evas_object_text_text_set(to, "Test - 유니코드"); adv = evas_object_text_horiz_advance_get(to); pos = prev_pos = 0; for (x = 0 ; x <= (adv - 1) ; x++) { pos = evas_object_text_last_up_to_pos(to, x, 0); _ck_assert_int(pos, >=, prev_pos); prev_pos = pos; } pos = evas_object_text_last_up_to_pos(to, x, 0); ck_assert_int_eq(pos, -1); pos = evas_object_text_last_up_to_pos(to, -50, 0); ck_assert_int_eq(pos, -1); END_TEXT_TEST(); }
END_TEST #ifdef HAVE_FRIBIDI START_TEST(evas_text_bidi) { START_TEXT_TEST(); const char *buf = "Test - בדיקה"; int i; Evas_Coord x, y, w, h, px; const char *font = TEST_FONT_NAME; Evas_Font_Size size = 14; evas_object_text_font_set(to, font, size); evas_object_text_text_set(to, buf); fail_if(evas_object_text_direction_get(to) != EVAS_BIDI_DIRECTION_LTR); evas_object_text_text_set(to, "בדיקה"); fail_if(evas_object_text_direction_get(to) != EVAS_BIDI_DIRECTION_RTL); /* With RTL text coords should be monotontically decreasing. */ evas_object_text_text_set(to, "נסיון..."); x = 0; px = 200; for (i = 0 ; i < eina_unicode_utf8_get_len("נסיון...") ; i++) { fail_if(!evas_object_text_char_pos_get(to, i, &x, &y, &w, &h)); fail_if(x >= px); px = x; /* Get back the coords */ fail_if(i != evas_object_text_char_coords_get(to, x + ((3 * w) / 4), y + (h / 2), &x, &y, &w, &h)); } /* Get back cursor position, if click on left half of char. */ evas_object_text_text_set(to, "שלום..."); x = 0; px = 200; for (i = 0 ; i < eina_unicode_utf8_get_len("שלום...") ; i++) { fail_if(!evas_object_text_char_pos_get(to, i, &x, &y, &w, &h)); fail_if(x >= px); px = x; fail_if((i + 1) != evas_object_text_char_coords_get(to, x + (w / 4), y + (h / 2), &x, &y, &w, &h)); } /* Bidi text is a bit more complex */ evas_object_text_text_set(to, "Test - נסיון..."); x = 0; px = -100; for (i = 0 ; i < eina_unicode_utf8_get_len("Test - ") ; i++) { fail_if(!evas_object_text_char_pos_get(to, i, &x, &y, &w, &h)); fail_if(x <= px); px = x; /* Get back the coords */ fail_if(i != evas_object_text_char_coords_get(to, x + (w / 4), y + (h / 2), &x, &y, &w, &h)); } /* First rtl char requires more specific handling */ fail_if(!evas_object_text_char_pos_get(to, i, &x, &y, &w, &h)); fail_if(x <= px); px = x; fail_if(i != evas_object_text_char_coords_get(to, x + ((3 * w) / 4), y + (h / 2), &x, &y, &w, &h)); i++; for ( ; i < eina_unicode_utf8_get_len("Test - נסיון") ; i++) { fail_if(!evas_object_text_char_pos_get(to, i, &x, &y, &w, &h)); fail_if(x >= px); px = x; /* Get back the coords */ fail_if(i != evas_object_text_char_coords_get(to, x + (w / 2), y + (h / 2), &x, &y, &w, &h)); } /* First ltr char requires more specific handling */ fail_if(!evas_object_text_char_pos_get(to, i, &x, &y, &w, &h)); fail_if(x <= px); px = x; i++; for ( ; i < eina_unicode_utf8_get_len("Test - נסיון...") ; i++) { fail_if(!evas_object_text_char_pos_get(to, i, &x, &y, &w, &h)); fail_if(x <= px); px = x; /* Get back the coords */ fail_if(i != evas_object_text_char_coords_get(to, x + (w / 2), y + (h / 2), &x, &y, &w, &h)); } /* And with an rtl text */ evas_object_text_text_set(to, "נסיון - test..."); x = 0; px = 100; for (i = 0 ; i < eina_unicode_utf8_get_len("נסיון - ") ; i++) { fail_if(!evas_object_text_char_pos_get(to, i, &x, &y, &w, &h)); fail_if(x >= px); px = x; /* Get back the coords */ if (w == 0) { int cx; fail_if(!evas_object_text_char_pos_get(to, i - 1, &cx, NULL, NULL, NULL)); w = cx - x; } fail_if(i != evas_object_text_char_coords_get(to, x + (3 * w /4), y + (h / 2), &x, &y, &w, &h)); } /* First ltr char requires more specific handling */ fail_if(!evas_object_text_char_pos_get(to, i, &x, &y, &w, &h)); fail_if(x >= px); px = x; fail_if(i != evas_object_text_char_coords_get(to, x + (w / 2), y + (h / 2), &x, &y, &w, &h)); i++; for ( ; i < eina_unicode_utf8_get_len("נסיון - test") ; i++) { fail_if(!evas_object_text_char_pos_get(to, i, &x, &y, &w, &h)); fail_if(x <= px); px = x; /* Get back the coords */ fail_if(i != evas_object_text_char_coords_get(to, x + (w / 2), y + (h / 2), &x, &y, &w, &h)); } /* First rtl char requires more specific handling */ fail_if(!evas_object_text_char_pos_get(to, i, &x, &y, &w, &h)); fail_if(x >= px); px = x; i++; for ( ; i < eina_unicode_utf8_get_len("נסיון - test...") ; i++) { fail_if(!evas_object_text_char_pos_get(to, i, &x, &y, &w, &h)); fail_if(x >= px); px = x; /* Get back the coords */ fail_if(i != evas_object_text_char_coords_get(to, x + (w / 2), y + (h / 2), &x, &y, &w, &h)); } /* And some last up to pos tests */ Evas_Coord adv; int pos, prev_pos; evas_object_text_text_set(to, "Test - נסיון..."); adv = evas_object_text_horiz_advance_get(to); pos = prev_pos = 0; for (x = 0 ; x <= (adv - 1) ; x++) { pos = evas_object_text_last_up_to_pos(to, x, 0); _ck_assert_int(pos, >=, prev_pos); prev_pos = pos; } pos = evas_object_text_last_up_to_pos(to, x, 0); fail_if(pos != -1); pos = evas_object_text_last_up_to_pos(to, -50, 0); fail_if(pos != -1); END_TEXT_TEST(); }
static void e_entry_move_cb(void *_data, Evas * _e, Evas_Object * _o, void *event) { E_Entry *entry; Evas_Event_Mouse_Move *ev = event; entry = _data; if (entry->mouse_down > 0) { int pos, ppos; double ty, tw; ppos = entry->cursor_pos; evas_object_geometry_get(entry->text, NULL, &ty, &tw, NULL); pos = evas_object_text_char_coords_get(entry->text, ev->cur.canvas.x, ty, NULL, NULL, NULL, NULL); if (pos < 0) { if (ev->cur.canvas.x > entry->x + tw) { entry->cursor_pos = strlen(entry->buffer); } else if (ev->cur.canvas.x < entry->x) { entry->cursor_pos = 0; } } else { entry->cursor_pos = pos; } if ((entry->select.start < 0) && (ppos != entry->cursor_pos)) { if (ppos < entry->cursor_pos) { entry->select.down = ppos; entry->select.start = ppos; entry->select.length = entry->cursor_pos - ppos +1; } else { entry->select.down = ppos; entry->select.start = entry->cursor_pos; entry->select.length = ppos - entry->cursor_pos +1; } } else if (entry->select.start >= 0) { if (entry->cursor_pos < entry->select.down) { entry->select.start = entry->cursor_pos; entry->select.length = entry->select.down - entry->cursor_pos + 1; } else { entry->select.start = entry->select.down; entry->select.length = entry->cursor_pos - entry->select.down + 1; } } if (entry->select.start >= 0) { char *str2; str2 = e_entry_get_selection(entry); if (str2) { if (entry->selection_win) ecore_window_destroy(entry->selection_win); entry->selection_win = ecore_selection_set(str2); free(str2); } } e_entry_configure(entry); } UN(_o); }