mirror of
https://github.com/geometer/FBReaderJ.git
synced 2025-10-05 10:49:24 +02:00
text highlighting, misc fixes
This commit is contained in:
parent
9296cef55e
commit
083629c6bf
7 changed files with 252 additions and 87 deletions
|
@ -126,6 +126,8 @@ final class NavigationPopup extends PopupPanel {
|
||||||
}
|
}
|
||||||
StartPosition = null;
|
StartPosition = null;
|
||||||
Application.hideActivePopup();
|
Application.hideActivePopup();
|
||||||
|
getReader().getViewWidget().reset();
|
||||||
|
getReader().getViewWidget().repaint();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
btnOk.setOnClickListener(listener);
|
btnOk.setOnClickListener(listener);
|
||||||
|
|
|
@ -66,8 +66,15 @@ public class ApiServerImplementation extends ApiInterface.Stub implements ApiMet
|
||||||
setPageStart((TextPosition)parameters[0]);
|
setPageStart((TextPosition)parameters[0]);
|
||||||
return ApiObject.Void.Instance;
|
return ApiObject.Void.Instance;
|
||||||
case HIGHLIGHT_AREA:
|
case HIGHLIGHT_AREA:
|
||||||
|
{
|
||||||
|
myReader.getTextView().highlight(
|
||||||
|
getZLTextPosition((TextPosition)parameters[0]),
|
||||||
|
getZLTextPosition((TextPosition)parameters[1])
|
||||||
|
);
|
||||||
return ApiObject.Void.Instance;
|
return ApiObject.Void.Instance;
|
||||||
|
}
|
||||||
case CLEAR_HIGHLIGHTING:
|
case CLEAR_HIGHLIGHTING:
|
||||||
|
myReader.getTextView().clearHighlighting();
|
||||||
return ApiObject.Void.Instance;
|
return ApiObject.Void.Instance;
|
||||||
default:
|
default:
|
||||||
return unsupportedMethodError(method);
|
return unsupportedMethodError(method);
|
||||||
|
@ -96,6 +103,14 @@ public class ApiServerImplementation extends ApiInterface.Stub implements ApiMet
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ZLTextFixedPosition getZLTextPosition(TextPosition position) {
|
||||||
|
return new ZLTextFixedPosition(
|
||||||
|
position.ParagraphIndex,
|
||||||
|
position.ElementIndex,
|
||||||
|
position.CharIndex
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isPageEndOfSection() {
|
private boolean isPageEndOfSection() {
|
||||||
final ZLTextWordCursor cursor = myReader.getTextView().getEndCursor();
|
final ZLTextWordCursor cursor = myReader.getTextView().getEndCursor();
|
||||||
return cursor.isEndOfParagraph() && cursor.getParagraphCursor().isEndOfSection();
|
return cursor.isEndOfParagraph() && cursor.getParagraphCursor().isEndOfSection();
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2007-2011 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geometerplus.zlibrary.text.view;
|
||||||
|
|
||||||
|
interface ZLTextAbstractHighlighting {
|
||||||
|
boolean clear();
|
||||||
|
|
||||||
|
boolean isEmpty();
|
||||||
|
ZLTextPosition getStartPosition();
|
||||||
|
ZLTextPosition getEndPosition();
|
||||||
|
ZLTextElementArea getStartArea(ZLTextPage page);
|
||||||
|
ZLTextElementArea getEndArea(ZLTextPage page);
|
||||||
|
}
|
|
@ -28,69 +28,105 @@ final class ZLTextElementAreaVector {
|
||||||
Collections.synchronizedList(new ArrayList<ZLTextRegion>());
|
Collections.synchronizedList(new ArrayList<ZLTextRegion>());
|
||||||
private ZLTextRegion myCurrentElementRegion;
|
private ZLTextRegion myCurrentElementRegion;
|
||||||
|
|
||||||
public void clear() {
|
void clear() {
|
||||||
myElementRegions.clear();
|
myElementRegions.clear();
|
||||||
myCurrentElementRegion = null;
|
myCurrentElementRegion = null;
|
||||||
myAreas.clear();
|
myAreas.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return myAreas.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
return myAreas.size();
|
return myAreas.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: remove this unsafe method
|
||||||
public ZLTextElementArea get(int index) {
|
public ZLTextElementArea get(int index) {
|
||||||
return myAreas.get(index);
|
return myAreas.get(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean add(ZLTextElementArea area) {
|
public ZLTextElementArea getFirstArea() {
|
||||||
if (myCurrentElementRegion != null
|
synchronized (myAreas) {
|
||||||
&& myCurrentElementRegion.getSoul().accepts(area)) {
|
return myAreas.isEmpty() ? null : myAreas.get(0);
|
||||||
myCurrentElementRegion.extend();
|
|
||||||
} else {
|
|
||||||
ZLTextRegion.Soul soul = null;
|
|
||||||
final ZLTextHyperlink hyperlink = area.Style.Hyperlink;
|
|
||||||
if (hyperlink.Id != null) {
|
|
||||||
soul = new ZLTextHyperlinkRegionSoul(area, hyperlink);
|
|
||||||
} else if (area.Element instanceof ZLTextImageElement) {
|
|
||||||
soul = new ZLTextImageRegionSoul(area, (ZLTextImageElement)area.Element);
|
|
||||||
} else if (area.Element instanceof ZLTextWord && !((ZLTextWord)area.Element).isASpace()) {
|
|
||||||
soul = new ZLTextWordRegionSoul(area, (ZLTextWord)area.Element);
|
|
||||||
}
|
|
||||||
if (soul != null) {
|
|
||||||
myCurrentElementRegion = new ZLTextRegion(soul, myAreas, size());
|
|
||||||
myElementRegions.add(myCurrentElementRegion);
|
|
||||||
} else {
|
|
||||||
myCurrentElementRegion = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return myAreas.add(area);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ZLTextElementArea binarySearch(int x, int y) {
|
public ZLTextElementArea getLastArea() {
|
||||||
int left = 0;
|
synchronized (myAreas) {
|
||||||
int right = size();
|
return myAreas.isEmpty() ? null : myAreas.get(myAreas.size() - 1);
|
||||||
while (left < right) {
|
}
|
||||||
final int middle = (left + right) / 2;
|
}
|
||||||
final ZLTextElementArea candidate = get(middle);
|
|
||||||
if (candidate.YStart > y) {
|
public boolean add(ZLTextElementArea area) {
|
||||||
right = middle;
|
synchronized (myAreas) {
|
||||||
} else if (candidate.YEnd < y) {
|
if (myCurrentElementRegion != null
|
||||||
left = middle + 1;
|
&& myCurrentElementRegion.getSoul().accepts(area)) {
|
||||||
} else if (candidate.XStart > x) {
|
myCurrentElementRegion.extend();
|
||||||
right = middle;
|
|
||||||
} else if (candidate.XEnd < x) {
|
|
||||||
left = middle + 1;
|
|
||||||
} else {
|
} else {
|
||||||
return candidate;
|
ZLTextRegion.Soul soul = null;
|
||||||
|
final ZLTextHyperlink hyperlink = area.Style.Hyperlink;
|
||||||
|
if (hyperlink.Id != null) {
|
||||||
|
soul = new ZLTextHyperlinkRegionSoul(area, hyperlink);
|
||||||
|
} else if (area.Element instanceof ZLTextImageElement) {
|
||||||
|
soul = new ZLTextImageRegionSoul(area, (ZLTextImageElement)area.Element);
|
||||||
|
} else if (area.Element instanceof ZLTextWord && !((ZLTextWord)area.Element).isASpace()) {
|
||||||
|
soul = new ZLTextWordRegionSoul(area, (ZLTextWord)area.Element);
|
||||||
|
}
|
||||||
|
if (soul != null) {
|
||||||
|
myCurrentElementRegion = new ZLTextRegion(soul, myAreas, myAreas.size());
|
||||||
|
myElementRegions.add(myCurrentElementRegion);
|
||||||
|
} else {
|
||||||
|
myCurrentElementRegion = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return myAreas.add(area);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ZLTextElementArea getFirstAfter(ZLTextPosition position) {
|
||||||
|
synchronized (myAreas) {
|
||||||
|
for (ZLTextElementArea area : myAreas) {
|
||||||
|
if (position.compareTo(area) <= 0) {
|
||||||
|
return area;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ZLTextElementArea getLastBefore(ZLTextPosition position) {
|
||||||
|
synchronized (myAreas) {
|
||||||
|
for (int i = myAreas.size() - 1; i >= 0; --i) {
|
||||||
|
final ZLTextElementArea area = myAreas.get(i);
|
||||||
|
if (position.compareTo(area) > 0) {
|
||||||
|
return area;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ZLTextElementArea binarySearch(int x, int y) {
|
||||||
|
synchronized (myAreas) {
|
||||||
|
int left = 0;
|
||||||
|
int right = myAreas.size();
|
||||||
|
while (left < right) {
|
||||||
|
final int middle = (left + right) / 2;
|
||||||
|
final ZLTextElementArea candidate = myAreas.get(middle);
|
||||||
|
if (candidate.YStart > y) {
|
||||||
|
right = middle;
|
||||||
|
} else if (candidate.YEnd < y) {
|
||||||
|
left = middle + 1;
|
||||||
|
} else if (candidate.XStart > x) {
|
||||||
|
right = middle;
|
||||||
|
} else if (candidate.XEnd < x) {
|
||||||
|
left = middle + 1;
|
||||||
|
} else {
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ZLTextRegion getRegion(ZLTextRegion.Soul soul) {
|
ZLTextRegion getRegion(ZLTextRegion.Soul soul) {
|
||||||
if (soul == null) {
|
if (soul == null) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2007-2011 Geometer Plus <contact@geometerplus.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geometerplus.zlibrary.text.view;
|
||||||
|
|
||||||
|
class ZLTextHighlighting implements ZLTextAbstractHighlighting {
|
||||||
|
private ZLTextPosition myStartPosition;
|
||||||
|
private ZLTextPosition myEndPosition;
|
||||||
|
|
||||||
|
void setup(ZLTextPosition start, ZLTextPosition end) {
|
||||||
|
myStartPosition = new ZLTextFixedPosition(start);
|
||||||
|
myEndPosition = new ZLTextFixedPosition(end);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean clear() {
|
||||||
|
if (isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
myStartPosition = null;
|
||||||
|
myEndPosition = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return myStartPosition == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZLTextPosition getStartPosition() {
|
||||||
|
return myStartPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZLTextPosition getEndPosition() {
|
||||||
|
return myEndPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZLTextElementArea getStartArea(ZLTextPage page) {
|
||||||
|
return page.TextElementMap.getFirstAfter(myStartPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZLTextElementArea getEndArea(ZLTextPage page) {
|
||||||
|
return page.TextElementMap.getLastBefore(myEndPosition);
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
package org.geometerplus.zlibrary.text.view;
|
package org.geometerplus.zlibrary.text.view;
|
||||||
|
|
||||||
public class ZLTextSelection {
|
class ZLTextSelection implements ZLTextAbstractHighlighting {
|
||||||
static class Point {
|
static class Point {
|
||||||
int X;
|
int X;
|
||||||
int Y;
|
int Y;
|
||||||
|
@ -45,11 +45,11 @@ public class ZLTextSelection {
|
||||||
myView = view;
|
myView = view;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return myLeftMostRegionSoul == null;
|
return myLeftMostRegionSoul == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean clear() {
|
public boolean clear() {
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,9 @@ public class ZLTextSelection {
|
||||||
}
|
}
|
||||||
|
|
||||||
final ZLTextElementAreaVector vector = myView.myCurrentPage.TextElementMap;
|
final ZLTextElementAreaVector vector = myView.myCurrentPage.TextElementMap;
|
||||||
if (!vector.isEmpty() && y < vector.get(0).YStart) {
|
final ZLTextElementArea firstArea = vector.getFirstArea();
|
||||||
|
final ZLTextElementArea lastArea = vector.getLastArea();
|
||||||
|
if (firstArea != null && y < firstArea.YStart) {
|
||||||
if (myScroller != null && myScroller.scrollsForward()) {
|
if (myScroller != null && myScroller.scrollsForward()) {
|
||||||
myScroller.stop();
|
myScroller.stop();
|
||||||
myScroller = null;
|
myScroller = null;
|
||||||
|
@ -112,7 +114,7 @@ public class ZLTextSelection {
|
||||||
myScroller = new Scroller(false, x, y);
|
myScroller = new Scroller(false, x, y);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (!vector.isEmpty() && y + ZLTextSelectionCursor.getHeight() / 2 + ZLTextSelectionCursor.getAccent() / 2 > vector.get(vector.size() - 1).YEnd) {
|
} else if (lastArea != null && y + ZLTextSelectionCursor.getHeight() / 2 + ZLTextSelectionCursor.getAccent() / 2 > lastArea.YEnd) {
|
||||||
if (myScroller != null && !myScroller.scrollsForward()) {
|
if (myScroller != null && !myScroller.scrollsForward()) {
|
||||||
myScroller.stop();
|
myScroller.stop();
|
||||||
myScroller = null;
|
myScroller = null;
|
||||||
|
@ -181,7 +183,7 @@ public class ZLTextSelection {
|
||||||
&& myRightMostRegionSoul.compareTo(area) >= 0;
|
&& myRightMostRegionSoul.compareTo(area) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZLTextPosition getStartPosition() {
|
public ZLTextPosition getStartPosition() {
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -192,7 +194,7 @@ public class ZLTextSelection {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZLTextPosition getEndPosition() {
|
public ZLTextPosition getEndPosition() {
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -203,38 +205,34 @@ public class ZLTextSelection {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ZLTextElementArea getStartArea(ZLTextPage page) {
|
public ZLTextElementArea getStartArea(ZLTextPage page) {
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final ZLTextElementAreaVector vector = page.TextElementMap;
|
final ZLTextElementAreaVector vector = page.TextElementMap;
|
||||||
if (vector.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final ZLTextRegion region = vector.getRegion(myLeftMostRegionSoul);
|
final ZLTextRegion region = vector.getRegion(myLeftMostRegionSoul);
|
||||||
if (region != null) {
|
if (region != null) {
|
||||||
return region.getFirstArea();
|
return region.getFirstArea();
|
||||||
}
|
}
|
||||||
if (myLeftMostRegionSoul.compareTo(vector.get(0)) <= 0) {
|
final ZLTextElementArea firstArea = vector.getFirstArea();
|
||||||
return vector.get(0);
|
if (firstArea != null && myLeftMostRegionSoul.compareTo(firstArea) <= 0) {
|
||||||
|
return firstArea;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZLTextElementArea getEndArea(ZLTextPage page) {
|
public ZLTextElementArea getEndArea(ZLTextPage page) {
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final ZLTextElementAreaVector vector = page.TextElementMap;
|
final ZLTextElementAreaVector vector = page.TextElementMap;
|
||||||
if (vector.isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
final ZLTextRegion region = vector.getRegion(myRightMostRegionSoul);
|
final ZLTextRegion region = vector.getRegion(myRightMostRegionSoul);
|
||||||
if (region != null) {
|
if (region != null) {
|
||||||
return region.getLastArea();
|
return region.getLastArea();
|
||||||
}
|
}
|
||||||
if (myRightMostRegionSoul.compareTo(vector.get(vector.size() - 1)) >= 0) {
|
final ZLTextElementArea lastArea = vector.getLastArea();
|
||||||
return vector.get(vector.size() - 1);
|
if (lastArea != null && myRightMostRegionSoul.compareTo(lastArea) >= 0) {
|
||||||
|
return lastArea;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -244,10 +242,10 @@ public class ZLTextSelection {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final ZLTextElementAreaVector vector = page.TextElementMap;
|
final ZLTextElementAreaVector vector = page.TextElementMap;
|
||||||
if (vector.isEmpty()) {
|
final ZLTextElementArea firstPageArea = page.TextElementMap.getFirstArea();
|
||||||
|
if (firstPageArea == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final ZLTextElementArea firstPageArea = vector.get(0);
|
|
||||||
final int cmp = myLeftMostRegionSoul.compareTo(firstPageArea);
|
final int cmp = myLeftMostRegionSoul.compareTo(firstPageArea);
|
||||||
return cmp < 0 || (cmp == 0 && !firstPageArea.isFirstInElement());
|
return cmp < 0 || (cmp == 0 && !firstPageArea.isFirstInElement());
|
||||||
}
|
}
|
||||||
|
@ -256,11 +254,10 @@ public class ZLTextSelection {
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final ZLTextElementAreaVector vector = page.TextElementMap;
|
final ZLTextElementArea lastPageArea = page.TextElementMap.getLastArea();
|
||||||
if (vector.isEmpty()) {
|
if (lastPageArea == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final ZLTextElementArea lastPageArea = vector.get(vector.size() - 1);
|
|
||||||
final int cmp = myRightMostRegionSoul.compareTo(lastPageArea);
|
final int cmp = myRightMostRegionSoul.compareTo(lastPageArea);
|
||||||
return cmp > 0 || (cmp == 0 && !lastPageArea.isLastInElement());
|
return cmp > 0 || (cmp == 0 && !lastPageArea.isLastInElement());
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.geometerplus.zlibrary.core.application.ZLApplication;
|
||||||
import org.geometerplus.zlibrary.core.view.ZLPaintContext;
|
import org.geometerplus.zlibrary.core.view.ZLPaintContext;
|
||||||
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
import org.geometerplus.zlibrary.core.filesystem.ZLFile;
|
||||||
import org.geometerplus.zlibrary.core.filesystem.ZLResourceFile;
|
import org.geometerplus.zlibrary.core.filesystem.ZLResourceFile;
|
||||||
|
import org.geometerplus.zlibrary.core.util.ZLColor;
|
||||||
|
|
||||||
import org.geometerplus.zlibrary.text.model.*;
|
import org.geometerplus.zlibrary.text.model.*;
|
||||||
import org.geometerplus.zlibrary.text.hyphenation.*;
|
import org.geometerplus.zlibrary.text.hyphenation.*;
|
||||||
|
@ -56,9 +57,16 @@ public abstract class ZLTextView extends ZLTextViewBase {
|
||||||
|
|
||||||
private final HashMap<ZLTextLineInfo,ZLTextLineInfo> myLineInfoCache = new HashMap<ZLTextLineInfo,ZLTextLineInfo>();
|
private final HashMap<ZLTextLineInfo,ZLTextLineInfo> myLineInfoCache = new HashMap<ZLTextLineInfo,ZLTextLineInfo>();
|
||||||
|
|
||||||
|
private ZLTextRegion.Soul mySelectedRegionSoul;
|
||||||
|
private boolean myHighlightSelectedRegion = true;
|
||||||
|
|
||||||
|
private ZLTextSelection mySelection;
|
||||||
|
private ZLTextHighlighting myHighlighting;
|
||||||
|
|
||||||
public ZLTextView(ZLApplication application) {
|
public ZLTextView(ZLApplication application) {
|
||||||
super(application);
|
super(application);
|
||||||
mySelection = new ZLTextSelection(this);
|
mySelection = new ZLTextSelection(this);
|
||||||
|
myHighlighting = new ZLTextHighlighting();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void setModel(ZLTextModel model) {
|
public synchronized void setModel(ZLTextModel model) {
|
||||||
|
@ -239,6 +247,19 @@ public abstract class ZLTextView extends ZLTextViewBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void highlight(ZLTextPosition start, ZLTextPosition end) {
|
||||||
|
myHighlighting.setup(start, end);
|
||||||
|
Application.getViewWidget().reset();
|
||||||
|
Application.getViewWidget().repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearHighlighting() {
|
||||||
|
if (myHighlighting.clear()) {
|
||||||
|
Application.getViewWidget().reset();
|
||||||
|
Application.getViewWidget().repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void moveSelectionCursorTo(ZLTextSelectionCursor cursor, int x, int y) {
|
protected void moveSelectionCursorTo(ZLTextSelectionCursor cursor, int x, int y) {
|
||||||
y -= ZLTextSelectionCursor.getHeight() / 2 + ZLTextSelectionCursor.getAccent() / 2;
|
y -= ZLTextSelectionCursor.getHeight() / 2 + ZLTextSelectionCursor.getAccent() / 2;
|
||||||
mySelection.setCursorInMovement(cursor, x, y);
|
mySelection.setCursorInMovement(cursor, x, y);
|
||||||
|
@ -647,16 +668,15 @@ public abstract class ZLTextView extends ZLTextViewBase {
|
||||||
preparePaintInfo();
|
preparePaintInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final char[] SPACE = new char[] { ' ' };
|
private void drawBackgroung(
|
||||||
private void drawTextLine(ZLTextPage page, ZLTextLineInfo info, int from, int to, int y) {
|
ZLTextAbstractHighlighting highligting, ZLColor color,
|
||||||
final ZLTextParagraphCursor paragraph = info.ParagraphCursor;
|
ZLTextPage page, ZLTextLineInfo info, int from, int to, int y
|
||||||
final ZLPaintContext context = myContext;
|
) {
|
||||||
|
if (!highligting.isEmpty() && from != to) {
|
||||||
if (!mySelection.isEmpty() && from != to) {
|
|
||||||
final ZLTextElementArea fromArea = page.TextElementMap.get(from);
|
final ZLTextElementArea fromArea = page.TextElementMap.get(from);
|
||||||
final ZLTextElementArea toArea = page.TextElementMap.get(to - 1);
|
final ZLTextElementArea toArea = page.TextElementMap.get(to - 1);
|
||||||
final ZLTextElementArea selectionStartArea = mySelection.getStartArea(page);
|
final ZLTextElementArea selectionStartArea = highligting.getStartArea(page);
|
||||||
final ZLTextElementArea selectionEndArea = mySelection.getEndArea(page);
|
final ZLTextElementArea selectionEndArea = highligting.getEndArea(page);
|
||||||
if (selectionStartArea != null
|
if (selectionStartArea != null
|
||||||
&& selectionEndArea != null
|
&& selectionEndArea != null
|
||||||
&& selectionStartArea.compareTo(toArea) <= 0
|
&& selectionStartArea.compareTo(toArea) <= 0
|
||||||
|
@ -674,11 +694,19 @@ public abstract class ZLTextView extends ZLTextViewBase {
|
||||||
} else {
|
} else {
|
||||||
right = selectionEndArea.XEnd;
|
right = selectionEndArea.XEnd;
|
||||||
}
|
}
|
||||||
context.setFillColor(getSelectedBackgroundColor());
|
myContext.setFillColor(color);
|
||||||
context.fillRectangle(left, top, right, bottom);
|
myContext.fillRectangle(left, top, right, bottom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final char[] SPACE = new char[] { ' ' };
|
||||||
|
private void drawTextLine(ZLTextPage page, ZLTextLineInfo info, int from, int to, int y) {
|
||||||
|
drawBackgroung(mySelection, getSelectedBackgroundColor(), page, info, from, to, y);
|
||||||
|
drawBackgroung(myHighlighting, getHighlightingColor(), page, info, from, to, y);
|
||||||
|
|
||||||
|
final ZLPaintContext context = myContext;
|
||||||
|
final ZLTextParagraphCursor paragraph = info.ParagraphCursor;
|
||||||
int index = from;
|
int index = from;
|
||||||
final int endElementIndex = info.EndElementIndex;
|
final int endElementIndex = info.EndElementIndex;
|
||||||
int charIndex = info.RealStartCharIndex;
|
int charIndex = info.RealStartCharIndex;
|
||||||
|
@ -1348,10 +1376,6 @@ public abstract class ZLTextView extends ZLTextViewBase {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ZLTextRegion.Soul mySelectedRegionSoul;
|
|
||||||
private ZLTextSelection mySelection;
|
|
||||||
private boolean myHighlightSelectedRegion = true;
|
|
||||||
|
|
||||||
public void hideSelectedRegionBorder() {
|
public void hideSelectedRegionBorder() {
|
||||||
myHighlightSelectedRegion = false;
|
myHighlightSelectedRegion = false;
|
||||||
Application.getViewWidget().reset();
|
Application.getViewWidget().reset();
|
||||||
|
@ -1399,8 +1423,7 @@ public abstract class ZLTextView extends ZLTextViewBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSelectionStartY() {
|
public int getSelectionStartY() {
|
||||||
final ZLTextElementAreaVector vector = myCurrentPage.TextElementMap;
|
if (mySelection.isEmpty()) {
|
||||||
if (mySelection.isEmpty() || vector.isEmpty()) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
final ZLTextElementArea selectionStartArea = mySelection.getStartArea(myCurrentPage);
|
final ZLTextElementArea selectionStartArea = mySelection.getStartArea(myCurrentPage);
|
||||||
|
@ -1408,15 +1431,16 @@ public abstract class ZLTextView extends ZLTextViewBase {
|
||||||
return selectionStartArea.YStart;
|
return selectionStartArea.YStart;
|
||||||
}
|
}
|
||||||
if (mySelection.hasAPartBeforePage(myCurrentPage)) {
|
if (mySelection.hasAPartBeforePage(myCurrentPage)) {
|
||||||
return vector.get(0).YStart;
|
final ZLTextElementArea firstArea = myCurrentPage.TextElementMap.getFirstArea();
|
||||||
|
return firstArea != null ? firstArea.YStart : 0;
|
||||||
} else {
|
} else {
|
||||||
return vector.get(vector.size() - 1).YEnd;
|
final ZLTextElementArea lastArea = myCurrentPage.TextElementMap.getLastArea();
|
||||||
|
return lastArea != null ? lastArea.YEnd : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSelectionEndY() {
|
public int getSelectionEndY() {
|
||||||
final ZLTextElementAreaVector vector = myCurrentPage.TextElementMap;
|
if (mySelection.isEmpty()) {
|
||||||
if (mySelection.isEmpty() || vector.isEmpty()) {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
final ZLTextElementArea selectionEndArea = mySelection.getEndArea(myCurrentPage);
|
final ZLTextElementArea selectionEndArea = mySelection.getEndArea(myCurrentPage);
|
||||||
|
@ -1424,9 +1448,11 @@ public abstract class ZLTextView extends ZLTextViewBase {
|
||||||
return selectionEndArea.YEnd;
|
return selectionEndArea.YEnd;
|
||||||
}
|
}
|
||||||
if (mySelection.hasAPartAfterPage(myCurrentPage)) {
|
if (mySelection.hasAPartAfterPage(myCurrentPage)) {
|
||||||
return vector.get(vector.size() - 1).YEnd;
|
final ZLTextElementArea lastArea = myCurrentPage.TextElementMap.getLastArea();
|
||||||
|
return lastArea != null ? lastArea.YEnd : 0;
|
||||||
} else {
|
} else {
|
||||||
return vector.get(0).YStart;
|
final ZLTextElementArea firstArea = myCurrentPage.TextElementMap.getFirstArea();
|
||||||
|
return firstArea != null ? firstArea.YStart : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue