2014-02-11 15:32:09 +01:00
|
|
|
/*
|
|
|
|
* This is the source code of Telegram for Android v. 1.3.x.
|
|
|
|
* It is licensed under GNU GPL v. 2 or later.
|
|
|
|
* You should have received a copy of the license in this archive (see LICENSE).
|
|
|
|
*
|
|
|
|
* Copyright Nikolai Kudashov, 2013.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package org.telegram.ui.Cells;
|
|
|
|
|
|
|
|
import android.content.Context;
|
2014-02-28 23:28:25 +01:00
|
|
|
import android.graphics.Canvas;
|
|
|
|
import android.text.Spannable;
|
|
|
|
import android.text.style.ClickableSpan;
|
|
|
|
import android.view.MotionEvent;
|
2014-02-11 15:32:09 +01:00
|
|
|
|
2014-07-03 00:39:05 +02:00
|
|
|
import org.telegram.android.AndroidUtilities;
|
2014-03-10 10:27:49 +01:00
|
|
|
import org.telegram.messenger.FileLog;
|
2014-08-22 16:24:33 +02:00
|
|
|
import org.telegram.android.MessageObject;
|
2014-02-28 23:28:25 +01:00
|
|
|
|
|
|
|
public class ChatMessageCell extends ChatBaseCell {
|
|
|
|
|
|
|
|
private int textX, textY;
|
|
|
|
private int totalHeight = 0;
|
|
|
|
private ClickableSpan pressedLink;
|
|
|
|
|
|
|
|
private int lastVisibleBlockNum = 0;
|
|
|
|
private int firstVisibleBlockNum = 0;
|
|
|
|
private int totalVisibleBlocksCount = 0;
|
|
|
|
|
2014-03-31 16:14:49 +02:00
|
|
|
public ChatMessageCell(Context context) {
|
|
|
|
super(context, false);
|
2014-02-28 23:28:25 +01:00
|
|
|
drawForwardedName = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onTouchEvent(MotionEvent event) {
|
2014-03-10 10:27:49 +01:00
|
|
|
if (currentMessageObject != null && currentMessageObject.textLayoutBlocks != null && !currentMessageObject.textLayoutBlocks.isEmpty() && currentMessageObject.messageText instanceof Spannable && !isPressed) {
|
2014-02-28 23:28:25 +01:00
|
|
|
if (event.getAction() == MotionEvent.ACTION_DOWN || pressedLink != null && event.getAction() == MotionEvent.ACTION_UP) {
|
|
|
|
int x = (int)event.getX();
|
|
|
|
int y = (int)event.getY();
|
|
|
|
if (x >= textX && y >= textY && x <= textX + currentMessageObject.textWidth && y <= textY + currentMessageObject.textHeight) {
|
2014-05-17 01:32:05 +02:00
|
|
|
y -= textY;
|
2014-05-18 23:44:30 +02:00
|
|
|
int blockNum = Math.max(0, y / currentMessageObject.blockHeight);
|
2014-02-28 23:28:25 +01:00
|
|
|
if (blockNum < currentMessageObject.textLayoutBlocks.size()) {
|
|
|
|
MessageObject.TextLayoutBlock block = currentMessageObject.textLayoutBlocks.get(blockNum);
|
|
|
|
x -= textX - (int)Math.ceil(block.textXOffset);
|
|
|
|
y -= block.textYOffset;
|
|
|
|
final int line = block.textLayout.getLineForVertical(y);
|
|
|
|
final int off = block.textLayout.getOffsetForHorizontal(line, x) + block.charactersOffset;
|
|
|
|
|
|
|
|
final float left = block.textLayout.getLineLeft(line);
|
|
|
|
if (left <= x && left + block.textLayout.getLineWidth(line) >= x) {
|
|
|
|
Spannable buffer = (Spannable)currentMessageObject.messageText;
|
|
|
|
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
|
|
|
|
|
|
|
|
if (link.length != 0) {
|
|
|
|
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
|
|
|
pressedLink = link[0];
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
if (link[0] == pressedLink) {
|
2014-03-10 10:27:49 +01:00
|
|
|
try {
|
|
|
|
pressedLink.onClick(this);
|
|
|
|
} catch (Exception e) {
|
|
|
|
FileLog.e("tmessages", e);
|
|
|
|
}
|
2014-02-28 23:28:25 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
pressedLink = null;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
pressedLink = null;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
pressedLink = null;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
pressedLink = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
pressedLink = null;
|
|
|
|
}
|
|
|
|
return super.onTouchEvent(event);
|
2014-02-11 15:32:09 +01:00
|
|
|
}
|
|
|
|
|
2014-02-28 23:28:25 +01:00
|
|
|
public void setVisiblePart(int position, int height) {
|
2014-03-10 10:27:49 +01:00
|
|
|
if (currentMessageObject == null || currentMessageObject.textLayoutBlocks == null) {
|
|
|
|
return;
|
|
|
|
}
|
2014-02-28 23:28:25 +01:00
|
|
|
int newFirst = -1, newLast = -1, newCount = 0;
|
|
|
|
|
2014-03-04 20:29:32 +01:00
|
|
|
for (int a = Math.max(0, (position - textY) / currentMessageObject.blockHeight); a < currentMessageObject.textLayoutBlocks.size(); a++) {
|
2014-02-28 23:28:25 +01:00
|
|
|
MessageObject.TextLayoutBlock block = currentMessageObject.textLayoutBlocks.get(a);
|
|
|
|
float y = textY + block.textYOffset;
|
2014-03-04 20:29:32 +01:00
|
|
|
if (intersect(y, y + currentMessageObject.blockHeight, position, position + height)) {
|
2014-02-28 23:28:25 +01:00
|
|
|
if (newFirst == -1) {
|
|
|
|
newFirst = a;
|
|
|
|
}
|
|
|
|
newLast = a;
|
|
|
|
newCount++;
|
2014-03-04 20:29:32 +01:00
|
|
|
} else if (y > position) {
|
2014-02-28 23:28:25 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lastVisibleBlockNum != newLast || firstVisibleBlockNum != newFirst || totalVisibleBlocksCount != newCount) {
|
|
|
|
lastVisibleBlockNum = newLast;
|
|
|
|
firstVisibleBlockNum = newFirst;
|
|
|
|
totalVisibleBlocksCount = newCount;
|
|
|
|
invalidate();
|
|
|
|
}
|
2014-02-11 15:32:09 +01:00
|
|
|
}
|
|
|
|
|
2014-02-28 23:28:25 +01:00
|
|
|
private boolean intersect(float left1, float right1, float left2, float right2) {
|
|
|
|
if (left1 <= left2) {
|
|
|
|
return right1 >= left2;
|
|
|
|
}
|
|
|
|
return left1 <= right2;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void setMessageObject(MessageObject messageObject) {
|
|
|
|
if (currentMessageObject != messageObject || isUserDataChanged()) {
|
2014-03-10 10:27:49 +01:00
|
|
|
if (currentMessageObject != messageObject) {
|
|
|
|
firstVisibleBlockNum = 0;
|
|
|
|
lastVisibleBlockNum = 0;
|
|
|
|
}
|
2014-02-28 23:28:25 +01:00
|
|
|
pressedLink = null;
|
|
|
|
int maxWidth;
|
2014-04-03 23:18:54 +02:00
|
|
|
if (isChat && !messageObject.isOut()) {
|
2014-07-03 00:39:05 +02:00
|
|
|
maxWidth = AndroidUtilities.displaySize.x - AndroidUtilities.dp(122);
|
2014-02-28 23:28:25 +01:00
|
|
|
drawName = true;
|
|
|
|
} else {
|
2014-07-03 00:39:05 +02:00
|
|
|
maxWidth = AndroidUtilities.displaySize.x - AndroidUtilities.dp(80);
|
2014-04-04 21:35:35 +02:00
|
|
|
drawName = false;
|
2014-02-28 23:28:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
backgroundWidth = maxWidth;
|
|
|
|
|
|
|
|
super.setMessageObject(messageObject);
|
|
|
|
|
|
|
|
backgroundWidth = messageObject.textWidth;
|
2014-07-03 00:39:05 +02:00
|
|
|
totalHeight = messageObject.textHeight + AndroidUtilities.dpf(19.5f) + namesOffset;
|
2014-02-28 23:28:25 +01:00
|
|
|
|
|
|
|
int maxChildWidth = Math.max(backgroundWidth, nameWidth);
|
|
|
|
maxChildWidth = Math.max(maxChildWidth, forwardedNameWidth);
|
|
|
|
|
2014-07-03 00:39:05 +02:00
|
|
|
int timeMore = timeWidth + AndroidUtilities.dp(6);
|
2014-04-03 23:18:54 +02:00
|
|
|
if (messageObject.isOut()) {
|
2014-07-03 00:39:05 +02:00
|
|
|
timeMore += AndroidUtilities.dpf(20.5f);
|
2014-02-28 23:28:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (maxWidth - messageObject.lastLineWidth < timeMore) {
|
2014-07-03 00:39:05 +02:00
|
|
|
totalHeight += AndroidUtilities.dp(14);
|
|
|
|
backgroundWidth = Math.max(maxChildWidth, messageObject.lastLineWidth) + AndroidUtilities.dp(29);
|
2014-02-28 23:28:25 +01:00
|
|
|
} else {
|
|
|
|
int diff = maxChildWidth - messageObject.lastLineWidth;
|
|
|
|
if (diff >= 0 && diff <= timeMore) {
|
2014-07-03 00:39:05 +02:00
|
|
|
backgroundWidth = maxChildWidth + timeMore - diff + AndroidUtilities.dp(29);
|
2014-02-28 23:28:25 +01:00
|
|
|
} else {
|
2014-07-03 00:39:05 +02:00
|
|
|
backgroundWidth = Math.max(maxChildWidth, messageObject.lastLineWidth + timeMore) + AndroidUtilities.dp(29);
|
2014-02-28 23:28:25 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
|
|
|
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), totalHeight);
|
|
|
|
}
|
|
|
|
|
2014-03-10 10:27:49 +01:00
|
|
|
@Override
|
|
|
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
|
|
|
super.onLayout(changed, left, top, right, bottom);
|
|
|
|
|
2014-04-03 23:18:54 +02:00
|
|
|
if (currentMessageObject.isOut()) {
|
2014-07-03 00:39:05 +02:00
|
|
|
textX = layoutWidth - backgroundWidth + AndroidUtilities.dp(10);
|
|
|
|
textY = AndroidUtilities.dp(10) + namesOffset;
|
2014-03-10 10:27:49 +01:00
|
|
|
} else {
|
2014-07-03 00:39:05 +02:00
|
|
|
textX = AndroidUtilities.dp(19) + (isChat ? AndroidUtilities.dp(52) : 0);
|
|
|
|
textY = AndroidUtilities.dp(10) + namesOffset;
|
2014-03-10 10:27:49 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-28 23:28:25 +01:00
|
|
|
@Override
|
|
|
|
protected void onDraw(Canvas canvas) {
|
|
|
|
super.onDraw(canvas);
|
2014-03-04 07:23:08 +01:00
|
|
|
if (currentMessageObject == null || currentMessageObject.textLayoutBlocks == null || currentMessageObject.textLayoutBlocks.isEmpty() || firstVisibleBlockNum < 0) {
|
2014-02-28 23:28:25 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-04-03 23:18:54 +02:00
|
|
|
if (currentMessageObject.isOut()) {
|
2014-07-03 00:39:05 +02:00
|
|
|
textX = layoutWidth - backgroundWidth + AndroidUtilities.dp(10);
|
|
|
|
textY = AndroidUtilities.dp(10) + namesOffset;
|
2014-03-04 20:29:32 +01:00
|
|
|
} else {
|
2014-07-03 00:39:05 +02:00
|
|
|
textX = AndroidUtilities.dp(19) + (isChat ? AndroidUtilities.dp(52) : 0);
|
|
|
|
textY = AndroidUtilities.dp(10) + namesOffset;
|
2014-03-04 20:29:32 +01:00
|
|
|
}
|
|
|
|
|
2014-03-04 07:23:08 +01:00
|
|
|
for (int a = firstVisibleBlockNum; a <= lastVisibleBlockNum; a++) {
|
2014-03-10 10:27:49 +01:00
|
|
|
if (a >= currentMessageObject.textLayoutBlocks.size()) {
|
|
|
|
break;
|
|
|
|
}
|
2014-02-28 23:28:25 +01:00
|
|
|
MessageObject.TextLayoutBlock block = currentMessageObject.textLayoutBlocks.get(a);
|
2014-03-04 20:29:32 +01:00
|
|
|
canvas.save();
|
|
|
|
canvas.translate(textX - (int)Math.ceil(block.textXOffset), textY + block.textYOffset);
|
2014-03-10 10:27:49 +01:00
|
|
|
try {
|
|
|
|
block.textLayout.draw(canvas);
|
|
|
|
} catch (Exception e) {
|
|
|
|
FileLog.e("tmessages", e);
|
|
|
|
}
|
2014-03-04 20:29:32 +01:00
|
|
|
canvas.restore();
|
2014-02-28 23:28:25 +01:00
|
|
|
}
|
2014-02-11 15:32:09 +01:00
|
|
|
}
|
|
|
|
}
|