public class StickerCell extends FrameLayoutFixed { private KharTheme theme = ThemeCenter.get().getTheme(); private BackupImageView imageView; public StickerCell(Context context) { super(context); imageView = new BackupImageView(context); imageView.setAspectFit(true); addView(imageView, LayoutHelper.createFrame(66, 66, Gravity.CENTER_HORIZONTAL, 0, 5, 0, 0)); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure( MeasureSpec.makeMeasureSpec( AndroidUtilities.dp(76) + getPaddingLeft() + getPaddingRight(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(78), MeasureSpec.EXACTLY)); } @Override public void setPressed(boolean pressed) { if (imageView.getImageReceiver().getPressed() != pressed) { imageView.getImageReceiver().setPressed(pressed); imageView.invalidate(); } super.setPressed(pressed); } public void setSticker(TLRPC.Document document, int side) { if (document != null && document.thumb != null) { imageView.setImage(document.thumb.location, null, "webp", null); } if (side == -1) { setBackgroundResource(theme.StickerCell_bg_1_R); setPadding(AndroidUtilities.dp(7), 0, 0, 0); } else if (side == 0) { setBackgroundResource(theme.StickerCell_bg_2_R); setPadding(0, 0, 0, 0); } else if (side == 1) { setBackgroundResource(theme.StickerCell_bg_3_R); setPadding(0, 0, AndroidUtilities.dp(7), 0); } else if (side == 2) { setBackgroundResource(theme.StickerCell_bg_4_R); setPadding(AndroidUtilities.dp(3), 0, AndroidUtilities.dp(3), 0); } if (getBackground() != null) { getBackground().setAlpha(230); } } }
public class ChatMusicCell extends ChatBaseCell implements SeekBar.SeekBarDelegate { private KharTheme theme = ThemeCenter.get().getTheme(); public interface ChatMusicCellDelegate { boolean needPlayMusic(MessageObject messageObject); } private static TextPaint timePaint; private static TextPaint titlePaint; private static TextPaint authorPaint; private SeekBar seekBar; private int seekBarX; private int seekBarY; private RadialProgress radialProgress; private int buttonState = 0; private int buttonX; private int buttonY; private boolean buttonPressed = false; private StaticLayout timeLayout; private int timeX; private String lastTimeString = null; private StaticLayout titleLayout; private int titleX; private StaticLayout authorLayout; private int authorX; private ChatMusicCellDelegate musicDelegate; public ChatMusicCell(Context context) { super(context); seekBar = new SeekBar(context); seekBar.delegate = this; radialProgress = new RadialProgress(this); drawForwardedName = false; if (timePaint == null) { timePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); timePaint.setTextSize(AndroidUtilities.dp(13)); titlePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); titlePaint.setTextSize(AndroidUtilities.dp(16)); titlePaint.setColor(theme.ChatMusicCell_titlePaint_color); titlePaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); authorPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); authorPaint.setTextSize(AndroidUtilities.dp(15)); authorPaint.setColor(theme.ChatMusicCell_authorPaint_color); } } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); MediaController.getInstance().removeLoadingFileObserver(this); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); updateButtonState(false); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); boolean result = seekBar.onTouch(event.getAction(), event.getX() - seekBarX, event.getY() - seekBarY); if (result) { if (event.getAction() == MotionEvent.ACTION_DOWN) { getParent().requestDisallowInterceptTouchEvent(true); } invalidate(); } else { int side = AndroidUtilities.dp(36); if (event.getAction() == MotionEvent.ACTION_DOWN) { if (x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side) { buttonPressed = true; invalidate(); result = true; } } else if (buttonPressed) { if (event.getAction() == MotionEvent.ACTION_UP) { buttonPressed = false; playSoundEffect(SoundEffectConstants.CLICK); didPressedButton(); invalidate(); } else if (event.getAction() == MotionEvent.ACTION_CANCEL) { buttonPressed = false; invalidate(); } else if (event.getAction() == MotionEvent.ACTION_MOVE) { if (!(x >= buttonX && x <= buttonX + side && y >= buttonY && y <= buttonY + side)) { buttonPressed = false; invalidate(); } } } if (!result) { result = super.onTouchEvent(event); } } return result; } private void didPressedButton() { if (buttonState == 0) { if (musicDelegate != null) { if (musicDelegate.needPlayMusic(currentMessageObject)) { buttonState = 1; radialProgress.setBackground(getDrawableForCurrentState(), false, false); invalidate(); } } } else if (buttonState == 1) { boolean result = MediaController.getInstance().pauseAudio(currentMessageObject); if (result) { buttonState = 0; radialProgress.setBackground(getDrawableForCurrentState(), false, false); invalidate(); } } else if (buttonState == 2) { radialProgress.setProgress(0, false); FileLoader.getInstance() .loadFile(currentMessageObject.messageOwner.media.document, true, false); buttonState = 3; radialProgress.setBackground(getDrawableForCurrentState(), true, false); invalidate(); } else if (buttonState == 3) { FileLoader.getInstance().cancelLoadFile(currentMessageObject.messageOwner.media.document); buttonState = 2; radialProgress.setBackground(getDrawableForCurrentState(), false, false); invalidate(); } else if (buttonState == 4) { if (currentMessageObject.isOut() && currentMessageObject.isSending()) { if (delegate != null) { delegate.didPressedCancelSendButton(this); } } } } public void setMusicDelegate(ChatMusicCellDelegate delegate) { musicDelegate = delegate; } public void updateProgress() { if (currentMessageObject == null) { return; } if (!seekBar.isDragging()) { seekBar.setProgress(currentMessageObject.audioProgress); } int duration = 0; int currentProgress = 0; for (TLRPC.DocumentAttribute attribute : currentMessageObject.messageOwner.media.document.attributes) { if (attribute instanceof TLRPC.TL_documentAttributeAudio) { duration = attribute.duration; break; } } if (MediaController.getInstance().isPlayingAudio(currentMessageObject)) { currentProgress = currentMessageObject.audioProgressSec; } String timeString = String.format( "%d:%02d / %d:%02d", currentProgress / 60, currentProgress % 60, duration / 60, duration % 60); if (lastTimeString == null || lastTimeString != null && !lastTimeString.equals(timeString)) { lastTimeString = timeString; int timeWidth = (int) Math.ceil(timePaint.measureText(timeString)); timeLayout = new StaticLayout( timeString, timePaint, timeWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); } invalidate(); } public void downloadAudioIfNeed() { // if (buttonState == 2) { // FileLoader.getInstance().loadFile(currentMessageObject.messageOwner.media.document, true, // false); // buttonState = 3; // invalidate(); // } } public void updateButtonState(boolean animated) { if (currentMessageObject == null) { return; } if (currentMessageObject.isOut() && currentMessageObject.isSending()) { MediaController.getInstance() .addLoadingFileObserver(currentMessageObject.messageOwner.attachPath, this); buttonState = 4; radialProgress.setBackground(getDrawableForCurrentState(), true, animated); Float progress = ImageLoader.getInstance().getFileProgress(currentMessageObject.messageOwner.attachPath); if (progress == null && SendMessagesHelper.getInstance().isSendingMessage(currentMessageObject.getId())) { progress = 1.0f; } radialProgress.setProgress(progress != null ? progress : 0, false); } else { File cacheFile = null; if (currentMessageObject.messageOwner.attachPath != null && currentMessageObject.messageOwner.attachPath.length() > 0) { cacheFile = new File(currentMessageObject.messageOwner.attachPath); if (!cacheFile.exists()) { cacheFile = null; } } if (cacheFile == null) { cacheFile = FileLoader.getPathToMessage(currentMessageObject.messageOwner); } if (cacheFile.exists()) { MediaController.getInstance().removeLoadingFileObserver(this); boolean playing = MediaController.getInstance().isPlayingAudio(currentMessageObject); if (!playing || playing && MediaController.getInstance().isAudioPaused()) { buttonState = 0; } else { buttonState = 1; } radialProgress.setProgress(0, animated); radialProgress.setBackground(getDrawableForCurrentState(), false, animated); } else { String fileName = currentMessageObject.getFileName(); MediaController.getInstance().addLoadingFileObserver(fileName, this); if (!FileLoader.getInstance().isLoadingFile(fileName)) { buttonState = 2; radialProgress.setProgress(0, animated); radialProgress.setBackground(getDrawableForCurrentState(), false, animated); } else { buttonState = 3; Float progress = ImageLoader.getInstance().getFileProgress(fileName); if (progress != null) { radialProgress.setProgress(progress, animated); } else { radialProgress.setProgress(0, animated); } radialProgress.setBackground(getDrawableForCurrentState(), true, animated); } } } updateProgress(); } @Override public void onFailedDownload(String fileName) { updateButtonState(true); } @Override public void onSuccessDownload(String fileName) { updateButtonState(true); } @Override public void onProgressDownload(String fileName, float progress) { radialProgress.setProgress(progress, true); if (buttonState != 3) { updateButtonState(false); } } @Override public void onProgressUpload(String fileName, float progress, boolean isEncrypted) { radialProgress.setProgress(progress, true); } @Override public void onSeekBarDrag(float progress) { if (currentMessageObject == null) { return; } currentMessageObject.audioProgress = progress; MediaController.getInstance().seekToProgress(currentMessageObject, progress); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = MeasureSpec.getSize(widthMeasureSpec); setMeasuredDimension(width, AndroidUtilities.dp(78) + namesOffset); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if (currentMessageObject.isOutOwner()) { seekBarX = layoutWidth - backgroundWidth + AndroidUtilities.dp(52); buttonX = layoutWidth - backgroundWidth + AndroidUtilities.dp(13); timeX = layoutWidth - backgroundWidth + AndroidUtilities.dp(63); } else { if (isChat && currentMessageObject.messageOwner.from_id > 0) { seekBarX = AndroidUtilities.dp(113); buttonX = AndroidUtilities.dp(74); timeX = AndroidUtilities.dp(124); } else { seekBarX = AndroidUtilities.dp(61); buttonX = AndroidUtilities.dp(22); timeX = AndroidUtilities.dp(72); } } seekBar.width = backgroundWidth - AndroidUtilities.dp(67); seekBar.height = AndroidUtilities.dp(30); seekBarY = AndroidUtilities.dp(26) + namesOffset; buttonY = AndroidUtilities.dp(13) + namesOffset; radialProgress.setProgressRect( buttonX, buttonY, buttonX + AndroidUtilities.dp(40), buttonY + AndroidUtilities.dp(40)); updateProgress(); } @Override public void setMessageObject(MessageObject messageObject) { boolean dataChanged = currentMessageObject == messageObject && isUserDataChanged(); if (currentMessageObject != messageObject || dataChanged) { if (AndroidUtilities.isTablet()) { backgroundWidth = Math.min( AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp( isChat && messageObject.messageOwner.from_id > 0 ? 102 : 50), AndroidUtilities.dp(300)); } else { backgroundWidth = Math.min( AndroidUtilities.displaySize.x - AndroidUtilities.dp( isChat && messageObject.messageOwner.from_id > 0 ? 102 : 50), AndroidUtilities.dp(300)); } if (messageObject.isOutOwner()) { seekBar.type = 0; radialProgress.setProgressColor(theme.ChatMusicCell_radialProgress_color); } else { seekBar.type = 1; radialProgress.setProgressColor(theme.ChatMusicCell_radialProgress_color_2); } int maxWidth = backgroundWidth - AndroidUtilities.dp(86); CharSequence stringFinal = TextUtils.ellipsize( messageObject.getMusicTitle().replace("\n", " "), titlePaint, maxWidth, TextUtils.TruncateAt.END); titleLayout = new StaticLayout( stringFinal, titlePaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); if (titleLayout.getLineCount() > 0) { titleX = (int) Math.ceil(titleLayout.getLineLeft(0)); } stringFinal = TextUtils.ellipsize( messageObject.getMusicAuthor().replace("\n", " "), authorPaint, maxWidth, TextUtils.TruncateAt.END); authorLayout = new StaticLayout( stringFinal, authorPaint, maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); if (authorLayout.getLineCount() > 0) { authorX = (int) Math.ceil(authorLayout.getLineLeft(0)); } super.setMessageObject(messageObject); } updateButtonState(dataChanged); } private Drawable getDrawableForCurrentState() { return ResourceLoader.audioStatesDrawable[ currentMessageObject.isOutOwner() ? buttonState : buttonState + 5][0]; // buttonPressed ? 1 : } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (currentMessageObject == null) { return; } if (currentMessageObject.isOutOwner()) { timePaint.setColor(theme.ChatMusicCell_timePaint_color); } else { timePaint.setColor(theme.ChatMusicCell_timePaint_color_2); } radialProgress.draw(canvas); canvas.save(); canvas.translate(timeX + titleX, AndroidUtilities.dp(12) + namesOffset); titleLayout.draw(canvas); canvas.restore(); canvas.save(); if (MediaController.getInstance().isPlayingAudio(currentMessageObject)) { canvas.translate(seekBarX, seekBarY); seekBar.draw(canvas); } else { canvas.translate(timeX + authorX, AndroidUtilities.dp(32) + namesOffset); authorLayout.draw(canvas); } canvas.restore(); canvas.save(); canvas.translate(timeX, AndroidUtilities.dp(52) + namesOffset); timeLayout.draw(canvas); canvas.restore(); } }
public class ChatContactCell extends ChatBaseCell { private KharTheme theme = ThemeCenter.get().getTheme(); public interface ChatContactCellDelegate { void didClickAddButton(ChatContactCell cell, TLRPC.User user); void didClickPhone(ChatContactCell cell); } private static TextPaint namePaint; private static TextPaint phonePaint; private static Drawable addContactDrawableIn; private static Drawable addContactDrawableOut; private ImageReceiver avatarImage; private AvatarDrawable avatarDrawable; private StaticLayout nameLayout; private StaticLayout phoneLayout; private TLRPC.User contactUser; private TLRPC.FileLocation currentPhoto; private boolean avatarPressed = false; private boolean buttonPressed = false; private boolean drawAddButton = false; private int namesWidth = 0; private ChatContactCellDelegate contactDelegate = null; public ChatContactCell(Context context) { super(context); if (namePaint == null) { namePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); namePaint.setTextSize(AndroidUtilities.dp(15)); phonePaint = new TextPaint(TextPaint.ANTI_ALIAS_FLAG); phonePaint.setTextSize(AndroidUtilities.dp(15)); phonePaint.setColor(theme.ChatContactCell_phonePaint_color); addContactDrawableIn = getResources().getDrawable(theme.ChatContactCell_addContactDrawableIn_R); addContactDrawableOut = getResources().getDrawable(theme.ChatContactCell_addContactDrawableOut_R); } avatarImage = new ImageReceiver(this); avatarImage.setRoundRadius(AndroidUtilities.dp(21)); avatarDrawable = new AvatarDrawable(); } public void setContactDelegate(ChatContactCellDelegate delegate) { this.contactDelegate = delegate; } @Override protected boolean isUserDataChanged() { if (currentMessageObject == null) { return false; } int uid = currentMessageObject.messageOwner.media.user_id; boolean newDrawAdd = contactUser != null && uid != UserConfig.getClientUserId() && ContactsController.getInstance().contactsDict.get(uid) == null; if (newDrawAdd != drawAddButton) { return true; } contactUser = MessagesController.getInstance().getUser(currentMessageObject.messageOwner.media.user_id); TLRPC.FileLocation newPhoto = null; if (contactUser != null && contactUser.photo != null) { newPhoto = contactUser.photo.photo_small; } return currentPhoto == null && newPhoto != null || currentPhoto != null && newPhoto == null || currentPhoto != null && newPhoto != null && (currentPhoto.local_id != newPhoto.local_id || currentPhoto.volume_id != newPhoto.volume_id) || super.isUserDataChanged(); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); boolean result = false; if (event.getAction() == MotionEvent.ACTION_DOWN) { if (x >= avatarImage.getImageX() && x <= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(42) && y >= avatarImage.getImageY() && y <= avatarImage.getImageY() + avatarImage.getImageHeight()) { avatarPressed = true; result = true; } else if (x >= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(52) && y >= AndroidUtilities.dp(13) + namesOffset && x <= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(92) && y <= AndroidUtilities.dp(52) + namesOffset) { buttonPressed = true; result = true; } if (result) { startCheckLongPress(); } } else { if (event.getAction() != MotionEvent.ACTION_MOVE) { cancelCheckLongPress(); } if (avatarPressed) { if (event.getAction() == MotionEvent.ACTION_UP) { avatarPressed = false; playSoundEffect(SoundEffectConstants.CLICK); if (contactUser != null) { if (delegate != null) { delegate.didPressedUserAvatar(this, contactUser); } } else { if (contactDelegate != null) { contactDelegate.didClickPhone(this); } } } else if (event.getAction() == MotionEvent.ACTION_CANCEL) { avatarPressed = false; } else if (event.getAction() == MotionEvent.ACTION_MOVE) { if (!(x >= avatarImage.getImageX() && x <= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(42) && y >= avatarImage.getImageY() && y <= avatarImage.getImageY() + avatarImage.getImageHeight())) { avatarPressed = false; } } } else if (buttonPressed) { if (event.getAction() == MotionEvent.ACTION_UP) { buttonPressed = false; playSoundEffect(SoundEffectConstants.CLICK); if (contactUser != null && contactDelegate != null) { contactDelegate.didClickAddButton(this, contactUser); } } else if (event.getAction() == MotionEvent.ACTION_CANCEL) { buttonPressed = false; } else if (event.getAction() == MotionEvent.ACTION_MOVE) { if (!(x >= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(52) && y >= AndroidUtilities.dp(13) + namesOffset && x <= avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(92) && y <= AndroidUtilities.dp(52) + namesOffset)) { buttonPressed = false; } } } } if (!result) { result = super.onTouchEvent(event); } return result; } @Override public void setMessageObject(MessageObject messageObject) { if (currentMessageObject != messageObject || isUserDataChanged()) { int uid = messageObject.messageOwner.media.user_id; contactUser = MessagesController.getInstance().getUser(uid); drawAddButton = contactUser != null && uid != UserConfig.getClientUserId() && ContactsController.getInstance().contactsDict.get(uid) == null; int maxWidth; if (AndroidUtilities.isTablet()) { maxWidth = (int) (AndroidUtilities.getMinTabletSide() * 0.7f); } else { maxWidth = (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.7f); } maxWidth -= AndroidUtilities.dp(58 + (drawAddButton ? 42 : 0)); if (contactUser != null) { if (contactUser.photo != null) { currentPhoto = contactUser.photo.photo_small; } else { currentPhoto = null; } avatarDrawable.setInfo(contactUser); } else { currentPhoto = null; avatarDrawable.setInfo(uid, null, null, false); } avatarImage.setImage(currentPhoto, "50_50", avatarDrawable, null, false); String currentNameString = ContactsController.formatName( messageObject.messageOwner.media.first_name, messageObject.messageOwner.media.last_name); int nameWidth = Math.min((int) Math.ceil(namePaint.measureText(currentNameString)), maxWidth); CharSequence stringFinal = TextUtils.ellipsize( currentNameString.replace("\n", " "), namePaint, nameWidth, TextUtils.TruncateAt.END); nameLayout = new StaticLayout( stringFinal, namePaint, nameWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); if (nameLayout.getLineCount() > 0) { nameWidth = (int) Math.ceil(nameLayout.getLineWidth(0)); } else { nameWidth = 0; } String phone = messageObject.messageOwner.media.phone_number; if (phone != null && phone.length() != 0) { if (!phone.startsWith("+")) { phone = "+" + phone; } phone = PhoneFormat.getInstance().format(phone); } else { phone = LocaleController.getString("NumberUnknown", R.string.NumberUnknown); } int phoneWidth = Math.min((int) Math.ceil(phonePaint.measureText(phone)), maxWidth); stringFinal = TextUtils.ellipsize( phone.replace("\n", " "), phonePaint, phoneWidth, TextUtils.TruncateAt.END); phoneLayout = new StaticLayout( stringFinal, phonePaint, phoneWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); if (phoneLayout.getLineCount() > 0) { phoneWidth = (int) Math.ceil(phoneLayout.getLineWidth(0)); } else { phoneWidth = 0; } namesWidth = Math.max(nameWidth, phoneWidth); backgroundWidth = AndroidUtilities.dp(77 + (drawAddButton ? 42 : 0)) + namesWidth; super.setMessageObject(messageObject); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension( MeasureSpec.getSize(widthMeasureSpec), AndroidUtilities.dp(71) + namesOffset); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if (currentMessageObject == null) { return; } int x; if (currentMessageObject.isOutOwner()) { x = layoutWidth - backgroundWidth + AndroidUtilities.dp(8); } else { if (isChat && currentMessageObject.messageOwner.from_id > 0) { x = AndroidUtilities.dp(69); } else { x = AndroidUtilities.dp(16); } } avatarImage.setImageCoords( x, AndroidUtilities.dp(9) + namesOffset, AndroidUtilities.dp(42), AndroidUtilities.dp(42)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (currentMessageObject == null) { return; } avatarImage.draw(canvas); if (nameLayout != null) { canvas.save(); canvas.translate( avatarImage.getImageX() + avatarImage.getImageWidth() + AndroidUtilities.dp(9), AndroidUtilities.dp(10) + namesOffset); namePaint.setColor( AvatarDrawable.getColorForId(currentMessageObject.messageOwner.media.user_id)); nameLayout.draw(canvas); canvas.restore(); } if (phoneLayout != null) { canvas.save(); canvas.translate( avatarImage.getImageX() + avatarImage.getImageWidth() + AndroidUtilities.dp(9), AndroidUtilities.dp(31) + namesOffset); phoneLayout.draw(canvas); canvas.restore(); } if (drawAddButton) { Drawable addContactDrawable; if (currentMessageObject.isOutOwner()) { addContactDrawable = addContactDrawableOut; } else { addContactDrawable = addContactDrawableIn; } setDrawableBounds( addContactDrawable, avatarImage.getImageX() + namesWidth + AndroidUtilities.dp(78), AndroidUtilities.dp(13) + namesOffset); addContactDrawable.draw(canvas); } } }