Select lines when clicking/dragging over line numbers
This commit is contained in:
parent
4854a9a357
commit
3008379635
@ -7,11 +7,13 @@ mooedit_tools_DATA = context.cfg menu.cfg filters.xml
|
||||
dummy_targets = \
|
||||
moocommand-exe.o \
|
||||
moocommand-exe-private.o \
|
||||
moolangmgr-private.o
|
||||
moolangmgr-private.o \
|
||||
mootextview-private.o
|
||||
CLEANFILES = $(dummy_targets)
|
||||
moocommand-exe.o: moocommand-exe-unix.o ; echo stamp > $(@F)
|
||||
moocommand-exe-private.o: moocommand-exe-unix.o ; echo stamp > $(@F)
|
||||
moolangmgr-private.o: moolangmgr.o ; echo stamp > $(@F)
|
||||
mootextview-private.o: mootextview.o ; echo stamp > $(@F)
|
||||
|
||||
unix_sources = \
|
||||
moocommand-exe-unix.c
|
||||
|
@ -387,11 +387,11 @@ extend_selection (MooTextView *view,
|
||||
inline static void
|
||||
clear_drag_stuff (MooTextView *view)
|
||||
{
|
||||
view->priv->drag_moved = FALSE;
|
||||
view->priv->drag_type = MOO_TEXT_VIEW_DRAG_NONE;
|
||||
view->priv->drag_start_x = -1;
|
||||
view->priv->drag_start_y = -1;
|
||||
view->priv->drag_button = GDK_BUTTON_RELEASE;
|
||||
view->priv->dnd.moved = FALSE;
|
||||
view->priv->dnd.type = MOO_TEXT_VIEW_DRAG_NONE;
|
||||
view->priv->dnd.start_x = -1;
|
||||
view->priv->dnd.start_y = -1;
|
||||
view->priv->dnd.button = GDK_BUTTON_RELEASE;
|
||||
}
|
||||
|
||||
#define get_buf(view) \
|
||||
@ -428,17 +428,19 @@ left_window_to_line (GtkTextView *text_view,
|
||||
|
||||
static gboolean
|
||||
left_window_click (GtkTextView *text_view,
|
||||
GdkEventButton *event)
|
||||
GdkEventButton *event,
|
||||
gboolean *line_numbers)
|
||||
{
|
||||
int line, window_width;
|
||||
int window_width;
|
||||
MooTextView *view = MOO_TEXT_VIEW (text_view);
|
||||
|
||||
*line_numbers = FALSE;
|
||||
gdk_drawable_get_size (event->window, &window_width, NULL);
|
||||
|
||||
if (view->priv->lm.show_icons && event->x >= 0 && event->x < view->priv->lm.icon_width)
|
||||
{
|
||||
gboolean ret;
|
||||
line = left_window_to_line (text_view, event->y);
|
||||
int line = left_window_to_line (text_view, event->y);
|
||||
g_signal_emit_by_name (text_view, "line-mark-clicked", line, &ret);
|
||||
return ret;
|
||||
}
|
||||
@ -448,6 +450,7 @@ left_window_click (GtkTextView *text_view,
|
||||
{
|
||||
MooTextBuffer *buffer = MOO_TEXT_BUFFER (gtk_text_view_get_buffer (text_view));
|
||||
MooFold *fold;
|
||||
int line;
|
||||
|
||||
line = left_window_to_line (text_view, event->y);
|
||||
fold = moo_text_buffer_get_fold_at_line (buffer, line);
|
||||
@ -462,10 +465,64 @@ left_window_click (GtkTextView *text_view,
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (view->priv->lm.show_numbers &&
|
||||
event->x >= view->priv->lm.icon_width &&
|
||||
event->x < view->priv->lm.icon_width + view->priv->lm.numbers_width)
|
||||
{
|
||||
*line_numbers = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
select_range (GtkTextBuffer *buffer,
|
||||
const GtkTextIter *sel_bound,
|
||||
const GtkTextIter *cursor)
|
||||
{
|
||||
GtkTextIter sel_start, sel_end;
|
||||
|
||||
gtk_text_buffer_get_iter_at_mark (buffer, &sel_start, gtk_text_buffer_get_selection_bound (buffer));
|
||||
gtk_text_buffer_get_iter_at_mark (buffer, &sel_end, gtk_text_buffer_get_insert (buffer));
|
||||
|
||||
if (gtk_text_iter_compare (sel_bound, &sel_start))
|
||||
{
|
||||
if (gtk_text_iter_compare (cursor, &sel_end))
|
||||
gtk_text_buffer_select_range (buffer, cursor, sel_bound);
|
||||
else
|
||||
gtk_text_buffer_move_mark_by_name (buffer, "selection_bound", sel_bound);
|
||||
}
|
||||
else if (gtk_text_iter_compare (cursor, &sel_end))
|
||||
{
|
||||
gtk_text_buffer_move_mark_by_name (buffer, "insert", cursor);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
select_lines (MooTextView *view,
|
||||
int y)
|
||||
{
|
||||
GtkTextView *text_view;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter start, end;
|
||||
int cmp;
|
||||
|
||||
text_view = GTK_TEXT_VIEW (view);
|
||||
buffer = gtk_text_view_get_buffer (text_view);
|
||||
|
||||
start = view->priv->dnd.start_iter;
|
||||
gtk_text_view_get_line_at_y (text_view, &end, y, NULL);
|
||||
cmp = gtk_text_iter_compare (&start, &end);
|
||||
|
||||
if (cmp <= 0)
|
||||
gtk_text_iter_forward_line (&end);
|
||||
else
|
||||
gtk_text_iter_forward_line (&start);
|
||||
|
||||
select_range (buffer, &start, &end);
|
||||
}
|
||||
|
||||
|
||||
static void start_drag_scroll (MooTextView *view);
|
||||
static void stop_drag_scroll (MooTextView *view);
|
||||
@ -486,6 +543,8 @@ _moo_text_view_button_press_event (GtkWidget *widget,
|
||||
GtkTextBuffer *buffer;
|
||||
int x, y;
|
||||
GtkTextIter iter;
|
||||
gboolean line_numbers = FALSE;
|
||||
gboolean ret;
|
||||
|
||||
text_view = GTK_TEXT_VIEW (widget);
|
||||
text_view_unobscure_mouse_cursor (text_view);
|
||||
@ -496,7 +555,10 @@ _moo_text_view_button_press_event (GtkWidget *widget,
|
||||
break;
|
||||
|
||||
case GTK_TEXT_WINDOW_LEFT:
|
||||
return left_window_click (text_view, event);
|
||||
ret = left_window_click (text_view, event, &line_numbers);
|
||||
if (!line_numbers)
|
||||
return ret;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
@ -508,40 +570,89 @@ _moo_text_view_button_press_event (GtkWidget *widget,
|
||||
|
||||
text_view_reset_im_context (text_view);
|
||||
|
||||
gtk_text_view_window_to_buffer_coords (text_view, GTK_TEXT_WINDOW_TEXT,
|
||||
(int)event->x, (int)event->y, &x, &y);
|
||||
|
||||
gtk_text_view_get_iter_at_location (text_view, &iter, x, y);
|
||||
if (!line_numbers)
|
||||
{
|
||||
gtk_text_view_window_to_buffer_coords (text_view, GTK_TEXT_WINDOW_TEXT,
|
||||
event->x, event->y, &x, &y);
|
||||
gtk_text_view_get_iter_at_location (text_view, &iter, x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
int line;
|
||||
gtk_text_view_window_to_buffer_coords (text_view, GTK_TEXT_WINDOW_LEFT,
|
||||
event->x, event->y, &x, &y);
|
||||
line = left_window_to_line (text_view, event->y);
|
||||
gtk_text_buffer_get_iter_at_line (buffer, &iter, line);
|
||||
}
|
||||
|
||||
if (event->type == GDK_BUTTON_PRESS)
|
||||
{
|
||||
if (event->button == 1) {
|
||||
if (event->button == 1)
|
||||
{
|
||||
GtkTextIter sel_start, sel_end;
|
||||
|
||||
view->priv->drag_button = GDK_BUTTON_PRESS;
|
||||
view->priv->drag_start_x = x;
|
||||
view->priv->drag_start_y = y;
|
||||
view->priv->dnd.button = GDK_BUTTON_PRESS;
|
||||
view->priv->dnd.start_x = x;
|
||||
view->priv->dnd.start_y = y;
|
||||
|
||||
/* if clicked in selected, start drag */
|
||||
if (gtk_text_buffer_get_selection_bounds (buffer, &sel_start, &sel_end))
|
||||
if (!line_numbers && gtk_text_buffer_get_selection_bounds (buffer, &sel_start, &sel_end))
|
||||
{
|
||||
gtk_text_iter_order (&sel_start, &sel_end);
|
||||
if (gtk_text_iter_in_range (&iter, &sel_start, &sel_end)) {
|
||||
|
||||
if (gtk_text_iter_in_range (&iter, &sel_start, &sel_end))
|
||||
{
|
||||
/* clicked inside of selection,
|
||||
* set up drag and return */
|
||||
view->priv->drag_type = MOO_TEXT_VIEW_DRAG_DRAG;
|
||||
view->priv->dnd.type = MOO_TEXT_VIEW_DRAG_DRAG;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* otherwise, clear selection, and position cursor at clicked point */
|
||||
if (event->state & GDK_SHIFT_MASK)
|
||||
gtk_text_buffer_move_mark (buffer,
|
||||
gtk_text_buffer_get_insert (buffer),
|
||||
&iter);
|
||||
view->priv->dnd.start_iter = iter;
|
||||
|
||||
if (!line_numbers)
|
||||
{
|
||||
/* otherwise, clear selection, and position cursor at clicked point */
|
||||
if (event->state & GDK_SHIFT_MASK)
|
||||
{
|
||||
gtk_text_buffer_get_iter_at_mark (buffer,
|
||||
&view->priv->dnd.start_iter,
|
||||
gtk_text_buffer_get_selection_bound (buffer));
|
||||
gtk_text_buffer_move_mark (buffer,
|
||||
gtk_text_buffer_get_insert (buffer),
|
||||
&iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_text_buffer_place_cursor (buffer, &iter);
|
||||
}
|
||||
}
|
||||
else
|
||||
gtk_text_buffer_place_cursor (buffer, &iter);
|
||||
view->priv->drag_type = MOO_TEXT_VIEW_DRAG_SELECT;
|
||||
{
|
||||
if (event->state & GDK_SHIFT_MASK)
|
||||
{
|
||||
gtk_text_buffer_get_iter_at_mark (buffer,
|
||||
&view->priv->dnd.start_iter,
|
||||
gtk_text_buffer_get_selection_bound (buffer));
|
||||
if (gtk_text_iter_starts_line (&view->priv->dnd.start_iter))
|
||||
{
|
||||
GtkTextIter tmp;
|
||||
gtk_text_buffer_get_iter_at_mark (buffer, &tmp,
|
||||
gtk_text_buffer_get_insert (buffer));
|
||||
if (gtk_text_iter_compare (&view->priv->dnd.start_iter, &tmp) > 0)
|
||||
gtk_text_iter_backward_line (&view->priv->dnd.start_iter);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_text_iter_set_line_offset (&view->priv->dnd.start_iter, 0);
|
||||
select_lines (view, y);
|
||||
}
|
||||
|
||||
if (!line_numbers)
|
||||
view->priv->dnd.type = MOO_TEXT_VIEW_DRAG_SELECT;
|
||||
else
|
||||
view->priv->dnd.type = MOO_TEXT_VIEW_DRAG_SELECT_LINES;
|
||||
}
|
||||
else if (event->button == 3 && MOO_IS_EDIT (widget))
|
||||
{
|
||||
@ -567,38 +678,39 @@ _moo_text_view_button_press_event (GtkWidget *widget,
|
||||
gtk_text_buffer_place_cursor (buffer, &iter);
|
||||
}
|
||||
|
||||
view->priv->drag_button = GDK_2BUTTON_PRESS;
|
||||
view->priv->drag_start_x = x;
|
||||
view->priv->drag_start_y = y;
|
||||
view->priv->drag_type = MOO_TEXT_VIEW_DRAG_SELECT;
|
||||
view->priv->dnd.button = GDK_2BUTTON_PRESS;
|
||||
view->priv->dnd.start_x = x;
|
||||
view->priv->dnd.start_y = y;
|
||||
view->priv->dnd.type = MOO_TEXT_VIEW_DRAG_SELECT;
|
||||
|
||||
bound = iter;
|
||||
if (extend_selection (view, MOO_TEXT_SELECT_WORDS, &iter, &bound))
|
||||
gtk_text_buffer_select_range (buffer, &iter, &bound);
|
||||
select_range (buffer, &bound, &iter);
|
||||
}
|
||||
else if (event->type == GDK_3BUTTON_PRESS && event->button == 1)
|
||||
{
|
||||
GtkTextIter bound = iter;
|
||||
view->priv->drag_button = GDK_3BUTTON_PRESS;
|
||||
view->priv->drag_start_x = x;
|
||||
view->priv->drag_start_y = y;
|
||||
view->priv->drag_type = MOO_TEXT_VIEW_DRAG_SELECT;
|
||||
view->priv->dnd.button = GDK_3BUTTON_PRESS;
|
||||
view->priv->dnd.start_x = x;
|
||||
view->priv->dnd.start_y = y;
|
||||
view->priv->dnd.type = MOO_TEXT_VIEW_DRAG_SELECT;
|
||||
if (extend_selection (view, MOO_TEXT_SELECT_LINES, &iter, &bound))
|
||||
gtk_text_buffer_select_range (buffer, &iter, &bound);
|
||||
select_range (buffer, &bound, &iter);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_moo_text_view_button_release_event (GtkWidget *widget,
|
||||
_moo_text_view_button_release_event (GtkWidget *widget,
|
||||
G_GNUC_UNUSED GdkEventButton *event)
|
||||
{
|
||||
GtkTextView *text_view = GTK_TEXT_VIEW (widget);
|
||||
MooTextView *view = MOO_TEXT_VIEW (widget);
|
||||
GtkTextIter iter;
|
||||
|
||||
switch (view->priv->drag_type) {
|
||||
switch (view->priv->dnd.type)
|
||||
{
|
||||
case MOO_TEXT_VIEW_DRAG_NONE:
|
||||
/* it may happen after right-click, or clicking outside
|
||||
* of widget or something like that
|
||||
@ -606,6 +718,7 @@ _moo_text_view_button_release_event (GtkWidget *widget,
|
||||
break;
|
||||
|
||||
case MOO_TEXT_VIEW_DRAG_SELECT:
|
||||
case MOO_TEXT_VIEW_DRAG_SELECT_LINES:
|
||||
/* everything should be done already in button_press and
|
||||
* motion_notify handlers */
|
||||
stop_drag_scroll (view);
|
||||
@ -614,21 +727,15 @@ _moo_text_view_button_release_event (GtkWidget *widget,
|
||||
case MOO_TEXT_VIEW_DRAG_DRAG:
|
||||
/* if we were really dragging, drop it
|
||||
* otherwise, it was just a single click in selected text */
|
||||
if (view->priv->drag_moved)
|
||||
if (view->priv->dnd.moved)
|
||||
{
|
||||
/* parent should handle drag */
|
||||
clear_drag_stuff (view);
|
||||
g_return_val_if_reached (FALSE);
|
||||
}
|
||||
gtk_text_view_get_iter_at_location (text_view, &iter,
|
||||
view->priv->drag_start_x,
|
||||
view->priv->drag_start_y);
|
||||
gtk_text_buffer_place_cursor (gtk_text_view_get_buffer (text_view),
|
||||
&iter);
|
||||
&view->priv->dnd.start_iter);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
clear_drag_stuff (view);
|
||||
@ -653,26 +760,51 @@ _moo_text_view_motion_event (GtkWidget *widget,
|
||||
|
||||
text_view_unobscure_mouse_cursor (text_view);
|
||||
|
||||
if (!view->priv->drag_type) return FALSE;
|
||||
if (!view->priv->dnd.type)
|
||||
return FALSE;
|
||||
|
||||
if (event->is_hint)
|
||||
{
|
||||
gdk_window_get_pointer (event->window, &event_x, &event_y, NULL);
|
||||
else {
|
||||
event_x = (int)event->x;
|
||||
event_y = (int)event->y;
|
||||
}
|
||||
else
|
||||
{
|
||||
event_x = event->x;
|
||||
event_y = event->y;
|
||||
}
|
||||
|
||||
gtk_text_view_window_to_buffer_coords (text_view,
|
||||
gtk_text_view_get_window_type (text_view, event->window),
|
||||
event_x, event_y, &x, &y);
|
||||
|
||||
if (view->priv->dnd.type == MOO_TEXT_VIEW_DRAG_SELECT_LINES)
|
||||
{
|
||||
GdkRectangle rect;
|
||||
GdkWindow *window;
|
||||
|
||||
window = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_LEFT);
|
||||
gtk_text_view_get_visible_rect (text_view, &rect);
|
||||
|
||||
select_lines (view, y);
|
||||
|
||||
if (y < rect.y || y >= rect.y + rect.height)
|
||||
start_drag_scroll (view);
|
||||
else
|
||||
stop_drag_scroll (view);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gtk_text_view_get_iter_at_location (text_view, &iter, x, y);
|
||||
|
||||
if (view->priv->drag_type == MOO_TEXT_VIEW_DRAG_SELECT) {
|
||||
if (view->priv->dnd.type == MOO_TEXT_VIEW_DRAG_SELECT)
|
||||
{
|
||||
GdkRectangle rect;
|
||||
GtkTextIter start;
|
||||
MooTextSelectionType t;
|
||||
GtkTextBuffer *buffer;
|
||||
|
||||
view->priv->drag_moved = TRUE;
|
||||
view->priv->dnd.moved = TRUE;
|
||||
gtk_text_view_get_visible_rect (text_view, &rect);
|
||||
|
||||
if (OUTSIDE (x, y, rect))
|
||||
@ -684,47 +816,34 @@ _moo_text_view_motion_event (GtkWidget *widget,
|
||||
stop_drag_scroll (view);
|
||||
|
||||
buffer = gtk_text_view_get_buffer (text_view);
|
||||
gtk_text_view_get_iter_at_location (text_view, &start,
|
||||
view->priv->drag_start_x,
|
||||
view->priv->drag_start_y);
|
||||
start = view->priv->dnd.start_iter;
|
||||
|
||||
if (view->priv->drag_button == GDK_BUTTON_PRESS)
|
||||
if (view->priv->dnd.button == GDK_BUTTON_PRESS)
|
||||
t = MOO_TEXT_SELECT_CHARS;
|
||||
else if (view->priv->drag_button == GDK_2BUTTON_PRESS)
|
||||
else if (view->priv->dnd.button == GDK_2BUTTON_PRESS)
|
||||
t = MOO_TEXT_SELECT_WORDS;
|
||||
else
|
||||
t = MOO_TEXT_SELECT_LINES;
|
||||
|
||||
if (extend_selection (view, t, &start, &iter))
|
||||
gtk_text_buffer_select_range (buffer, &iter, &start);
|
||||
select_range (buffer, &start, &iter);
|
||||
else
|
||||
gtk_text_buffer_place_cursor (buffer, &iter);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
/* this piece is from gtktextview.c */
|
||||
int x, y;
|
||||
gdk_window_get_pointer (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT),
|
||||
&x, &y, NULL);
|
||||
|
||||
if (gtk_drag_check_threshold (widget,
|
||||
view->priv->drag_start_x,
|
||||
view->priv->drag_start_y,
|
||||
view->priv->dnd.start_x,
|
||||
view->priv->dnd.start_y,
|
||||
x, y))
|
||||
{
|
||||
GtkTextIter iter;
|
||||
int buffer_x, buffer_y;
|
||||
|
||||
gtk_text_view_window_to_buffer_coords (text_view,
|
||||
GTK_TEXT_WINDOW_TEXT,
|
||||
view->priv->drag_start_x,
|
||||
view->priv->drag_start_y,
|
||||
&buffer_x,
|
||||
&buffer_y);
|
||||
|
||||
gtk_text_view_get_iter_at_location (text_view, &iter, buffer_x, buffer_y);
|
||||
|
||||
view->priv->drag_type = MOO_TEXT_VIEW_DRAG_NONE;
|
||||
text_view_start_selection_dnd (text_view, &iter, event);
|
||||
view->priv->dnd.type = MOO_TEXT_VIEW_DRAG_NONE;
|
||||
text_view_start_selection_dnd (text_view, &view->priv->dnd.start_iter, event);
|
||||
}
|
||||
}
|
||||
|
||||
@ -791,7 +910,7 @@ _moo_text_view_extend_selection (MooTextView *view,
|
||||
{
|
||||
int ch_class;
|
||||
|
||||
if (!order && view->priv->double_click_selects_brackets)
|
||||
if (!order && view->priv->dnd.double_click_selects_brackets)
|
||||
{
|
||||
GtkTextIter rstart = *start;
|
||||
if (moo_text_iter_at_bracket (&rstart) &&
|
||||
@ -803,14 +922,14 @@ _moo_text_view_extend_selection (MooTextView *view,
|
||||
{
|
||||
if (gtk_text_iter_compare (&rstart, &rend) > 0)
|
||||
{ /* <rend>( <rstart>) */
|
||||
if (view->priv->double_click_selects_inside)
|
||||
if (view->priv->dnd.double_click_selects_inside)
|
||||
gtk_text_iter_forward_char (&rend);
|
||||
else
|
||||
gtk_text_iter_forward_char (&rstart);
|
||||
}
|
||||
else
|
||||
{ /* <rstart>( <rend>) */
|
||||
if (view->priv->double_click_selects_inside)
|
||||
if (view->priv->dnd.double_click_selects_inside)
|
||||
gtk_text_iter_forward_char (&rstart);
|
||||
else
|
||||
gtk_text_iter_forward_char (&rend);
|
||||
@ -868,8 +987,8 @@ _moo_text_view_extend_selection (MooTextView *view,
|
||||
static void
|
||||
start_drag_scroll (MooTextView *view)
|
||||
{
|
||||
if (!view->priv->drag_scroll_timeout)
|
||||
view->priv->drag_scroll_timeout =
|
||||
if (!view->priv->dnd.scroll_timeout)
|
||||
view->priv->dnd.scroll_timeout =
|
||||
_moo_timeout_add (SCROLL_TIMEOUT,
|
||||
(GSourceFunc)drag_scroll_timeout_func,
|
||||
view);
|
||||
@ -880,9 +999,9 @@ start_drag_scroll (MooTextView *view)
|
||||
static void
|
||||
stop_drag_scroll (MooTextView *view)
|
||||
{
|
||||
if (view->priv->drag_scroll_timeout)
|
||||
g_source_remove (view->priv->drag_scroll_timeout);
|
||||
view->priv->drag_scroll_timeout = 0;
|
||||
if (view->priv->dnd.scroll_timeout)
|
||||
g_source_remove (view->priv->dnd.scroll_timeout);
|
||||
view->priv->dnd.scroll_timeout = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -896,7 +1015,7 @@ drag_scroll_timeout_func (MooTextView *view)
|
||||
MooTextSelectionType t;
|
||||
GtkTextBuffer *buffer;
|
||||
|
||||
g_assert (view->priv->drag_type == MOO_TEXT_VIEW_DRAG_SELECT);
|
||||
g_assert (view->priv->dnd.type == MOO_TEXT_VIEW_DRAG_SELECT);
|
||||
|
||||
text_view = GTK_TEXT_VIEW (view);
|
||||
|
||||
@ -909,18 +1028,18 @@ drag_scroll_timeout_func (MooTextView *view)
|
||||
buffer = gtk_text_view_get_buffer (text_view);
|
||||
|
||||
gtk_text_view_get_iter_at_location (text_view, &start,
|
||||
view->priv->drag_start_x,
|
||||
view->priv->drag_start_y);
|
||||
view->priv->dnd.start_x,
|
||||
view->priv->dnd.start_y);
|
||||
|
||||
if (view->priv->drag_button == GDK_BUTTON_PRESS)
|
||||
if (view->priv->dnd.button == GDK_BUTTON_PRESS)
|
||||
t = MOO_TEXT_SELECT_CHARS;
|
||||
else if (view->priv->drag_button == GDK_2BUTTON_PRESS)
|
||||
else if (view->priv->dnd.button == GDK_2BUTTON_PRESS)
|
||||
t = MOO_TEXT_SELECT_WORDS;
|
||||
else
|
||||
t = MOO_TEXT_SELECT_LINES;
|
||||
|
||||
if (extend_selection (view, t, &start, &iter))
|
||||
gtk_text_buffer_select_range (buffer, &iter, &start);
|
||||
select_range (buffer, &start, &iter);
|
||||
else
|
||||
gtk_text_buffer_place_cursor (buffer, &iter);
|
||||
gtk_text_view_scroll_mark_onscreen (text_view,
|
||||
|
@ -64,7 +64,8 @@ void _moo_text_view_set_line_numbers_font (MooTextView *view,
|
||||
typedef enum {
|
||||
MOO_TEXT_VIEW_DRAG_NONE = 0,
|
||||
MOO_TEXT_VIEW_DRAG_SELECT,
|
||||
MOO_TEXT_VIEW_DRAG_DRAG
|
||||
MOO_TEXT_VIEW_DRAG_DRAG,
|
||||
MOO_TEXT_VIEW_DRAG_SELECT_LINES
|
||||
} MooTextViewDragType;
|
||||
|
||||
typedef enum {
|
||||
@ -109,6 +110,7 @@ struct _MooTextViewPrivate {
|
||||
int icon_width;
|
||||
gboolean show_numbers;
|
||||
int digit_width;
|
||||
int numbers_width;
|
||||
PangoFontDescription *numbers_font;
|
||||
gboolean show_folds;
|
||||
int fold_width;
|
||||
@ -149,14 +151,17 @@ struct _MooTextViewPrivate {
|
||||
/***********************************************************************/
|
||||
/* Selection and drag
|
||||
*/
|
||||
guint drag_scroll_timeout;
|
||||
GdkEventType drag_button;
|
||||
MooTextViewDragType drag_type;
|
||||
int drag_start_x;
|
||||
int drag_start_y;
|
||||
guint drag_moved : 1;
|
||||
guint double_click_selects_brackets : 1;
|
||||
guint double_click_selects_inside : 1;
|
||||
struct {
|
||||
guint scroll_timeout;
|
||||
GdkEventType button;
|
||||
MooTextViewDragType type;
|
||||
int start_x; /* buffer coordinates */
|
||||
int start_y; /* buffer coordinates */
|
||||
GtkTextIter start_iter;
|
||||
guint moved : 1;
|
||||
guint double_click_selects_brackets : 1;
|
||||
guint double_click_selects_inside : 1;
|
||||
} dnd;
|
||||
|
||||
/***********************************************************************/
|
||||
/* Drag'n'drop from outside
|
||||
|
@ -180,6 +180,8 @@ static gboolean has_box_at_iter (MooTextView *view,
|
||||
static gboolean text_iter_forward_visible_line (MooTextView *view,
|
||||
GtkTextIter *iter,
|
||||
int *line);
|
||||
static int get_border_window_size (GtkTextView *text_view,
|
||||
GtkTextWindowType type);
|
||||
|
||||
|
||||
enum {
|
||||
@ -257,6 +259,7 @@ static void moo_text_view_class_init (MooTextViewClass *klass)
|
||||
gobject_class->constructor = moo_text_view_constructor;
|
||||
gobject_class->finalize = moo_text_view_finalize;
|
||||
|
||||
|
||||
widget_class->button_press_event = _moo_text_view_button_press_event;
|
||||
widget_class->button_release_event = _moo_text_view_button_release_event;
|
||||
widget_class->motion_notify_event = _moo_text_view_motion_event;
|
||||
@ -640,10 +643,10 @@ static void moo_text_view_init (MooTextView *view)
|
||||
view->priv->current_line_color = gdk_color_copy (&clr);
|
||||
gdk_color_parse (LIGHT_BLUE, view->priv->current_line_color);
|
||||
|
||||
view->priv->drag_button = GDK_BUTTON_RELEASE;
|
||||
view->priv->drag_type = MOO_TEXT_VIEW_DRAG_NONE;
|
||||
view->priv->drag_start_x = -1;
|
||||
view->priv->drag_start_y = -1;
|
||||
view->priv->dnd.button = GDK_BUTTON_RELEASE;
|
||||
view->priv->dnd.type = MOO_TEXT_VIEW_DRAG_NONE;
|
||||
view->priv->dnd.start_x = -1;
|
||||
view->priv->dnd.start_y = -1;
|
||||
|
||||
view->priv->last_search_stamp = -1;
|
||||
|
||||
@ -1951,6 +1954,12 @@ moo_text_view_unrealize (GtkWidget *widget)
|
||||
view->priv->blink_timeout = 0;
|
||||
}
|
||||
|
||||
if (view->priv->dnd.scroll_timeout)
|
||||
{
|
||||
g_source_remove (view->priv->dnd.scroll_timeout);
|
||||
view->priv->dnd.scroll_timeout = 0;
|
||||
}
|
||||
|
||||
#if GTK_CHECK_VERSION(2,6,0)
|
||||
clipboard = gtk_widget_get_clipboard (widget, GDK_SELECTION_CLIPBOARD);
|
||||
if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (view))
|
||||
@ -2883,6 +2892,7 @@ update_digit_width (MooTextView *view)
|
||||
|
||||
layout = create_line_numbers_layout (view);
|
||||
view->priv->lm.digit_width = 0;
|
||||
view->priv->lm.numbers_width = 0;
|
||||
|
||||
for (i = 0; i < 10; ++i)
|
||||
{
|
||||
@ -2908,6 +2918,8 @@ static void
|
||||
update_left_margin (MooTextView *view)
|
||||
{
|
||||
int margin_size;
|
||||
int old_size;
|
||||
GtkTextView *text_view = GTK_TEXT_VIEW (view);
|
||||
|
||||
if (!GTK_WIDGET_REALIZED (view))
|
||||
return;
|
||||
@ -2923,8 +2935,8 @@ update_left_margin (MooTextView *view)
|
||||
if (view->priv->lm.show_numbers)
|
||||
{
|
||||
update_digit_width (view);
|
||||
margin_size += view->priv->lm.digit_width * get_n_digits (view) +
|
||||
LINE_NUMBER_LPAD + LINE_NUMBER_RPAD;
|
||||
view->priv->lm.numbers_width = view->priv->lm.digit_width * get_n_digits (view);
|
||||
margin_size += view->priv->lm.numbers_width + LINE_NUMBER_LPAD + LINE_NUMBER_RPAD;
|
||||
}
|
||||
|
||||
if (view->priv->lm.show_folds)
|
||||
@ -2933,9 +2945,19 @@ update_left_margin (MooTextView *view)
|
||||
margin_size += view->priv->lm.fold_width;
|
||||
}
|
||||
|
||||
gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (view),
|
||||
old_size = get_border_window_size (text_view, GTK_TEXT_WINDOW_LEFT);
|
||||
gtk_text_view_set_border_window_size (text_view,
|
||||
GTK_TEXT_WINDOW_LEFT,
|
||||
margin_size);
|
||||
|
||||
if (old_size == 0 && margin_size != 0)
|
||||
{
|
||||
GdkWindow *window = gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_LEFT);
|
||||
GdkCursor *cursor = gdk_cursor_new (GDK_RIGHT_PTR);
|
||||
gdk_window_set_cursor (window, cursor);
|
||||
gdk_cursor_unref (cursor);
|
||||
}
|
||||
|
||||
/* XXX do not invalidate whole widget */
|
||||
gtk_widget_queue_draw (GTK_WIDGET (view));
|
||||
}
|
||||
@ -3075,7 +3097,7 @@ draw_left_margin (MooTextView *view,
|
||||
if (view->priv->lm.show_numbers)
|
||||
{
|
||||
layout = create_line_numbers_layout (view);
|
||||
text_width = view->priv->lm.digit_width * get_n_digits (view);
|
||||
text_width = view->priv->lm.numbers_width;
|
||||
}
|
||||
|
||||
if (view->priv->lm.show_icons)
|
||||
|
Loading…
x
Reference in New Issue
Block a user