KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > gjt > sp > jedit > textarea > TextAreaMouseHandler


1 /*
2  * TextAreaMouseHandler.java - Handles services.xml files in plugins
3  * :tabSize=8:indentSize=8:noTabs=false:
4  * :folding=explicit:collapseFolds=1:
5  *
6  * Copyright (C) 2006 Matthieu Casanova
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21  */

22 package org.gjt.sp.jedit.textarea;
23
24 import org.gjt.sp.jedit.OperatingSystem;
25 import org.gjt.sp.jedit.TextUtilities;
26 import org.gjt.sp.util.StandardUtilities;
27
28 import javax.swing.event.MouseInputAdapter JavaDoc;
29 import java.awt.event.MouseEvent JavaDoc;
30 import java.awt.*;
31
32 /**
33  * @author Matthieu Casanova
34  * @version $Id: FoldHandler.java 5568 2006-07-10 20:52:23Z kpouer $
35  */

36 public class TextAreaMouseHandler extends MouseInputAdapter JavaDoc
37 {
38     //{{{ MouseHandler constructor
39
TextAreaMouseHandler(TextArea textArea)
40     {
41         this.textArea = textArea;
42     } //}}}
43

44     //{{{ mousePressed() method
45
public void mousePressed(MouseEvent JavaDoc evt)
46     {
47         showCursor();
48
49         control = (OperatingSystem.isMacOS() && evt.isMetaDown())
50             || (!OperatingSystem.isMacOS() && evt.isControlDown());
51
52         // so that Home <mouse click> Home is not the same
53
// as pressing Home twice in a row
54
textArea.getInputHandler().resetLastActionCount();
55
56         quickCopyDrag = (textArea.isQuickCopyEnabled() &&
57             isMiddleButton(evt.getModifiers()));
58
59         if(!quickCopyDrag)
60         {
61             textArea.requestFocus();
62             TextArea.focusedComponent = textArea;
63         }
64
65         if(textArea.getBuffer().isLoading())
66             return;
67
68         int x = evt.getX();
69         int y = evt.getY();
70
71         dragStart = textArea.xyToOffset(x,y,
72             !(textArea.getPainter().isBlockCaretEnabled()
73             || textArea.isOverwriteEnabled()));
74         dragStartLine = textArea.getLineOfOffset(dragStart);
75         dragStartOffset = dragStart - textArea.getLineStartOffset(
76             dragStartLine);
77
78
79         dragged = false;
80
81         textArea.blink = true;
82         textArea.invalidateLine(textArea.getCaretLine());
83
84         clickCount = evt.getClickCount();
85
86         if(textArea.isDragEnabled()
87             && textArea.selectionManager.insideSelection(x,y)
88             && clickCount == 1 && !evt.isShiftDown())
89         {
90             maybeDragAndDrop = true;
91             textArea.moveCaretPosition(dragStart,false);
92             return;
93         }
94         else
95             maybeDragAndDrop = false;
96
97         if(quickCopyDrag)
98         {
99             // ignore double clicks of middle button
100
doSingleClick(evt);
101         }
102         else
103         {
104             switch(clickCount)
105             {
106             case 1:
107                 doSingleClick(evt);
108                 break;
109             case 2:
110                 doDoubleClick();
111                 break;
112             default: //case 3:
113
doTripleClick();
114                 break;
115             }
116         }
117     } //}}}
118

119     //{{{ doSingleClick() method
120
protected void doSingleClick(MouseEvent JavaDoc evt)
121     {
122         int x = evt.getX();
123
124         int extraEndVirt = 0;
125         if(textArea.chunkCache.getLineInfo(
126             textArea.getLastScreenLine()).lastSubregion)
127         {
128             int dragStart = textArea.xyToOffset(x,evt.getY(),
129                 !textArea.getPainter().isBlockCaretEnabled()
130                 && !textArea.isOverwriteEnabled());
131             int screenLine = textArea.getScreenLineOfOffset(dragStart);
132             ChunkCache.LineInfo lineInfo = textArea.chunkCache.getLineInfo(screenLine);
133             int offset = textArea.getScreenLineEndOffset(screenLine);
134             if ((1 != offset - dragStart) || (lineInfo.lastSubregion))
135             {
136                 offset--;
137             }
138             float dragStartLineWidth = textArea.offsetToXY(offset).x;
139             if(x > dragStartLineWidth)
140             {
141                 extraEndVirt = (int)(
142                     (x - dragStartLineWidth)
143                     / textArea.charWidth);
144                 if(!textArea.getPainter().isBlockCaretEnabled()
145                     && !textArea.isOverwriteEnabled()
146                     && (x - textArea.getHorizontalOffset())
147                     % textArea.charWidth > textArea.charWidth / 2)
148                 {
149                     extraEndVirt++;
150                 }
151             }
152         }
153
154         if((control || textArea.isRectangularSelectionEnabled())
155             && textArea.isEditable())
156         {
157             int screenLine = (evt.getY() / textArea.getPainter()
158                 .getFontMetrics().getHeight());
159             if(screenLine > textArea.getLastScreenLine())
160                 screenLine = textArea.getLastScreenLine();
161             ChunkCache.LineInfo info = textArea.chunkCache.getLineInfo(screenLine);
162             if(info.lastSubregion && extraEndVirt != 0)
163             {
164                 // control-click in virtual space inserts
165
// whitespace and moves caret
166
String JavaDoc whitespace = StandardUtilities
167                     .createWhiteSpace(extraEndVirt,0);
168                 textArea.getBuffer().insert(dragStart,whitespace);
169
170                 dragStart += whitespace.length();
171             }
172         }
173
174         if(evt.isShiftDown())
175         {
176             // XXX: getMarkPosition() deprecated!
177
textArea.resizeSelection(
178                 textArea.getMarkPosition(),dragStart,extraEndVirt,
179                 textArea.isRectangularSelectionEnabled()
180                 || control);
181
182             if(!quickCopyDrag)
183                 textArea.moveCaretPosition(dragStart,false);
184
185             // so that shift-click-drag works
186
dragStartLine = textArea.getMarkLine();
187             dragStart = textArea.getMarkPosition();
188             dragStartOffset = dragStart
189                 - textArea.getLineStartOffset(dragStartLine);
190
191             // so that quick copy works
192
dragged = true;
193
194             return;
195         }
196
197         if(!quickCopyDrag)
198             textArea.moveCaretPosition(dragStart,false);
199
200         if(!(textArea.isMultipleSelectionEnabled()
201             || quickCopyDrag))
202             textArea.selectNone();
203     } //}}}
204

205     //{{{ doDoubleClick() method
206
protected void doDoubleClick()
207     {
208         // Ignore empty lines
209
if(textArea.getLineLength(dragStartLine) == 0)
210             return;
211
212         String JavaDoc lineText = textArea.getLineText(dragStartLine);
213         String JavaDoc noWordSep = textArea.getBuffer()
214             .getStringProperty("noWordSep");
215         if(dragStartOffset == textArea.getLineLength(dragStartLine))
216             dragStartOffset--;
217
218         boolean joinNonWordChars = textArea.getJoinNonWordChars();
219         int wordStart = TextUtilities.findWordStart(lineText,dragStartOffset,
220             noWordSep,textArea.getJoinNonWordChars());
221         int wordEnd = TextUtilities.findWordEnd(lineText,
222             dragStartOffset+1,noWordSep,
223             textArea.getJoinNonWordChars());
224
225         int lineStart = textArea.getLineStartOffset(dragStartLine);
226         Selection sel = new Selection.Range(
227             lineStart + wordStart,
228             lineStart + wordEnd);
229         if(textArea.isMultipleSelectionEnabled())
230             textArea.addToSelection(sel);
231         else
232             textArea.setSelection(sel);
233
234         if(quickCopyDrag)
235             quickCopyDrag = false;
236
237         textArea.moveCaretPosition(lineStart + wordEnd,false);
238
239         dragged = true;
240     } //}}}
241

242     //{{{ doTripleClick() method
243
protected void doTripleClick()
244     {
245         int newCaret = textArea.getLineEndOffset(dragStartLine);
246         if(dragStartLine == textArea.getLineCount() - 1)
247             newCaret--;
248
249         Selection sel = new Selection.Range(
250             textArea.getLineStartOffset(dragStartLine),
251             newCaret);
252         if(textArea.isMultipleSelectionEnabled())
253             textArea.addToSelection(sel);
254         else
255             textArea.setSelection(sel);
256
257         if(quickCopyDrag)
258             quickCopyDrag = false;
259
260         textArea.moveCaretPosition(newCaret,false);
261
262         dragged = true;
263     } //}}}
264

265     //{{{ mouseMoved() method
266
public void mouseMoved(MouseEvent JavaDoc evt)
267     {
268         showCursor();
269     } //}}}
270

271     //{{{ mouseDragged() method
272
public void mouseDragged(MouseEvent JavaDoc evt)
273     {
274         if(maybeDragAndDrop)
275         {
276             textArea.startDragAndDrop(evt,control);
277             return;
278         }
279
280         if(textArea.isDragInProgress())
281             return;
282
283         if(textArea.getBuffer().isLoading())
284             return;
285
286         TextAreaPainter painter = textArea.getPainter();
287         if(evt.getY() < 0)
288         {
289             int delta = Math.min(-1,evt.getY()
290                 / painter.getFontMetrics()
291                 .getHeight());
292             textArea.setFirstLine(textArea.getFirstLine() + delta);
293         }
294         else if(evt.getY() >= painter.getHeight())
295         {
296             int delta = Math.max(1,(evt.getY()
297                 - painter.getHeight()) /
298                 painter.getFontMetrics()
299                 .getHeight());
300             if(textArea.lastLinePartial)
301                 delta--;
302             textArea.setFirstLine(textArea.getFirstLine() + delta);
303         }
304
305         switch(clickCount)
306         {
307         case 1:
308             doSingleDrag(evt);
309             break;
310         case 2:
311             doDoubleDrag(evt);
312             break;
313         default: //case 3:
314
doTripleDrag(evt);
315             break;
316         }
317     } //}}}
318

319     //{{{ doSingleDrag() method
320
private void doSingleDrag(MouseEvent JavaDoc evt)
321     {
322         dragged = true;
323
324         TextAreaPainter painter = textArea.getPainter();
325
326         int x = evt.getX();
327         int y = evt.getY();
328         if(y < 0)
329             y = 0;
330         else if(y >= painter.getHeight())
331             y = painter.getHeight() - 1;
332
333         int dot = textArea.xyToOffset(x,y,
334             (!painter.isBlockCaretEnabled()
335             && !textArea.isOverwriteEnabled())
336             || quickCopyDrag);
337         int dotLine = textArea.getLineOfOffset(dot);
338         int extraEndVirt = 0;
339
340         if(textArea.chunkCache.getLineInfo(
341             textArea.getLastScreenLine())
342             .lastSubregion)
343         {
344             int screenLine = textArea.getScreenLineOfOffset(dot);
345             ChunkCache.LineInfo lineInfo = textArea.chunkCache.getLineInfo(screenLine);
346             int offset = textArea.getScreenLineEndOffset(screenLine);
347             if ((1 != offset - dot) || (lineInfo.lastSubregion))
348             {
349                 offset--;
350             }
351             float dotLineWidth = textArea.offsetToXY(offset).x;
352             if(x > dotLineWidth)
353             {
354                 extraEndVirt = (int)((x - dotLineWidth) / textArea.charWidth);
355                 if(!painter.isBlockCaretEnabled()
356                     && !textArea.isOverwriteEnabled()
357                     && (x - textArea.getHorizontalOffset()) % textArea.charWidth > textArea.charWidth / 2)
358                     extraEndVirt++;
359             }
360         }
361
362         textArea.resizeSelection(dragStart,dot,extraEndVirt,
363             textArea.isRectangularSelectionEnabled()
364             || control);
365
366         if(quickCopyDrag)
367         {
368             // just scroll to the dragged location
369
textArea.scrollTo(dotLine,dot - textArea.getLineStartOffset(dotLine),false);
370         }
371         else
372         {
373             if(dot != textArea.getCaretPosition())
374                 textArea.moveCaretPosition(dot,false);
375             if(textArea.isRectangularSelectionEnabled()
376                 && extraEndVirt != 0)
377             {
378                 textArea.scrollTo(dotLine,dot - textArea.getLineStartOffset(dotLine)
379                     + extraEndVirt,false);
380             }
381         }
382     } //}}}
383

384     //{{{ doDoubleDrag() method
385
private void doDoubleDrag(MouseEvent JavaDoc evt)
386     {
387         int markLineStart = textArea.getLineStartOffset(dragStartLine);
388         int markLineLength = textArea.getLineLength(dragStartLine);
389         int mark = dragStartOffset;
390
391         TextAreaPainter painter = textArea.getPainter();
392
393         int pos = textArea.xyToOffset(evt.getX(),
394             Math.max(0,Math.min(painter.getHeight(),evt.getY())),
395             !(painter.isBlockCaretEnabled()
396             || textArea.isOverwriteEnabled()));
397         int line = textArea.getLineOfOffset(pos);
398         int lineStart = textArea.getLineStartOffset(line);
399         int lineLength = textArea.getLineLength(line);
400         int offset = pos - lineStart;
401
402         String JavaDoc lineText = textArea.getLineText(line);
403         String JavaDoc markLineText = textArea.getLineText(dragStartLine);
404         String JavaDoc noWordSep = textArea.getBuffer()
405             .getStringProperty("noWordSep");
406         boolean joinNonWordChars = textArea.getJoinNonWordChars();
407
408         if(markLineStart + dragStartOffset > lineStart + offset)
409         {
410             if(offset != 0 && offset != lineLength)
411             {
412                 offset = TextUtilities.findWordStart(
413                     lineText,offset,noWordSep,
414                     joinNonWordChars);
415             }
416
417             if(markLineLength != 0)
418             {
419                 mark = TextUtilities.findWordEnd(
420                     markLineText,mark,noWordSep,
421                     joinNonWordChars);
422             }
423         }
424         else
425         {
426             if(offset != 0 && lineLength != 0)
427             {
428                 offset = TextUtilities.findWordEnd(
429                     lineText,offset,noWordSep,
430                     joinNonWordChars);
431             }
432
433             if(mark != 0 && mark != markLineLength)
434             {
435                 mark = TextUtilities.findWordStart(
436                     markLineText,mark,noWordSep,
437                     joinNonWordChars);
438             }
439         }
440
441         if(lineStart + offset == textArea.getCaretPosition())
442             return;
443
444         textArea.resizeSelection(markLineStart + mark,
445             lineStart + offset,0,false);
446         textArea.moveCaretPosition(lineStart + offset,false);
447
448         dragged = true;
449     } //}}}
450

451     //{{{ doTripleDrag() method
452
private void doTripleDrag(MouseEvent JavaDoc evt)
453     {
454         TextAreaPainter painter = textArea.getPainter();
455
456         int offset = textArea.xyToOffset(evt.getX(),
457             Math.max(0,Math.min(painter.getHeight(),evt.getY())),
458             false);
459         int mouseLine = textArea.getLineOfOffset(offset);
460         int mark;
461         int mouse;
462         if(dragStartLine > mouseLine)
463         {
464             mark = textArea.getLineEndOffset(dragStartLine) - 1;
465             if(offset == textArea.getLineEndOffset(mouseLine) - 1)
466                 mouse = offset;
467             else
468                 mouse = textArea.getLineStartOffset(mouseLine);
469         }
470         else
471         {
472             mark = textArea.getLineStartOffset(dragStartLine);
473             if(offset == textArea.getLineStartOffset(mouseLine))
474                 mouse = offset;
475             else if(offset == textArea.getLineEndOffset(mouseLine) - 1
476                 && mouseLine != textArea.getLineCount() - 1)
477                 mouse = textArea.getLineEndOffset(mouseLine);
478             else
479                 mouse = textArea.getLineEndOffset(mouseLine) - 1;
480         }
481
482         mouse = Math.min(textArea.getBuffer().getLength(),mouse);
483
484         if(mouse == textArea.getCaretPosition())
485             return;
486
487         textArea.resizeSelection(mark,mouse,0,false);
488         textArea.moveCaretPosition(mouse,false);
489
490         dragged = true;
491     } //}}}
492

493     //{{{ mouseReleased() method
494
public void mouseReleased(MouseEvent JavaDoc evt)
495     {
496         if(!dragged && textArea.isQuickCopyEnabled() &&
497             isMiddleButton(evt.getModifiers()))
498         {
499             textArea.requestFocus();
500             TextArea.focusedComponent = textArea;
501
502             textArea.setCaretPosition(dragStart,false);
503         }
504         else if(maybeDragAndDrop
505             && !textArea.isMultipleSelectionEnabled())
506         {
507             textArea.selectNone();
508         }
509
510         dragged = false;
511     } //}}}
512

513     //{{{ isPopupTrigger() method
514
/**
515      * Returns if the specified event is the popup trigger event.
516      * This implements precisely defined behavior, as opposed to
517      * MouseEvent.isPopupTrigger().
518      * @param evt The event
519      * @since jEdit 4.3pre7
520      */

521     public static boolean isPopupTrigger(MouseEvent JavaDoc evt)
522     {
523         return isRightButton(evt.getModifiers());
524     } //}}}
525

526     //{{{ isMiddleButton() method
527
/**
528      * @param modifiers The modifiers flag from a mouse event
529      * @since jEdit 4.3pre7
530      */

531     public static boolean isMiddleButton(int modifiers)
532     {
533         if (OperatingSystem.isMacOS())
534         {
535             if((modifiers & MouseEvent.BUTTON1_MASK) != 0)
536                 return (modifiers & MouseEvent.ALT_MASK) != 0;
537             else
538                 return (modifiers & MouseEvent.BUTTON2_MASK) != 0;
539         }
540         else
541             return (modifiers & MouseEvent.BUTTON2_MASK) != 0;
542     } //}}}
543

544     //{{{ isRightButton() method
545
/**
546      * @param modifiers The modifiers flag from a mouse event
547      * @since jEdit 4.3pre7
548      */

549     public static boolean isRightButton(int modifiers)
550     {
551         if (OperatingSystem.isMacOS())
552         {
553             if((modifiers & MouseEvent.BUTTON1_MASK) != 0)
554                 return (modifiers & MouseEvent.CTRL_MASK) != 0;
555             else
556                 return (modifiers & MouseEvent.BUTTON3_MASK) != 0;
557         }
558         else
559             return (modifiers & MouseEvent.BUTTON3_MASK) != 0;
560     } //}}}
561

562     //{{{ Private members
563
protected TextArea textArea;
564     protected int dragStartLine;
565     protected int dragStartOffset;
566     protected int dragStart;
567     protected int clickCount;
568     protected boolean dragged;
569     protected boolean quickCopyDrag;
570     protected boolean control;
571     /* with drag and drop on, a mouse down in a selection does not
572     immediately deselect */

573     protected boolean maybeDragAndDrop;
574
575     //{{{ showCursor() method
576
protected void showCursor()
577     {
578         textArea.getPainter().setCursor(
579             Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
580     } //}}}
581

582     //}}}
583
}
584
Popular Tags