/* Copies the selected text of the spinner to the given selection */ static void _etk_spinner_selection_copy(Etk_Spinner *spinner, Etk_Selection_Type selection, Etk_Bool cut) { Evas_Object *editable; int cursor_pos, selection_pos; int start_pos, end_pos; Etk_Bool selecting; char *range; if (!spinner) return; editable = spinner->editable_object; cursor_pos = etk_editable_cursor_pos_get(editable); selection_pos = etk_editable_selection_pos_get(editable); start_pos = ETK_MIN(cursor_pos, selection_pos); end_pos = ETK_MAX(cursor_pos, selection_pos); selecting = (start_pos != end_pos); if (!selecting) return; range = etk_editable_text_range_get(editable, start_pos, end_pos); if (range) { etk_selection_text_set(selection, range); free(range); if (cut) etk_editable_delete(editable, start_pos, end_pos); } }
/* Called when the selection/clipboard content is received */ static Etk_Bool _etk_spinner_selection_received_cb(Etk_Object *object, void *event, void *data) { Etk_Spinner *spinner; Evas_Object *editable; Etk_Selection_Event *ev = event; const char *text; if (!(spinner = ETK_SPINNER(object)) || !(editable = spinner->editable_object)) return ETK_TRUE; if (ev->type == ETK_SELECTION_TEXT && (text = ev->data.text) && *text && (strlen(text) != 1 || text[0] >= 0x20)) { int cursor_pos, selection_pos; int start_pos, end_pos; Etk_Bool selecting; cursor_pos = etk_editable_cursor_pos_get(editable); selection_pos = etk_editable_selection_pos_get(editable); start_pos = ETK_MIN(cursor_pos, selection_pos); end_pos = ETK_MAX(cursor_pos, selection_pos); selecting = (start_pos != end_pos); if (selecting) etk_editable_delete(editable, start_pos, end_pos); etk_editable_insert(editable, start_pos, text); } return ETK_TRUE; }
/* Called when the user presses a key */ static Etk_Bool _etk_spinner_key_down_cb(Etk_Object *object, Etk_Event_Key_Down *event, void *data) { Etk_Spinner *spinner; Etk_Range *range; Evas_Object *editable; int cursor_pos, selection_pos; int start_pos, end_pos; int climb_factor; Etk_Bool selecting; Etk_Bool changed = ETK_FALSE; Etk_Bool selection_changed = ETK_FALSE; Etk_Bool stop_signal = ETK_TRUE; if (!(spinner = ETK_SPINNER(object))) return ETK_TRUE; range = ETK_RANGE(spinner); editable = spinner->editable_object; cursor_pos = etk_editable_cursor_pos_get(editable); selection_pos = etk_editable_selection_pos_get(editable); start_pos = ETK_MIN(cursor_pos, selection_pos); end_pos = ETK_MAX(cursor_pos, selection_pos); selecting = (start_pos != end_pos); /* TODO: increment faster if the key has been pressed for a long time... */ climb_factor = 1; /* Move the cursor/selection to the left */ if (strcmp(event->keyname, "Left") == 0) { if (event->modifiers & ETK_MODIFIER_SHIFT) { etk_editable_cursor_move_left(editable); selection_changed = ETK_TRUE; } else if (selecting) { if (cursor_pos < selection_pos) etk_editable_selection_pos_set(editable, cursor_pos); else etk_editable_cursor_pos_set(editable, selection_pos); } else { etk_editable_cursor_move_left(editable); etk_editable_selection_pos_set(editable, etk_editable_cursor_pos_get(editable)); } } /* Move the cursor/selection to the right */ else if (strcmp(event->keyname, "Right") == 0) { if (event->modifiers & ETK_MODIFIER_SHIFT) { etk_editable_cursor_move_right(editable); selection_changed = ETK_TRUE; } else if (selecting) { if (cursor_pos > selection_pos) etk_editable_selection_pos_set(editable, cursor_pos); else etk_editable_cursor_pos_set(editable, selection_pos); } else { etk_editable_cursor_move_right(editable); etk_editable_selection_pos_set(editable, etk_editable_cursor_pos_get(editable)); } } /* Move the cursor/selection to the start of the spinner */ else if (strcmp(event->keyname, "Home") == 0) { etk_editable_cursor_move_to_start(editable); if (!(event->modifiers & ETK_MODIFIER_SHIFT)) etk_editable_selection_pos_set(editable, etk_editable_cursor_pos_get(editable)); else selection_changed = ETK_TRUE; } /* Move the cursor/selection to the end of the spinner */ else if (strcmp(event->keyname, "End") == 0) { etk_editable_cursor_move_to_end(editable); if (!(event->modifiers & ETK_MODIFIER_SHIFT)) etk_editable_selection_pos_set(editable, etk_editable_cursor_pos_get(editable)); else selection_changed = ETK_TRUE; } /* Delete the previous character */ else if (strcmp(event->keyname, "BackSpace") == 0) { if (selecting) changed = etk_editable_delete(editable, start_pos, end_pos); else changed = etk_editable_delete(editable, cursor_pos - 1, cursor_pos); } /* Delete the next character */ else if (strcmp(event->keyname, "Delete") == 0) { if (selecting) changed = etk_editable_delete(editable, start_pos, end_pos); else changed = etk_editable_delete(editable, cursor_pos, cursor_pos + 1); } /* Increment the value */ else if (strcmp(event->keyname, "Up") == 0) { _etk_spinner_spin(spinner, climb_factor * range->step_increment); } /* Decrement the value */ else if (strcmp(event->keyname, "Down") == 0) { _etk_spinner_spin(spinner, -(climb_factor * range->step_increment)); } /* Increment the value by the page-increment */ else if (strcmp(event->keyname, "Prior") == 0) { _etk_spinner_spin(spinner, climb_factor * range->page_increment); } /* Decrement the value by the page-increment */ else if (strcmp(event->keyname, "Next") == 0) { _etk_spinner_spin(spinner, -(climb_factor * range->page_increment)); } /* Validate the value entered in the spinner */ else if (strcmp(event->keyname, "Return") == 0 || strcmp(event->keyname, "KP_Enter") == 0) { _etk_spinner_update_value_from_text(spinner); } /* Ctrl + A,C,X,V */ else if (event->modifiers & ETK_MODIFIER_CTRL) { if (strcmp(event->keyname, "a") == 0) { etk_editable_select_all(editable); selection_changed = ETK_TRUE; } else if (strcmp(event->keyname, "x") == 0 || strcmp(event->keyname, "c") == 0) _etk_spinner_selection_copy(spinner, ETK_SELECTION_CLIPBOARD, (strcmp(event->keyname, "x") == 0)); else if (strcmp(event->keyname, "v") == 0) etk_selection_text_request(ETK_SELECTION_CLIPBOARD, ETK_WIDGET(spinner)); else stop_signal = ETK_FALSE; } /* Otherwise, we insert the corresponding character */ else if (event->string && *event->string && (strlen(event->string) != 1 || event->string[0] >= 0x20)) { if (selecting) changed |= etk_editable_delete(editable, start_pos, end_pos); changed |= etk_editable_insert(editable, start_pos, event->string); } else stop_signal = ETK_FALSE; if (selection_changed) _etk_spinner_selection_copy(spinner, ETK_SELECTION_PRIMARY, ETK_FALSE); return (!stop_signal); }
/** * @brief Resizes the table. The children that are attached to a row or a column that is removed will be unparented * @param table a table * @param num_rows the new number of rows * @param num_cols the new number of cols */ void etk_table_resize(Etk_Table *table, int num_cols, int num_rows) { Eina_List *l, *next; Etk_Table_Cell **new_cells; Etk_Table_Cell *cell; Etk_Table_Col_Row *new_cols, *new_rows; Etk_Widget *child; int i, j; if (!table) return; if (num_cols < 0) num_cols = 0; if (num_rows < 0) num_rows = 0; if (num_cols == 0 && num_rows == 0) { new_cells = NULL; new_cols = NULL; new_rows = NULL; } else { new_cells = calloc(num_cols * num_rows, sizeof(Etk_Table_Cell *)); new_cols = malloc(num_cols * sizeof(Etk_Table_Col_Row)); new_rows = malloc(num_rows * sizeof(Etk_Table_Col_Row)); } for (l = table->cells_list; l; l = next) { next = l->next; cell = l->data; child = cell->child; /* The child is in the old table but not in the new one: we remove it */ if (cell->left_attach >= num_cols || cell->top_attach >= num_rows) etk_table_cell_clear(table, cell->left_attach, cell->top_attach); /* The child is in the new table: we copy it to the new table */ else { cell->right_attach = ETK_MIN(num_cols - 1, cell->right_attach); cell->bottom_attach = ETK_MIN(num_rows - 1, cell->bottom_attach); for (i = cell->left_attach; i <= cell->right_attach; i++) { for (j = cell->top_attach; j <= cell->bottom_attach; j++) new_cells[j * num_cols + i] = cell; } } } free(table->cells); free(table->cols); free(table->rows); table->cells = new_cells; table->cols = new_cols; table->rows = new_rows; table->num_cols = num_cols; table->num_rows = num_rows; etk_widget_size_recalc_queue(ETK_WIDGET(table)); etk_object_notify(ETK_OBJECT(table), "num-cols"); etk_object_notify(ETK_OBJECT(table), "num-rows"); }