📄 textsw_selection.c
字号:
position = first; ASSERT(position != ES_CANNOT_SET); break; case EI_SPAN_LINE: ev_span(folio->views, position, &first, &last_plus_one, (int)folio->span_level | EI_SPAN_LEFT_ONLY); position = first; ASSERT(position != ES_CANNOT_SET); break; } } last_plus_one = folio->adjust_pivot; } else { if (folio->span_level == EI_SPAN_CHAR) { last_plus_one = position+1; } else { ev_span(folio->views, position, &first, &last_plus_one, (int)folio->span_level | EI_SPAN_RIGHT_ONLY); ASSERT(first != ES_CANNOT_SET); } position = folio->adjust_pivot; } folio->span_level = save_span_level; }Do_Update: if (sel_type & (EV_SEL_PD_PRIMARY|EV_SEL_PD_SECONDARY)) { ro_bdry = TXTSW_IS_READ_ONLY(folio) ? last_plus_one : textsw_read_only_boundary_is_at(folio); if (last_plus_one <= ro_bdry) { sel_type &= ~(EV_SEL_PD_PRIMARY|EV_SEL_PD_SECONDARY); } } textsw_set_selection(VIEW_REP_TO_ABS(view), position, last_plus_one, sel_type); if (sel_type & EV_SEL_PRIMARY) { textsw_checkpoint_again(VIEW_REP_TO_ABS(view)); } ASSERT(allock());}pkg_privatestart_selection_tracking(view, ie) Textsw_view view; register Event *ie;{ register Textsw_folio folio = FOLIO_FOR_VIEW(view); textsw_flush_caches(view, TFC_STD); switch (event_action(ie)) { case TXTSW_ADJUST: folio->track_state |= TXTSW_TRACK_ADJUST; folio->last_click_x = ie->ie_locx; folio->last_click_y = ie->ie_locy; break; case TXTSW_POINT: { int delta; /* in millisecs */ folio->track_state |= TXTSW_TRACK_POINT; delta = (ie->ie_time.tv_sec - folio->last_point.tv_sec) * 1000; delta += ie->ie_time.tv_usec / 1000; delta -= folio->last_point.tv_usec / 1000; if (delta >= folio->multi_click_timeout) { folio->span_level = EI_SPAN_CHAR; } else { int delta_x = ie->ie_locx - folio->last_click_x; int delta_y = ie->ie_locy - folio->last_click_y; if (delta_x < 0) delta_x = -delta_x; if (delta_y < 0) delta_y = -delta_y; if (delta_x > folio->multi_click_space || delta_y > folio->multi_click_space) { folio->span_level = EI_SPAN_CHAR; } else { switch (folio->span_level) { case EI_SPAN_CHAR: folio->span_level = EI_SPAN_WORD; break; case EI_SPAN_WORD: folio->span_level = EI_SPAN_LINE; break; case EI_SPAN_LINE: folio->span_level = EI_SPAN_DOCUMENT; break; case EI_SPAN_DOCUMENT: folio->span_level = EI_SPAN_CHAR; break; default: folio->span_level = EI_SPAN_CHAR; } } } folio->last_click_x = ie->ie_locx; folio->last_click_y = ie->ie_locy; break; } default: LINT_IGNORE(ASSUME(0)); } if ((folio->state & TXTSW_CONTROL_DOWN) && !TXTSW_IS_READ_ONLY(folio)) folio->state |= TXTSW_PENDING_DELETE; update_selection(view, ie);}static Es_indexdo_balance_beam(view, x, y, first, last_plus_one) Textsw_view view; int x, y; register Es_index first, last_plus_one;{ register Ev_handle e_view; Es_index new_insert; register Textsw_folio folio = FOLIO_FOR_VIEW(view); register int delta; int lt_index; struct rect rect; if (folio->track_state & TXTSW_TRACK_ADJUST) { return((first == folio->adjust_pivot) ? last_plus_one : first); } new_insert = last_plus_one; e_view = view->e_view; /* * When the user has multi-clicked up to select enough text to * occupy multiple physical display lines, linearize the * distance to the endpoints, then do the balance beam. */ if (ev_xy_in_view(e_view, first, <_index, &rect) != EV_XY_VISIBLE) goto Did_balance; delta = x - rect.r_left; delta += ((y - rect.r_top) / rect.r_height) * e_view->rect.r_width; switch (ev_xy_in_view(e_view, last_plus_one, <_index, &rect)) { case EV_XY_BELOW: /* * SPECIAL CASE: if last_plus_one was at the start of * the last line in the line table, it is still EV_XY_BELOW, * and we should still treat it like EV_XY_VISIBLE, * with rect.r_left == e_view->rect.r_left. */ if (last_plus_one != ft_position_for_index( e_view->line_table, e_view->line_table.last_plus_one - 1)) { new_insert = first; goto Did_balance; } else { rect.r_left = e_view->rect.r_left; } /* FALL THROUGH */ case EV_XY_VISIBLE: if (e_view->rect.r_left == rect.r_left) { /* last_plus_one must be a new_line, so back up */ if (ev_xy_in_view(e_view, last_plus_one-1, <_index, &rect) != EV_XY_VISIBLE) { new_insert = first; goto Did_balance; } if ((x >= rect.r_left) && (y >= rect.r_top) && (y <= rect_bottom(&rect))) { /* * SPECIAL CASE: Selecting in the white-space past the end * of a line puts the insertion point at the end of that * line, rather than the beginning of the next line. * * SPECIAL SPECIAL CASE: Selecting in the white-space past * the end of a wrapped line (due to wide margins * or word wrapping) puts the insertion point at the * beginning of the next line. */ if (ev_considered_for_line(e_view, lt_index) >= ev_index_for_line(e_view, lt_index+1)) new_insert = last_plus_one; else new_insert = last_plus_one-1; goto Did_balance; } } break; default: new_insert = first; goto Did_balance; } if (y < rect.r_top) rect.r_left += (((rect.r_top - y) / rect.r_height) + 1) * e_view->rect.r_width; if (delta < rect.r_left - x) new_insert = first;Did_balance: return(new_insert);}staticdone_tracking(view, x, y) Textsw_view view; register int x, y;{ register Textsw_folio folio = FOLIO_FOR_VIEW(view); if (((folio->track_state & TXTSW_TRACK_SECONDARY) == 0) || (folio->func_state & TXTSW_FUNC_PUT)) { Es_index first, last_plus_one, new_insert; (void) ev_get_selection(folio->views, &first, &last_plus_one, (unsigned)((folio->func_state & TXTSW_FUNC_PUT) ? EV_SEL_SECONDARY : EV_SEL_PRIMARY)); new_insert = do_balance_beam(view, x, y, first, last_plus_one); if (new_insert != ES_INFINITY) { first = textsw_set_insert(folio, new_insert); ASSUME(first != ES_CANNOT_SET); } } folio->track_state &= ~(TXTSW_TRACK_ADJUST | TXTSW_TRACK_ADJUST_END | TXTSW_TRACK_POINT); /* Reset pending-delete state (although we may be in the middle of a * multi-click, there is no way to know that and we must reset now in * case user has ADJUST_IS_PENDING_DELETE or had CONTROL_DOWN). */ if ((folio->func_state & TXTSW_FUNC_DELETE) == 0) folio->state &= ~TXTSW_PENDING_DELETE;}pkg_private inttrack_selection(view, ie) Textsw_view view; register Event *ie;{ int do_done_tracking = 0; register Textsw_folio folio = FOLIO_FOR_VIEW(view); if (win_inputnegevent(ie)) { switch (event_action(ie)) { case TXTSW_POINT: { folio->last_point = ie->ie_time; break; } case TXTSW_ADJUST: { folio->last_adjust = ie->ie_time; break; } default: if ((folio->track_state & TXTSW_TRACK_SECONDARY) || (folio->func_state & TXTSW_FUNC_ALL)) { done_tracking(view, ie->ie_locx, ie->ie_locy); return(FALSE); /* Don't ignore: FUNC up */ } else { return(TRUE); /* Ignore: other key up */ } } done_tracking(view, ie->ie_locx, ie->ie_locy); } else { switch (event_action(ie)) { case SCROLL_EXIT: /* * if we were tracking before entering the scrollbar * and the equivalent mouse button is up on exiting the * scrollbar then quit tracking. */ if (folio->track_state & TXTSW_TRACK_ADJUST) { do_done_tracking = (win_get_vuid_value( WIN_FD_FOR_VIEW(view), TXTSW_ADJUST) == 0); } else if (folio->track_state & TXTSW_TRACK_POINT) { do_done_tracking = (win_get_vuid_value( WIN_FD_FOR_VIEW(view), TXTSW_POINT) == 0); } if (do_done_tracking) { /* use x, y from SCROLL_ENTER */ done_tracking(view, folio->last_click_x, folio->last_click_y); } break; case LOC_MOVE: update_selection(view, ie); break; case LOC_WINEXIT: done_tracking(view, ie->ie_locx, ie->ie_locy); textsw_may_win_exit(folio); break; default:; /* ignore it */ } } return(TRUE);}/* =============================================================== * * Utilities to simplify dealing with selections. * * =============================================================== */pkg_private inttextsw_get_selection_as_int(folio, type, default_value) register Textsw_folio folio; unsigned type; int default_value;{ Textsw_selection_object selection; int result; char buf[20]; textsw_init_selection_object(folio, &selection, buf, sizeof(buf), 0); result = textsw_func_selection_internal( folio, &selection, type, TFS_FILL_ALWAYS); if (TFS_IS_ERROR(result)) { result = default_value; } else { buf[selection.buf_len] = '\0'; result = atoi(buf); } return(result);}pkg_private inttextsw_get_selection_as_string(folio, type, buf, buf_max_len) register Textsw_folio folio; unsigned type; char *buf;{ Textsw_selection_object selection; int result; textsw_init_selection_object(folio, &selection, buf, buf_max_len, 0); result = textsw_func_selection_internal( folio, &selection, type, TFS_FILL_ALWAYS); if (TFS_IS_ERROR(result) || (selection.buf_len == 0)) { result = 0; } else { buf[selection.buf_len] = '\0'; result = selection.buf_len+1; } return(result);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -