void widget_replace (Widget * old_w, Widget * new_w) { WDialog *h = old_w->owner; gboolean should_focus = FALSE; if (h->widgets == NULL) return; if (h->current == NULL) h->current = h->widgets; if (old_w == h->current->data) should_focus = TRUE; new_w->owner = h; new_w->id = old_w->id; if (should_focus) h->current->data = new_w; else g_list_find (h->widgets, old_w)->data = new_w; send_message (old_w, NULL, MSG_DESTROY, 0, NULL); send_message (new_w, NULL, MSG_INIT, 0, NULL); if (should_focus) dlg_select_widget (new_w); widget_redraw (new_w); }
/************************************************************************** Universal redraw Group of Widget function. Function is optimized to WindowGroup: start draw from 'pEnd' and stop on 'pBegin', in theory 'pEnd' is window widget; **************************************************************************/ Uint16 redraw_group(const struct widget *pBeginGroupWidgetList, const struct widget *pEndGroupWidgetList, int add_to_update) { Uint16 count = 0; struct widget *pTmpWidget = (struct widget *) pEndGroupWidgetList; while (pTmpWidget) { if ((get_wflags(pTmpWidget) & WF_HIDDEN) != WF_HIDDEN) { widget_redraw(pTmpWidget); if (add_to_update) { widget_mark_dirty(pTmpWidget); } count++; } if (pTmpWidget == pBeginGroupWidgetList) { break; } pTmpWidget = pTmpWidget->prev; } return count; }
static void update_split (const WDialog * h) { /* Check split has to be done before testing if it changed, since it can change due to calling check_split() as well */ check_split (&panels_layout); if (panels_layout.horizontal_split) check_options[0].widget->state = panels_layout.horizontal_equal ? 1 : 0; else check_options[0].widget->state = panels_layout.vertical_equal ? 1 : 0; widget_redraw (WIDGET (check_options[0].widget)); tty_setcolor (check_options[0].widget->state & C_BOOL ? DISABLED_COLOR : COLOR_NORMAL); widget_move (h, 6, 5); if (panels_layout.horizontal_split) tty_printf ("%03d", panels_layout.top_panel_size); else tty_printf ("%03d", panels_layout.left_panel_size); widget_move (h, 6, 17); if (panels_layout.horizontal_split) tty_printf ("%03d", height - panels_layout.top_panel_size); else tty_printf ("%03d", COLS - panels_layout.left_panel_size); widget_move (h, 6, 12); tty_print_char ('='); }
/** * Set text of edit box * * @param __edit - edit box to set text to * @param __text - text to be set */ void w_edit_set_text (w_edit_t* __edit, const wchar_t *__text) { if (!__edit || !__text) { return; } size_t new_len = wcslen (__text) + 1; if (new_len > __edit->text.allocated) { /* Length of new string is longer than length of allocated buffer, */ /* so we need to increase this buffer */ __edit->text.data = realloc (__edit->text.data, new_len * sizeof (wchar_t)); __edit->text.allocated = new_len; } wcscpy (__edit->text.data, __text); /* Move caret to end of text */ __edit->caret_pos = wcslen (__edit->text.data); edit_validate_scrolling (__edit); widget_redraw (WIDGET (__edit)); }
/** * Set variants list for auto-guessing stuff * * @param __edit - edit box for which variants will be set * @param __strings - list of variants * @param __count - count of elements in list */ void w_edit_set_variants (w_edit_t *__edit, wchar_t **__strings, unsigned long __count) { unsigned long i; if (!__edit || !__strings) { return; } /* Free previously used variants */ free_variants (__edit); __edit->variants.strings = malloc (__count * sizeof (wchar_t*)); for (i = 0; i < __count; ++i) { __edit->variants.strings[i] = wcsdup (__strings[i]); } __edit->variants.count = __count; sort_variants (__edit); /* We should to re-new suffix and redraw widget */ make_guessing (__edit); widget_redraw (WIDGET (__edit)); }
/************************************************************************** ... **************************************************************************/ static int redraw_textcheckbox(struct widget *pCBox) { int ret; SDL_Surface *pTheme_Surface, *pIcon; ret = (*textcheckbox_baseclass_redraw)(pCBox); if (ret != 0) { return ret; } if(!pCBox->string16) { return widget_redraw(pCBox); } pTheme_Surface = pCBox->theme; pIcon = create_icon_from_theme(pTheme_Surface, get_wstate(pCBox)); if (!pIcon) { return -3; } pCBox->theme = pIcon; /* redraw icon label */ ret = redraw_iconlabel(pCBox); FREESURFACE(pIcon); pCBox->theme = pTheme_Surface; return ret; }
static void tree_chdir_sel (WTree * tree) { if (tree->is_panel) { change_panel (); if (do_cd (tree->selected_ptr->name, cd_exact)) select_item (current_panel); else message (D_ERROR, MSG_ERROR, _("Cannot chdir to \"%s\"\n%s"), vfs_path_as_str (tree->selected_ptr->name), unix_error_string (errno)); widget_redraw (WIDGET (current_panel)); change_panel (); show_tree (tree); } else { WDialog *h = WIDGET (tree)->owner; h->ret_value = B_ENTER; dlg_stop (h); } }
static cb_ret_t tree_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data) { WTree *tree = (WTree *) w; WDialog *h = w->owner; WButtonBar *b; switch (msg) { case MSG_DRAW: tree_frame (h, tree); show_tree (tree); if (widget_get_state (w, WST_FOCUSED)) { b = find_buttonbar (h); widget_redraw (WIDGET (b)); } return MSG_HANDLED; case MSG_FOCUS: b = find_buttonbar (h); buttonbar_set_label (b, 1, Q_ ("ButtonBar|Help"), tree_map, w); buttonbar_set_label (b, 2, Q_ ("ButtonBar|Rescan"), tree_map, w); buttonbar_set_label (b, 3, Q_ ("ButtonBar|Forget"), tree_map, w); buttonbar_set_label (b, 4, tree_navigation_flag ? Q_ ("ButtonBar|Static") : Q_ ("ButtonBar|Dynamc"), tree_map, w); buttonbar_set_label (b, 5, Q_ ("ButtonBar|Copy"), tree_map, w); buttonbar_set_label (b, 6, Q_ ("ButtonBar|RenMov"), tree_map, w); #if 0 /* FIXME: mkdir is currently defunct */ buttonbar_set_label (b, 7, Q_ ("ButtonBar|Mkdir"), tree_map, w); #else buttonbar_clear_label (b, 7, w); #endif buttonbar_set_label (b, 8, Q_ ("ButtonBar|Rmdir"), tree_map, w); return MSG_HANDLED; case MSG_UNFOCUS: tree->searching = 0; return MSG_HANDLED; case MSG_KEY: return tree_key (tree, parm); case MSG_ACTION: /* command from buttonbar */ return tree_execute_cmd (tree, parm); case MSG_DESTROY: tree_destroy (tree); return MSG_HANDLED; default: return widget_default_callback (w, sender, msg, parm, data); } }
void gauge_show (WGauge * g, gboolean shown) { if (g->shown != shown) { g->shown = shown; widget_redraw (WIDGET (g)); } }
void hline_set_text (WHLine * l, const char *text) { g_free (l->text); if (text == NULL || *text == '\0') l->text = NULL; else l->text = g_strdup (text); widget_redraw (WIDGET (l)); }
void gauge_set_value (WGauge * g, int max, int current) { if (g->current == current && g->max == max) return; /* Do not flicker */ if (max == 0) max = 1; /* I do not like division by zero :) */ g->current = current; g->max = max; widget_redraw (WIDGET (g)); }
void widget_replace (Widget * old_w, Widget * new_w) { WDialog *h = old_w->owner; gboolean should_focus = FALSE; GList *holder; if (h->widgets == NULL) return; if (h->current == NULL) h->current = h->widgets; /* locate widget position in the list */ if (old_w == h->current->data) holder = h->current; else holder = g_list_find (h->widgets, old_w); /* if old widget is focused, we should focus the new one... */ if (widget_get_state (old_w, WST_FOCUSED)) should_focus = TRUE; /* ...but if new widget isn't selectable, we cannot focus it */ if (!widget_get_options (new_w, WOP_SELECTABLE)) should_focus = FALSE; /* if new widget isn't selectable, select other widget before replace */ if (!should_focus) { GList *l; for (l = dlg_get_widget_next_of (holder); !widget_get_options (WIDGET (l->data), WOP_SELECTABLE) && !widget_get_state (WIDGET (l->data), WST_DISABLED); l = dlg_get_widget_next_of (l)) ; widget_select (WIDGET (l->data)); } /* replace widget */ new_w->owner = h; new_w->id = old_w->id; holder->data = new_w; send_message (old_w, NULL, MSG_DESTROY, 0, NULL); send_message (new_w, NULL, MSG_INIT, 0, NULL); if (should_focus) widget_select (new_w); else widget_redraw (new_w); }
static void tree_toggle_navig (WTree * tree) { WButtonBar *b; tree_navigation_flag = !tree_navigation_flag; b = find_buttonbar (WIDGET (tree)->owner); buttonbar_set_label (b, 4, tree_navigation_flag ? Q_ ("ButtonBar|Static") : Q_ ("ButtonBar|Dynamc"), tree_map, WIDGET (tree)); widget_redraw (WIDGET (b)); }
/** * Handler of `blured` callback (system-based) * * @param __edit - edit which catched this callback * @return zero if callback hasn't handled callback */ static int edit_blured (w_edit_t *__edit) { _WIDGET_CALL_USER_CALLBACK (__edit, blured, __edit); /* Assume suffix should be rejected if edit box lost focus */ __edit->suffix = NULL; widget_redraw (WIDGET (__edit)); /* When edit box is blured we should hide caret */ scr_hide_cursor (); return 0; }
/** * Set font of window * * @param __window - for which window change fonts * @param __font - font determines background of window and * color of lonely text on window * @param __caption_font - font for caption */ void w_window_set_fonts (w_window_t *__window, scr_font_t *__font, scr_font_t *__caption_font) { if (!__window) { return; } WIDGET_SAFE_SET_FONT (__window, font, __font); WIDGET_SAFE_SET_FONT (__window, caption.font, __caption_font); widget_redraw (WIDGET (__window)); }
/** * Set fonts used in edit * * @param __edit - for which edit fonts are to be set * @param __font - font of default text in normal state * @param __shaded_font - font of text when edit is in shaded state */ void w_edit_set_fonts (w_edit_t *__edit, scr_font_t *__font, scr_font_t *__shaded_font, scr_font_t *__suffix_font) { if (!__edit) { return; } WIDGET_SAFE_SET_FONT (__edit, font, __font); WIDGET_SAFE_SET_FONT (__edit, shaded_font, __shaded_font); WIDGET_SAFE_SET_FONT (__edit, suffix_font, __suffix_font); widget_redraw (WIDGET (__edit)); }
/** * Callback for onresize action * * @param __window - window which catched this event * @return zero if callback hasn't handled callback */ static int window_onresize (w_window_t *__window) { if (!__window) { return -1; } _WIDGET_CALL_USER_CALLBACK (__window, onresize, __window); if (__window->style & WMS_CENTERED) { centre_window (__window); } /* There is no window's resising stuff, so */ /* we have to create new window and use it */ scr_window_t oldwnd = WIDGET_LAYOUT (__window), newwnd = widget_create_layout (WIDGET (__window)); WIDGET_LAYOUT (__window) = newwnd; panel_replace (__window->panel, newwnd); panels_doupdate (); BOOL locked = WIDGET_TEST_FLAG (__window, WF_REDRAW_LOCKED); if (!locked) { widget_lock_redraw (WIDGET (__window)); } WIDGET_CONTAINER_ACTION_ITERONLY (__window, WIDGET_CALL_CALLBACK, onresize, __iterator_); if (!locked) { widget_unlock_redraw (WIDGET (__window)); widget_redraw (WIDGET (__window)); } if (oldwnd) { scr_destroy_window (oldwnd); } return TRUE; }
void groupbox_set_title (WGroupbox * g, const char *title) { MC_PTR_FREE (g->title); /* Strip existing spaces, add one space before and after the title */ if (title != NULL && *title != '\0') { char *t; t = g_strstrip (g_strdup (title)); g->title = g_strconcat (" ", t, " ", (char *) NULL); g_free (t); } widget_redraw (WIDGET (g)); }
/** * Set fonts used in button * * @param __button - for which button fonts are to be set * @param __font - font of default text in normal state * @param __focused_font - font of default text in focused state * @param __font - font of highlighted text (i.e. shortcut) in normal state * @param __focused_font - font of highlighted text * (i.e. shortcut) in focused state */ void w_button_set_fonts (w_button_t *__button, scr_font_t *__font, scr_font_t *__focused_font, scr_font_t *__hot_font, scr_font_t *__hot_focused_font) { if (!__button) { return; } WIDGET_SAFE_SET_FONT (__button, font, __font); WIDGET_SAFE_SET_FONT (__button, focused_font, __focused_font); WIDGET_SAFE_SET_FONT (__button, hot_font, __hot_font); WIDGET_SAFE_SET_FONT (__button, hot_focused_font, __hot_focused_font); widget_redraw (WIDGET (__button)); }
void mcview_update (WView * view) { static int dirt_limit = 1; if (view->dpy_bbar_dirty) { view->dpy_bbar_dirty = FALSE; mcview_set_buttonbar (view); widget_redraw (WIDGET (find_buttonbar (WIDGET (view)->owner))); } if (view->dirty > dirt_limit) { /* Too many updates skipped -> force a update */ mcview_display (view); view->dirty = 0; /* Raise the update skipping limit */ dirt_limit++; if (dirt_limit > mcview_max_dirt_limit) dirt_limit = mcview_max_dirt_limit; } else if (view->dirty > 0) { if (is_idle ()) { /* We have time to update the screen properly */ mcview_display (view); view->dirty = 0; if (dirt_limit > 1) dirt_limit--; } else { /* We are busy -> skipping full update, only the status line is updated */ mcview_display_status (view); } /* Here we had a refresh, if fast scrolling does not work restore the refresh, although this should not happen */ } }
void edit_update_screen (WEdit * e) { WDialog *h = WIDGET (e)->owner; edit_scroll_screen_over_cursor (e); edit_update_curs_col (e); edit_status (e, widget_get_state (WIDGET (e), WST_FOCUSED)); /* pop all events for this window for internal handling */ if (!is_idle ()) e->force |= REDRAW_PAGE; else { if ((e->force & REDRAW_COMPLETELY) != 0) e->force |= REDRAW_PAGE; edit_render_keypress (e); } widget_redraw (WIDGET (find_buttonbar (h))); }
/** * Default part of window showing stuff * * @param __window - window to be shown * @param _show_mode - mode in which window have to be shown. * Possible values: * WSM_NORLAM - Normal window * WSM_MODAL - Modal window * @return zero or modal result of window on success. * Less-zero value on failure. */ static int window_show_entry (w_window_t *__window, int __show_mode) { if (!__window) { return -1; } /* Window is now visible */ WIDGET_POSITION (__window).z = 1; __window->focused = TRUE; panel_show (__window->panel); widget_add_root (WIDGET (__window)); widget_push_context (WIDGET (__window)); __window->show_mode = __show_mode; __window->modal_result = MR_NONE; /* widget_set_current_widget (WIDGET (__window)); */ /* Is it okay if we think that showing of window */ /* is the same as focusing of window? */ WIDGET_CALL_CALLBACK (__window, focused, __window); /* Set focus to first widget in window */ if (WIDGET_CONTAINER_LENGTH (__window)) { widget_t *w; if (!WIDGET_CONTAINER_FOCUSED (__window)) { w = widget_first_focusable (WIDGET_CONTAINER (__window)); } else { w = WIDGET_CONTAINER_FOCUSED (__window); w->focused = FALSE; } if (w) { widget_set_focus (w); } } /* Draw window */ widget_redraw (WIDGET (__window)); if (__show_mode == WSM_MODAL) { widget_t *w; window_proc (__window); if (!__window->mode_changing) { if ((w = __window->focused_widget)) { WIDGET_CALL_CALLBACK (w, blured, w); } w_window_hide (__window); return __window->modal_result; } } return 0; }
/************************************************************************** Update all information in the player list dialog. **************************************************************************/ void real_players_dialog_update(void) { if(pPlayers_Dlg) { struct widget *pPlayer0, *pPlayer1; struct player *pPlayer; SDL_Rect dst0, dst1; int i; struct astring astr = ASTRING_INIT; /* redraw window */ widget_redraw(pPlayers_Dlg->pEndWidgetList); /* exit button -> neutral -> war -> casefire -> peace -> alliance */ pPlayer0 = pPlayers_Dlg->pEndWidgetList->prev->prev->prev->prev->prev->prev; do{ pPlayer0 = pPlayer0->prev; pPlayer1 = pPlayer0; pPlayer = pPlayer0->data.player; for (i = 0; i < num_player_dlg_columns; i++) { if (player_dlg_columns[i].show) { switch (player_dlg_columns[i].type) { case COL_TEXT: case COL_RIGHT_TEXT: astr_add_line(&astr, "%s: %s", player_dlg_columns[i].title, player_dlg_columns[i].func(pPlayer)); break; case COL_BOOLEAN: astr_add_line(&astr, "%s: %s", player_dlg_columns[i].title, player_dlg_columns[i].bool_func(pPlayer) ? _("Yes") : _("No")); break; default: break; } } } copy_chars_to_string16(pPlayer0->info_label, astr_str(&astr)); astr_free(&astr); /* now add some eye candy ... */ if(pPlayer1 != pPlayers_Dlg->pBeginWidgetList) { dst0.x = pPlayer0->size.x + pPlayer0->size.w / 2; dst0.y = pPlayer0->size.y + pPlayer0->size.h / 2; do{ pPlayer1 = pPlayer1->prev; if (have_diplomat_info_about(pPlayer) || have_diplomat_info_about(pPlayer1->data.player)) { dst1.x = pPlayer1->size.x + pPlayer1->size.w / 2; dst1.y = pPlayer1->size.y + pPlayer1->size.h / 2; switch (player_diplstate_get(pPlayer, pPlayer1->data.player)->type) { case DS_ARMISTICE: if(SDL_Client_Flags & CF_DRAW_PLAYERS_NEUTRAL_STATUS) { putline(pPlayer1->dst->surface, dst0.x, dst0.y, dst1.x, dst1.y, get_theme_color(COLOR_THEME_PLRDLG_ARMISTICE)); } break; case DS_WAR: if(SDL_Client_Flags & CF_DRAW_PLAYERS_WAR_STATUS) { putline(pPlayer1->dst->surface, dst0.x, dst0.y, dst1.x, dst1.y, get_theme_color(COLOR_THEME_PLRDLG_WAR)); } break; case DS_CEASEFIRE: if (SDL_Client_Flags & CF_DRAW_PLAYERS_CEASEFIRE_STATUS) { putline(pPlayer1->dst->surface, dst0.x, dst0.y, dst1.x, dst1.y, get_theme_color(COLOR_THEME_PLRDLG_CEASEFIRE)); } break; case DS_PEACE: if (SDL_Client_Flags & CF_DRAW_PLAYERS_PEACE_STATUS) { putline(pPlayer1->dst->surface, dst0.x, dst0.y, dst1.x, dst1.y, get_theme_color(COLOR_THEME_PLRDLG_PEACE)); } break; case DS_ALLIANCE: if (SDL_Client_Flags & CF_DRAW_PLAYERS_ALLIANCE_STATUS) { putline(pPlayer1->dst->surface, dst0.x, dst0.y, dst1.x, dst1.y, get_theme_color(COLOR_THEME_PLRDLG_ALLIANCE)); } break; default: /* no contact */ break; } } } while(pPlayer1 != pPlayers_Dlg->pBeginWidgetList); } } while(pPlayer0 != pPlayers_Dlg->pBeginWidgetList); /* -------------------- */ /* redraw */ redraw_group(pPlayers_Dlg->pBeginWidgetList, pPlayers_Dlg->pEndWidgetList->prev, 0); widget_mark_dirty(pPlayers_Dlg->pEndWidgetList); flush_dirty(); } }
/************************************************************************** Do default Widget action when pressed, and then call widget callback function. example for Button: set flags FW_Pressed redraw button ( pressed ) refresh screen ( to see result ) wait 300 ms ( to see result :) If exist (button callback function) then call (button callback function) Function normal return Widget ID. NOTE: NOZERO return of this function deterninate exit of MAIN_SDL_GAME_LOOP if ( pWidget->action ) if ( pWidget->action(pWidget) ) ID = 0; if widget callback function return = 0 then return NOZERO I default return (-1) from Widget callback functions. **************************************************************************/ Uint16 widget_pressed_action(struct widget * pWidget) { Uint16 ID = 0; if (!pWidget) { return 0; } widget_info_counter = 0; if (pInfo_Area) { sdl_dirty_rect(*pInfo_Area); FC_FREE(pInfo_Area); FREESURFACE(pInfo_Label); } switch (get_wtype(pWidget)) { case WT_TI_BUTTON: case WT_I_BUTTON: case WT_ICON: case WT_ICON2: if (Main.event.button.button == SDL_BUTTON_LEFT) { set_wstate(pWidget, FC_WS_PRESSED); widget_redraw(pWidget); widget_mark_dirty(pWidget); flush_dirty(); set_wstate(pWidget, FC_WS_SELLECTED); SDL_Delay(300); } ID = pWidget->ID; if (pWidget->action) { if (pWidget->action(pWidget)) { ID = 0; } } break; case WT_EDIT: { if (Main.event.button.button == SDL_BUTTON_LEFT) { bool ret, loop = ((get_wflags(pWidget) & WF_EDIT_LOOP) == WF_EDIT_LOOP); enum Edit_Return_Codes change; do { ret = FALSE; change = edit_field(pWidget); if (change != ED_FORCE_EXIT && (!loop || change != ED_RETURN)) { widget_redraw(pWidget); widget_mark_dirty(pWidget); flush_dirty(); } if (change != ED_FORCE_EXIT && change != ED_ESC && pWidget->action) { if (pWidget->action(pWidget)) { ID = 0; } } if (loop && change == ED_RETURN) { ret = TRUE; } } while(ret); ID = 0; } break; } case WT_VSCROLLBAR: case WT_HSCROLLBAR: if (Main.event.button.button == SDL_BUTTON_LEFT) { set_wstate(pWidget, FC_WS_PRESSED); widget_redraw(pWidget); widget_mark_dirty(pWidget); flush_dirty(); } ID = pWidget->ID; if (pWidget->action) { if (pWidget->action(pWidget)) { ID = 0; } } break; case WT_CHECKBOX: case WT_TCHECKBOX: if (Main.event.button.button == SDL_BUTTON_LEFT) { set_wstate(pWidget, FC_WS_PRESSED); widget_redraw(pWidget); widget_mark_dirty(pWidget); flush_dirty(); set_wstate(pWidget, FC_WS_SELLECTED); togle_checkbox(pWidget); SDL_Delay(300); } ID = pWidget->ID; if (pWidget->action) { if (pWidget->action(pWidget)) { ID = 0; } } break; case WT_COMBO: if (Main.event.button.button == SDL_BUTTON_LEFT) { set_wstate(pWidget, FC_WS_PRESSED); combo_popup(pWidget); } else { combo_popdown(pWidget); } break; default: ID = pWidget->ID; if (pWidget->action) { if (pWidget->action(pWidget) != 0) { ID = 0; } } break; } return ID; }
/** * Set shaded state of specified edit widget * * @param __edit - edit widget where shade state will be changed * @param __shaded - new state of shading */ void w_edit_set_shaded (w_edit_t *__edit, BOOL __shaded) { __edit->shaded = __shaded; widget_redraw (WIDGET (__edit)); }
/** * Handle a keydown callback * * @param __edit - edit received a callback * @param __ch - received character * @return zero if callback hasn't handled received character */ static int edit_keydown (w_edit_t *__edit, wint_t __ch) { _WIDGET_CALL_USER_CALLBACK (__edit, keydown, __edit, __ch); size_t spos, sscrolled; wchar_t *sbuffer = NULL; BOOL rollback_changes = FALSE, sshaded, reject_suffix = FALSE; /* Save data for rollback if validation failed */ spos = __edit->caret_pos; sscrolled = __edit->scrolled; sshaded = __edit->shaded; /* Buffer may be unallocated, so we need this checking */ if (__edit->text.data) { sbuffer = wcsdup (__edit->text.data); } switch (__ch) { /* Navigation */ case KEY_LEFT: if (__edit->caret_pos > 0) { --__edit->caret_pos; } __edit->shaded = FALSE; break; case KEY_RIGHT: if (__edit->caret_pos < wcslen (__edit->text.data)) { ++__edit->caret_pos; } __edit->shaded = FALSE; break; case KEY_HOME: /* * NOTE: IMHO using this stupid cycle is much more convenient * than hard-core patching edit_validate_scrolling(). * If you'll find a grateful solving of this * problem - you are welcome :) */ while (__edit->caret_pos > 0) { __edit->caret_pos--; edit_validate_scrolling (__edit); } __edit->shaded = FALSE; break; case KEY_END: while (__edit->caret_pos < wcslen (__edit->text.data)) { __edit->caret_pos++; edit_validate_scrolling (__edit); } __edit->shaded = FALSE; break; case KEY_DELETE: case KEY_BACKSPACE: { size_t i, n; n = wcslen (__edit->text.data); /* If pressed key is a `backspace`, we should */ /* move caret left by one position. */ if (__ch == KEY_BACKSPACE) { wchar_t c = __edit->text.data[n - 1], nch; int ch_width = wcwidth (c), dummy; /* Caret is already in zero position. */ /* No chars to delete */ if (!__edit->caret_pos) { break; } if (__edit->scrolled > 0) { /* This dark spell is needed to make cursor to */ /* at his old position */ /* * TODO: There is some troubles in this stuff */ while (__edit->scrolled > 0) { nch = __edit->text.data[__edit->scrolled]; dummy = wcwidth (nch); if (ch_width - dummy < 0) { break; } ch_width -= dummy; --__edit->scrolled; } } --__edit->caret_pos; } else { /* There are no chars at the right side from cursor */ /* so, there are no chars to delete */ if (__edit->caret_pos == n) { reject_suffix = TRUE; widget_redraw (WIDGET (__edit)); break; } } /* Shift text */ for (i = __edit->caret_pos; i < n - 1; i++) { __edit->text.data[i] = __edit->text.data[i + 1]; } /* Set new null-terminator */ __edit->text.data[n - 1] = 0; /* Send validating message */ if (CALL_CHECKVALIDNESS (__edit)) { /* We need rollback changes */ rollback_changes = TRUE; } __edit->shaded = FALSE; } break; case KEY_ESC: /* If user hits Escape button when there is guessed suffix of string */ /* we should cancel this guessing */ /* And if user hits Escape button when there is no suffix, */ /* we should do nothing */ if (__edit->suffix) { __edit->suffix = NULL; widget_redraw (WIDGET (__edit)); return TRUE; } else { return FALSE; } break; case KEY_RETURN: /* If user hits Return button when there is guessed suffix of string */ /* we should accept guessing string to main buffer */ /* And if user hits Return button when there is no suffix, */ /* we should do nothing */ if (__edit->suffix) { size_t len = wcslen (__edit->text.data), suff_len = wcslen (__edit->suffix); /* Realloc buffer if needed */ if (len + suff_len >= __edit->text.allocated) { __edit->text.data = realloc (__edit->text.data, (len + suff_len + 1) * sizeof (wchar_t)); __edit->text.allocated = len + suff_len; } /* Append auto-guessed suffix to main text buffer */ wcscat (__edit->text.data, __edit->suffix); /* Move caret to end of text */ __edit->caret_pos = len + suff_len; edit_validate_scrolling (__edit); __edit->suffix = NULL; widget_redraw (WIDGET (__edit)); return TRUE; } else { return FALSE; } break; default: #ifdef SCREEN_NCURSESW /* * FIXME: We'd better not use specific stuff of terminal * handling in widgets. */ if (is_ncurses_funckey (__ch)) { return FALSE; } #endif if (iswprint (__ch)) { /* Character is printable, so we have to handle this */ /* callback ourselves */ size_t i, len; /* Is edit in shaded state? */ if (__edit->shaded) { /* If edit is in shaded state, we should clear text */ /* and move caret to the beginning. */ /* We should also reset count of scrolled characters */ /* and finally, exit edit from shaded state. */ wcscpy (__edit->text.data, L""); __edit->caret_pos = __edit->scrolled = 0; __edit->shaded = FALSE; } len = wcslen (__edit->text.data); /* Synchronize buffer to make sure that there is */ /* enough memory to append character */ edit_sync_buffer (__edit); /* Shift buffer */ for (i = len; i > __edit->caret_pos; --i) { __edit->text.data[i] = __edit->text.data[i - 1]; } /* Insert new character into text */ __edit->text.data[__edit->caret_pos] = __ch; __edit->text.data[len + 1] = 0; /* Move caret to new position */ __edit->caret_pos++; /* Send validating message */ if (CALL_CHECKVALIDNESS (__edit)) { /* We need rollback changes */ rollback_changes = TRUE; } } else { return FALSE; } } /* If validator rejected buffer.. */ if (rollback_changes) { /* ..roll-back changes */ __edit->caret_pos = spos; __edit->scrolled = sscrolled; __edit->shaded = sshaded; /* Reject renewed buffer */ SAFE_FREE (__edit->text.data); if (sbuffer) { __edit->text.data = sbuffer; __edit->text.allocated = wcslen (sbuffer) + 1; /* Need this to prevent freeing buffer later */ sbuffer = NULL; } else { __edit->text.allocated = 0; } } else { if (!reject_suffix) { make_guessing (__edit); } else { __edit->suffix = NULL; } } SAFE_FREE (sbuffer); edit_validate_scrolling (__edit); widget_redraw (WIDGET (__edit)); return TRUE; }
/************************************************************************** ... **************************************************************************/ static void widget_core_unselect(struct widget *pwidget) { widget_redraw(pwidget); widget_flush(pwidget); }