Search in sources :

Example 1 with LinkPath

use of org.telegram.ui.Components.LinkPath in project Telegram-FOSS by Telegram-FOSS-Team.

the class ChatMessageCell method checkGameMotionEvent.

private boolean checkGameMotionEvent(MotionEvent event) {
    if (!hasGamePreview) {
        return false;
    }
    int x = (int) event.getX();
    int y = (int) event.getY();
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        if (drawPhotoImage && drawImageButton && buttonState != -1 && x >= buttonX && x <= buttonX + AndroidUtilities.dp(48) && y >= buttonY && y <= buttonY + AndroidUtilities.dp(48) && radialProgress.getIcon() != MediaActionDrawable.ICON_NONE) {
            buttonPressed = 1;
            invalidate();
            return true;
        } else if (drawPhotoImage && photoImage.isInsideImage(x, y)) {
            gamePreviewPressed = true;
            return true;
        } else if (descriptionLayout != null && y >= descriptionY) {
            try {
                x -= unmovedTextX + AndroidUtilities.dp(10) + descriptionX;
                y -= descriptionY;
                final int line = descriptionLayout.getLineForVertical(y);
                final int off = descriptionLayout.getOffsetForHorizontal(line, x);
                final float left = descriptionLayout.getLineLeft(line);
                if (left <= x && left + descriptionLayout.getLineWidth(line) >= x) {
                    Spannable buffer = (Spannable) currentMessageObject.linkDescription;
                    ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
                    boolean ignore = false;
                    if (link.length == 0 || link[0] instanceof URLSpanBotCommand && !URLSpanBotCommand.enabled) {
                        ignore = true;
                    }
                    if (!ignore) {
                        pressedLink = link[0];
                        linkBlockNum = -10;
                        pressedLinkType = 2;
                        resetUrlPaths(false);
                        try {
                            LinkPath path = obtainNewUrlPath(false);
                            int[] pos = getRealSpanStartAndEnd(buffer, pressedLink);
                            path.setCurrentLayout(descriptionLayout, pos[0], 0);
                            descriptionLayout.getSelectionPath(pos[0], pos[1], path);
                        } catch (Exception e) {
                            FileLog.e(e);
                        }
                        invalidate();
                        return true;
                    }
                }
            } catch (Exception e) {
                FileLog.e(e);
            }
        }
    } else if (event.getAction() == MotionEvent.ACTION_UP) {
        if (pressedLinkType == 2 || gamePreviewPressed || buttonPressed != 0) {
            if (buttonPressed != 0) {
                buttonPressed = 0;
                playSoundEffect(SoundEffectConstants.CLICK);
                didPressButton(true, false);
                invalidate();
            } else if (pressedLink != null) {
                if (pressedLink instanceof URLSpan) {
                    Browser.openUrl(getContext(), ((URLSpan) pressedLink).getURL());
                } else if (pressedLink instanceof ClickableSpan) {
                    ((ClickableSpan) pressedLink).onClick(this);
                }
                resetPressedLink(2);
            } else {
                gamePreviewPressed = false;
                for (int a = 0; a < botButtons.size(); a++) {
                    BotButton button = botButtons.get(a);
                    if (button.button instanceof TLRPC.TL_keyboardButtonGame) {
                        playSoundEffect(SoundEffectConstants.CLICK);
                        delegate.didPressBotButton(this, button.button);
                        invalidate();
                        break;
                    }
                }
                resetPressedLink(2);
                return true;
            }
        } else {
            resetPressedLink(2);
        }
    }
    return false;
}
Also used : URLSpanBotCommand(org.telegram.ui.Components.URLSpanBotCommand) URLSpan(android.text.style.URLSpan) ClickableSpan(android.text.style.ClickableSpan) TextPaint(android.text.TextPaint) Paint(android.graphics.Paint) SuppressLint(android.annotation.SuppressLint) Point(org.telegram.ui.Components.Point) LinkPath(org.telegram.ui.Components.LinkPath) Spannable(android.text.Spannable)

Example 2 with LinkPath

use of org.telegram.ui.Components.LinkPath in project Telegram-FOSS by Telegram-FOSS-Team.

the class CameraScanActivity method createView.

@Override
public View createView(Context context) {
    actionBar.setBackButtonImage(R.drawable.ic_ab_back);
    actionBar.setItemsColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2), false);
    actionBar.setItemsBackgroundColor(Theme.getColor(Theme.key_actionBarWhiteSelector), false);
    actionBar.setCastShadows(false);
    if (!AndroidUtilities.isTablet() && !isQr()) {
        actionBar.showActionModeTop();
    }
    actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {

        @Override
        public void onItemClick(int id) {
            if (id == -1) {
                finishFragment();
            }
        }
    });
    paint.setColor(0x7f000000);
    cornerPaint.setColor(0xffffffff);
    cornerPaint.setStyle(Paint.Style.STROKE);
    cornerPaint.setStrokeWidth(AndroidUtilities.dp(4));
    cornerPaint.setStrokeJoin(Paint.Join.ROUND);
    ViewGroup viewGroup = new ViewGroup(context) {

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int height = MeasureSpec.getSize(heightMeasureSpec);
            actionBar.measure(widthMeasureSpec, heightMeasureSpec);
            if (currentType == TYPE_MRZ) {
                cameraView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec((int) (width * 0.704f), MeasureSpec.EXACTLY));
            } else {
                cameraView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
                recognizedMrzView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED));
                if (galleryButton != null) {
                    galleryButton.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(60), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(60), MeasureSpec.EXACTLY));
                }
                flashButton.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(60), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(60), MeasureSpec.EXACTLY));
            }
            titleTextView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(72), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED));
            descriptionText.measure(MeasureSpec.makeMeasureSpec((int) (width * 0.9f), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.UNSPECIFIED));
            setMeasuredDimension(width, height);
        }

        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            int width = r - l;
            int height = b - t;
            int y = 0;
            if (currentType == TYPE_MRZ) {
                cameraView.layout(0, y, cameraView.getMeasuredWidth(), y + cameraView.getMeasuredHeight());
                y = (int) (height * 0.65f);
                titleTextView.layout(AndroidUtilities.dp(36), y, AndroidUtilities.dp(36) + titleTextView.getMeasuredWidth(), y + titleTextView.getMeasuredHeight());
                recognizedMrzView.setTextSize(TypedValue.COMPLEX_UNIT_PX, cameraView.getMeasuredHeight() / 22);
                recognizedMrzView.setPadding(0, 0, 0, cameraView.getMeasuredHeight() / 15);
            } else {
                actionBar.layout(0, 0, actionBar.getMeasuredWidth(), actionBar.getMeasuredHeight());
                cameraView.layout(0, 0, cameraView.getMeasuredWidth(), cameraView.getMeasuredHeight());
                int size = (int) (Math.min(cameraView.getWidth(), cameraView.getHeight()) / 1.5f);
                if (currentType == TYPE_QR) {
                    y = (cameraView.getMeasuredHeight() - size) / 2 - titleTextView.getMeasuredHeight() - AndroidUtilities.dp(30);
                } else {
                    y = (cameraView.getMeasuredHeight() - size) / 2 - titleTextView.getMeasuredHeight() - AndroidUtilities.dp(64);
                }
                titleTextView.layout(AndroidUtilities.dp(36), y, AndroidUtilities.dp(36) + titleTextView.getMeasuredWidth(), y + titleTextView.getMeasuredHeight());
                recognizedMrzView.layout(0, getMeasuredHeight() - recognizedMrzView.getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight());
                int x;
                if (needGalleryButton) {
                    x = cameraView.getMeasuredWidth() / 2 + AndroidUtilities.dp(35);
                } else {
                    x = cameraView.getMeasuredWidth() / 2 - flashButton.getMeasuredWidth() / 2;
                }
                y = (cameraView.getMeasuredHeight() - size) / 2 + size + AndroidUtilities.dp(30);
                flashButton.layout(x, y, x + flashButton.getMeasuredWidth(), y + flashButton.getMeasuredHeight());
                if (galleryButton != null) {
                    x = cameraView.getMeasuredWidth() / 2 - AndroidUtilities.dp(35) - galleryButton.getMeasuredWidth();
                    galleryButton.layout(x, y, x + galleryButton.getMeasuredWidth(), y + galleryButton.getMeasuredHeight());
                }
            }
            y = (int) (height * 0.74f);
            int x = (int) (width * 0.05f);
            descriptionText.layout(x, y, x + descriptionText.getMeasuredWidth(), y + descriptionText.getMeasuredHeight());
        }

        @Override
        protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
            boolean result = super.drawChild(canvas, child, drawingTime);
            if (isQr() && child == cameraView) {
                int size = (int) (Math.min(child.getWidth(), child.getHeight()) / 1.5f);
                int x = (child.getWidth() - size) / 2;
                int y = (child.getHeight() - size) / 2;
                canvas.drawRect(0, 0, child.getMeasuredWidth(), y, paint);
                canvas.drawRect(0, y + size, child.getMeasuredWidth(), child.getMeasuredHeight(), paint);
                canvas.drawRect(0, y, x, y + size, paint);
                canvas.drawRect(x + size, y, child.getMeasuredWidth(), y + size, paint);
                path.reset();
                path.moveTo(x, y + AndroidUtilities.dp(20));
                path.lineTo(x, y);
                path.lineTo(x + AndroidUtilities.dp(20), y);
                canvas.drawPath(path, cornerPaint);
                path.reset();
                path.moveTo(x + size, y + AndroidUtilities.dp(20));
                path.lineTo(x + size, y);
                path.lineTo(x + size - AndroidUtilities.dp(20), y);
                canvas.drawPath(path, cornerPaint);
                path.reset();
                path.moveTo(x, y + size - AndroidUtilities.dp(20));
                path.lineTo(x, y + size);
                path.lineTo(x + AndroidUtilities.dp(20), y + size);
                canvas.drawPath(path, cornerPaint);
                path.reset();
                path.moveTo(x + size, y + size - AndroidUtilities.dp(20));
                path.lineTo(x + size, y + size);
                path.lineTo(x + size - AndroidUtilities.dp(20), y + size);
                canvas.drawPath(path, cornerPaint);
            }
            return result;
        }
    };
    viewGroup.setOnTouchListener((v, event) -> true);
    fragmentView = viewGroup;
    cameraView = new CameraView(context, false);
    cameraView.setUseMaxPreview(true);
    cameraView.setOptimizeForBarcode(true);
    cameraView.setDelegate(new CameraView.CameraViewDelegate() {

        @Override
        public void onCameraCreated(Camera camera) {
        }

        @Override
        public void onCameraInit() {
            startRecognizing();
        }
    });
    viewGroup.addView(cameraView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
    if (currentType == TYPE_MRZ) {
        actionBar.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
        fragmentView.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
    } else {
        actionBar.setBackgroundDrawable(null);
        actionBar.setAddToContainer(false);
        actionBar.setItemsColor(0xffffffff, false);
        actionBar.setItemsBackgroundColor(0x22ffffff, false);
        viewGroup.setBackgroundColor(Theme.getColor(Theme.key_wallet_blackBackground));
        viewGroup.addView(actionBar);
    }
    if (currentType == TYPE_QR_LOGIN) {
        actionBar.setTitle(LocaleController.getString("AuthAnotherClientScan", R.string.AuthAnotherClientScan));
    }
    Paint selectionPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    selectionPaint.setColor(ColorUtils.setAlphaComponent(Color.WHITE, 100));
    titleTextView = new TextView(context) {

        LinkPath textPath;

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if (getText() instanceof Spanned) {
                Spanned spanned = (Spanned) getText();
                URLSpanNoUnderline[] innerSpans = spanned.getSpans(0, spanned.length(), URLSpanNoUnderline.class);
                if (innerSpans != null && innerSpans.length > 0) {
                    textPath = new LinkPath(true);
                    textPath.setAllowReset(false);
                    for (int a = 0; a < innerSpans.length; a++) {
                        int start = spanned.getSpanStart(innerSpans[a]);
                        int end = spanned.getSpanEnd(innerSpans[a]);
                        textPath.setCurrentLayout(getLayout(), start, 0);
                        int shift = getText() != null ? getPaint().baselineShift : 0;
                        textPath.setBaselineShift(shift != 0 ? shift + AndroidUtilities.dp(shift > 0 ? 5 : -2) : 0);
                        getLayout().getSelectionPath(start, end, textPath);
                    }
                    textPath.setAllowReset(true);
                }
            }
        }

        @Override
        protected void onDraw(Canvas canvas) {
            if (textPath != null) {
                canvas.drawPath(textPath, selectionPaint);
            }
            super.onDraw(canvas);
        }
    };
    titleTextView.setGravity(Gravity.CENTER_HORIZONTAL);
    titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 24);
    viewGroup.addView(titleTextView);
    descriptionText = new TextView(context);
    descriptionText.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText6));
    descriptionText.setGravity(Gravity.CENTER_HORIZONTAL);
    descriptionText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
    viewGroup.addView(descriptionText);
    recognizedMrzView = new TextView(context);
    recognizedMrzView.setTextColor(0xffffffff);
    recognizedMrzView.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM);
    recognizedMrzView.setAlpha(0);
    if (currentType == TYPE_MRZ) {
        titleTextView.setText(LocaleController.getString("PassportScanPassport", R.string.PassportScanPassport));
        descriptionText.setText(LocaleController.getString("PassportScanPassportInfo", R.string.PassportScanPassportInfo));
        titleTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
        recognizedMrzView.setTypeface(Typeface.MONOSPACE);
        cameraView.addView(recognizedMrzView);
    } else {
        if (needGalleryButton) {
        // titleTextView.setText(LocaleController.getString("WalletScanCode", R.string.WalletScanCode));
        } else {
            if (currentType == TYPE_QR) {
                titleTextView.setText(LocaleController.getString("AuthAnotherClientScan", R.string.AuthAnotherClientScan));
            } else {
                String text = LocaleController.getString("AuthAnotherClientInfo5", R.string.AuthAnotherClientInfo5);
                SpannableStringBuilder spanned = new SpannableStringBuilder(text);
                int index1 = text.indexOf('*');
                int index2 = text.indexOf('*', index1 + 1);
                if (index1 != -1 && index2 != -1 && index1 != index2) {
                    titleTextView.setMovementMethod(new AndroidUtilities.LinkMovementMethodMy());
                    spanned.replace(index2, index2 + 1, " ");
                    spanned.replace(index1, index1 + 1, " ");
                    index1 += 1;
                    index2 += 1;
                    spanned.setSpan(new URLSpanNoUnderline(LocaleController.getString("AuthAnotherClientDownloadClientUrl", R.string.AuthAnotherClientDownloadClientUrl)), index1, index2 - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    spanned.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), index1, index2 - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
                text = spanned.toString();
                index1 = text.indexOf('*');
                index2 = text.indexOf('*', index1 + 1);
                if (index1 != -1 && index2 != -1 && index1 != index2) {
                    spanned.replace(index2, index2 + 1, " ");
                    spanned.replace(index1, index1 + 1, " ");
                    index1 += 1;
                    index2 += 1;
                    spanned.setSpan(new URLSpanNoUnderline(LocaleController.getString("AuthAnotherWebClientUrl", R.string.AuthAnotherWebClientUrl)), index1, index2 - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    spanned.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), index1, index2 - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
                titleTextView.setLinkTextColor(Color.WHITE);
                titleTextView.setHighlightColor(Theme.getColor(Theme.key_windowBackgroundWhiteLinkSelection));
                titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
                titleTextView.setLineSpacing(AndroidUtilities.dp(2), 1.0f);
                titleTextView.setPadding(0, 0, 0, 0);
                titleTextView.setText(spanned);
            }
        }
        titleTextView.setTextColor(0xffffffff);
        recognizedMrzView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
        recognizedMrzView.setPadding(AndroidUtilities.dp(10), 0, AndroidUtilities.dp(10), AndroidUtilities.dp(10));
        if (needGalleryButton) {
        // recognizedMrzView.setText(LocaleController.getString("WalletScanCodeNotFound", R.string.WalletScanCodeNotFound));
        } else {
            recognizedMrzView.setText(LocaleController.getString("AuthAnotherClientNotFound", R.string.AuthAnotherClientNotFound));
        }
        viewGroup.addView(recognizedMrzView);
        if (needGalleryButton) {
            galleryButton = new ImageView(context);
            galleryButton.setScaleType(ImageView.ScaleType.CENTER);
            galleryButton.setImageResource(R.drawable.qr_gallery);
            galleryButton.setBackgroundDrawable(Theme.createSelectorDrawableFromDrawables(Theme.createCircleDrawable(AndroidUtilities.dp(60), 0x22ffffff), Theme.createCircleDrawable(AndroidUtilities.dp(60), 0x44ffffff)));
            viewGroup.addView(galleryButton);
            galleryButton.setOnClickListener(currentImage -> {
                if (getParentActivity() == null) {
                    return;
                }
                if (Build.VERSION.SDK_INT >= 23) {
                    if (getParentActivity().checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                        getParentActivity().requestPermissions(new String[] { Manifest.permission.READ_EXTERNAL_STORAGE }, 4);
                        return;
                    }
                }
                PhotoAlbumPickerActivity fragment = new PhotoAlbumPickerActivity(PhotoAlbumPickerActivity.SELECT_TYPE_QR, false, false, null);
                fragment.setMaxSelectedPhotos(1, false);
                fragment.setAllowSearchImages(false);
                fragment.setDelegate(new PhotoAlbumPickerActivity.PhotoAlbumPickerActivityDelegate() {

                    @Override
                    public void didSelectPhotos(ArrayList<SendMessagesHelper.SendingMediaInfo> photos, boolean notify, int scheduleDate) {
                        try {
                            if (!photos.isEmpty()) {
                                SendMessagesHelper.SendingMediaInfo info = photos.get(0);
                                if (info.path != null) {
                                    Point screenSize = AndroidUtilities.getRealScreenSize();
                                    Bitmap bitmap = ImageLoader.loadBitmap(info.path, null, screenSize.x, screenSize.y, true);
                                    String text = tryReadQr(null, null, 0, 0, 0, bitmap);
                                    if (text != null) {
                                        if (delegate != null) {
                                            delegate.didFindQr(text);
                                        }
                                        removeSelfFromStack();
                                    }
                                }
                            }
                        } catch (Throwable e) {
                            FileLog.e(e);
                        }
                    }

                    @Override
                    public void startPhotoSelectActivity() {
                        try {
                            Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
                            photoPickerIntent.setType("image/*");
                            getParentActivity().startActivityForResult(photoPickerIntent, 11);
                        } catch (Exception e) {
                            FileLog.e(e);
                        }
                    }
                });
                presentFragment(fragment);
            });
        }
        flashButton = new ImageView(context);
        flashButton.setScaleType(ImageView.ScaleType.CENTER);
        flashButton.setImageResource(R.drawable.qr_flashlight);
        flashButton.setBackgroundDrawable(Theme.createCircleDrawable(AndroidUtilities.dp(60), 0x22ffffff));
        viewGroup.addView(flashButton);
        flashButton.setOnClickListener(currentImage -> {
            CameraSession session = cameraView.getCameraSession();
            if (session != null) {
                ShapeDrawable shapeDrawable = (ShapeDrawable) flashButton.getBackground();
                if (flashAnimator != null) {
                    flashAnimator.cancel();
                    flashAnimator = null;
                }
                flashAnimator = new AnimatorSet();
                ObjectAnimator animator = ObjectAnimator.ofInt(shapeDrawable, AnimationProperties.SHAPE_DRAWABLE_ALPHA, flashButton.getTag() == null ? 0x44 : 0x22);
                animator.addUpdateListener(animation -> flashButton.invalidate());
                flashAnimator.playTogether(animator);
                flashAnimator.setDuration(200);
                flashAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
                flashAnimator.addListener(new AnimatorListenerAdapter() {

                    @Override
                    public void onAnimationEnd(Animator animation) {
                        flashAnimator = null;
                    }
                });
                flashAnimator.start();
                if (flashButton.getTag() == null) {
                    flashButton.setTag(1);
                    session.setTorchEnabled(true);
                } else {
                    flashButton.setTag(null);
                    session.setTorchEnabled(false);
                }
            }
        });
    }
    if (getParentActivity() != null) {
        getParentActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }
    fragmentView.setKeepScreenOn(true);
    return fragmentView;
}
Also used : AnimatorSet(android.animation.AnimatorSet) Bitmap(android.graphics.Bitmap) BinaryBitmap(com.google.zxing.BinaryBitmap) AnimatorListenerAdapter(android.animation.AnimatorListenerAdapter) LinkPath(org.telegram.ui.Components.LinkPath) CameraSession(org.telegram.messenger.camera.CameraSession) TextView(android.widget.TextView) Camera(android.hardware.Camera) ImageView(android.widget.ImageView) URLSpanNoUnderline(org.telegram.ui.Components.URLSpanNoUnderline) ActionBar(org.telegram.ui.ActionBar.ActionBar) ViewGroup(android.view.ViewGroup) ObjectAnimator(android.animation.ObjectAnimator) Canvas(android.graphics.Canvas) Intent(android.content.Intent) Paint(android.graphics.Paint) Point(android.graphics.Point) ImageView(android.widget.ImageView) View(android.view.View) TextView(android.widget.TextView) CameraView(org.telegram.messenger.camera.CameraView) Spanned(android.text.Spanned) Paint(android.graphics.Paint) Point(android.graphics.Point) CameraView(org.telegram.messenger.camera.CameraView) NotFoundException(com.google.zxing.NotFoundException) AndroidUtilities(org.telegram.messenger.AndroidUtilities) Animator(android.animation.Animator) ObjectAnimator(android.animation.ObjectAnimator) ShapeDrawable(android.graphics.drawable.ShapeDrawable) SpannableStringBuilder(android.text.SpannableStringBuilder) TypefaceSpan(org.telegram.ui.Components.TypefaceSpan)

Example 3 with LinkPath

use of org.telegram.ui.Components.LinkPath in project Telegram-FOSS by Telegram-FOSS-Team.

the class ArticleViewer method createLayoutForText.

private DrawingText createLayoutForText(View parentView, CharSequence plainText, TLRPC.RichText richText, int width, int textY, TLRPC.PageBlock parentBlock, Layout.Alignment align, int maxLines, WebpageAdapter parentAdapter) {
    if (plainText == null && (richText == null || richText instanceof TLRPC.TL_textEmpty)) {
        return null;
    }
    if (width < 0) {
        width = AndroidUtilities.dp(10);
    }
    CharSequence text;
    if (plainText != null) {
        text = plainText;
    } else {
        text = getText(parentAdapter, parentView, richText, richText, parentBlock, width);
    }
    if (TextUtils.isEmpty(text)) {
        return null;
    }
    int additionalSize = AndroidUtilities.dp(SharedConfig.ivFontSize - 16);
    TextPaint paint;
    if (parentBlock instanceof TLRPC.TL_pageBlockEmbedPost && richText == null) {
        TLRPC.TL_pageBlockEmbedPost pageBlockEmbedPost = (TLRPC.TL_pageBlockEmbedPost) parentBlock;
        if (pageBlockEmbedPost.author == plainText) {
            if (embedPostAuthorPaint == null) {
                embedPostAuthorPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
                embedPostAuthorPaint.setColor(getTextColor());
            }
            embedPostAuthorPaint.setTextSize(AndroidUtilities.dp(15) + additionalSize);
            paint = embedPostAuthorPaint;
        } else {
            if (embedPostDatePaint == null) {
                embedPostDatePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
                embedPostDatePaint.setColor(getGrayTextColor());
            }
            embedPostDatePaint.setTextSize(AndroidUtilities.dp(14) + additionalSize);
            paint = embedPostDatePaint;
        }
    } else if (parentBlock instanceof TLRPC.TL_pageBlockChannel) {
        if (channelNamePaint == null) {
            channelNamePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
            channelNamePaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
            channelNamePhotoPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
            channelNamePhotoPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
        }
        channelNamePaint.setColor(getTextColor());
        channelNamePaint.setTextSize(AndroidUtilities.dp(15));
        channelNamePhotoPaint.setColor(0xffffffff);
        channelNamePhotoPaint.setTextSize(AndroidUtilities.dp(15));
        paint = parentAdapter.channelBlock != null ? channelNamePhotoPaint : channelNamePaint;
    } else if (parentBlock instanceof TL_pageBlockRelatedArticlesChild) {
        TL_pageBlockRelatedArticlesChild pageBlockRelatedArticlesChild = (TL_pageBlockRelatedArticlesChild) parentBlock;
        if (plainText == pageBlockRelatedArticlesChild.parent.articles.get(pageBlockRelatedArticlesChild.num).title) {
            if (relatedArticleHeaderPaint == null) {
                relatedArticleHeaderPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
                relatedArticleHeaderPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
            }
            relatedArticleHeaderPaint.setColor(getTextColor());
            relatedArticleHeaderPaint.setTextSize(AndroidUtilities.dp(15) + additionalSize);
            paint = relatedArticleHeaderPaint;
        } else {
            if (relatedArticleTextPaint == null) {
                relatedArticleTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
            }
            relatedArticleTextPaint.setColor(getGrayTextColor());
            relatedArticleTextPaint.setTextSize(AndroidUtilities.dp(14) + additionalSize);
            paint = relatedArticleTextPaint;
        }
    } else if (isListItemBlock(parentBlock) && plainText != null) {
        if (listTextPointerPaint == null) {
            listTextPointerPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
            listTextPointerPaint.setColor(getTextColor());
        }
        if (listTextNumPaint == null) {
            listTextNumPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
            listTextNumPaint.setColor(getTextColor());
        }
        listTextPointerPaint.setTextSize(AndroidUtilities.dp(19) + additionalSize);
        listTextNumPaint.setTextSize(AndroidUtilities.dp(16) + additionalSize);
        if (parentBlock instanceof TL_pageBlockListItem && !((TL_pageBlockListItem) parentBlock).parent.pageBlockList.ordered) {
            paint = listTextPointerPaint;
        } else {
            paint = listTextNumPaint;
        }
    } else {
        paint = getTextPaint(richText, richText, parentBlock);
    }
    StaticLayout result;
    if (maxLines != 0) {
        if (parentBlock instanceof TLRPC.TL_pageBlockPullquote) {
            result = StaticLayoutEx.createStaticLayout(text, paint, width, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false, TextUtils.TruncateAt.END, width, maxLines);
        } else {
            result = StaticLayoutEx.createStaticLayout(text, paint, width, align, 1.0f, AndroidUtilities.dp(4), false, TextUtils.TruncateAt.END, width, maxLines);
        }
    } else {
        if (text.charAt(text.length() - 1) == '\n') {
            text = text.subSequence(0, text.length() - 1);
        }
        if (parentBlock instanceof TLRPC.TL_pageBlockPullquote) {
            result = new StaticLayout(text, paint, width, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
        } else {
            result = new StaticLayout(text, paint, width, align, 1.0f, AndroidUtilities.dp(4), false);
        }
    }
    if (result == null) {
        return null;
    }
    CharSequence finalText = result.getText();
    LinkPath textPath = null;
    LinkPath markPath = null;
    if (textY >= 0) {
        if (result != null && !searchResults.isEmpty() && searchText != null) {
            String lowerString = text.toString().toLowerCase();
            int startIndex = 0;
            int index;
            while ((index = lowerString.indexOf(searchText, startIndex)) >= 0) {
                startIndex = index + searchText.length();
                if (index == 0 || AndroidUtilities.isPunctuationCharacter(lowerString.charAt(index - 1))) {
                    adapter[0].searchTextOffset.put(searchText + parentBlock + richText + index, textY + result.getLineTop(result.getLineForOffset(index)));
                }
            }
        }
    }
    if (result != null && finalText instanceof Spanned) {
        Spanned spanned = (Spanned) finalText;
        try {
            AnchorSpan[] innerSpans = spanned.getSpans(0, spanned.length(), AnchorSpan.class);
            int linesCount = result.getLineCount();
            if (innerSpans != null && innerSpans.length > 0) {
                for (int a = 0; a < innerSpans.length; a++) {
                    if (linesCount <= 1) {
                        parentAdapter.anchorsOffset.put(innerSpans[a].getName(), textY);
                    } else {
                        parentAdapter.anchorsOffset.put(innerSpans[a].getName(), textY + result.getLineTop(result.getLineForOffset(spanned.getSpanStart(innerSpans[a]))));
                    }
                }
            }
        } catch (Exception ignore) {
        }
        try {
            TextPaintWebpageUrlSpan[] innerSpans = spanned.getSpans(0, spanned.length(), TextPaintWebpageUrlSpan.class);
            if (innerSpans != null && innerSpans.length > 0) {
                textPath = new LinkPath(true);
                textPath.setAllowReset(false);
                for (int a = 0; a < innerSpans.length; a++) {
                    int start = spanned.getSpanStart(innerSpans[a]);
                    int end = spanned.getSpanEnd(innerSpans[a]);
                    textPath.setCurrentLayout(result, start, 0);
                    int shift = innerSpans[a].getTextPaint() != null ? innerSpans[a].getTextPaint().baselineShift : 0;
                    textPath.setBaselineShift(shift != 0 ? shift + AndroidUtilities.dp(shift > 0 ? 5 : -2) : 0);
                    result.getSelectionPath(start, end, textPath);
                }
                textPath.setAllowReset(true);
            }
        } catch (Exception ignore) {
        }
        try {
            TextPaintMarkSpan[] innerSpans = spanned.getSpans(0, spanned.length(), TextPaintMarkSpan.class);
            if (innerSpans != null && innerSpans.length > 0) {
                markPath = new LinkPath(true);
                markPath.setAllowReset(false);
                for (int a = 0; a < innerSpans.length; a++) {
                    int start = spanned.getSpanStart(innerSpans[a]);
                    int end = spanned.getSpanEnd(innerSpans[a]);
                    markPath.setCurrentLayout(result, start, 0);
                    int shift = innerSpans[a].getTextPaint() != null ? innerSpans[a].getTextPaint().baselineShift : 0;
                    markPath.setBaselineShift(shift != 0 ? shift + AndroidUtilities.dp(shift > 0 ? 5 : -2) : 0);
                    result.getSelectionPath(start, end, markPath);
                }
                markPath.setAllowReset(true);
            }
        } catch (Exception ignore) {
        }
    }
    DrawingText drawingText = new DrawingText();
    drawingText.textLayout = result;
    drawingText.textPath = textPath;
    drawingText.markPath = markPath;
    drawingText.parentBlock = parentBlock;
    drawingText.parentText = richText;
    return drawingText;
}
Also used : TextPaintWebpageUrlSpan(org.telegram.ui.Components.TextPaintWebpageUrlSpan) TextPaintMarkSpan(org.telegram.ui.Components.TextPaintMarkSpan) StaticLayout(android.text.StaticLayout) Spanned(android.text.Spanned) TLRPC(org.telegram.tgnet.TLRPC) TextPaint(android.text.TextPaint) Paint(android.graphics.Paint) SuppressLint(android.annotation.SuppressLint) TextPaint(android.text.TextPaint) LinkPath(org.telegram.ui.Components.LinkPath) AnchorSpan(org.telegram.ui.Components.AnchorSpan)

Example 4 with LinkPath

use of org.telegram.ui.Components.LinkPath in project Telegram-FOSS by Telegram-FOSS-Team.

the class ChatMessageCell method checkCaptionMotionEvent.

private boolean checkCaptionMotionEvent(MotionEvent event) {
    if (!(currentCaption instanceof Spannable) || captionLayout == null) {
        return false;
    }
    if (event.getAction() == MotionEvent.ACTION_DOWN || (linkPreviewPressed || pressedLink != null) && event.getAction() == MotionEvent.ACTION_UP) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        if (x >= captionX && x <= captionX + captionWidth && y >= captionY && y <= captionY + captionHeight) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                try {
                    x -= captionX;
                    y -= captionY;
                    final int line = captionLayout.getLineForVertical(y);
                    final int off = captionLayout.getOffsetForHorizontal(line, x);
                    final float left = captionLayout.getLineLeft(line);
                    if (left <= x && left + captionLayout.getLineWidth(line) >= x) {
                        Spannable buffer = (Spannable) currentCaption;
                        CharacterStyle[] link = buffer.getSpans(off, off, ClickableSpan.class);
                        if (link == null || link.length == 0) {
                            link = buffer.getSpans(off, off, URLSpanMono.class);
                        }
                        boolean ignore = false;
                        if (link.length == 0 || link[0] instanceof URLSpanBotCommand && !URLSpanBotCommand.enabled) {
                            ignore = true;
                        }
                        if (!ignore) {
                            pressedLink = link[0];
                            pressedLinkType = 3;
                            resetUrlPaths(false);
                            try {
                                LinkPath path = obtainNewUrlPath(false);
                                int[] pos = getRealSpanStartAndEnd(buffer, pressedLink);
                                path.setCurrentLayout(captionLayout, pos[0], 0);
                                captionLayout.getSelectionPath(pos[0], pos[1], path);
                            } catch (Exception e) {
                                FileLog.e(e);
                            }
                            invalidateWithParent();
                            return true;
                        }
                    }
                } catch (Exception e) {
                    FileLog.e(e);
                }
            } else if (pressedLinkType == 3) {
                delegate.didPressUrl(this, pressedLink, false);
                resetPressedLink(3);
                return true;
            }
        } else {
            resetPressedLink(3);
        }
    }
    return false;
}
Also used : URLSpanMono(org.telegram.ui.Components.URLSpanMono) URLSpanBotCommand(org.telegram.ui.Components.URLSpanBotCommand) LinkPath(org.telegram.ui.Components.LinkPath) Spannable(android.text.Spannable) TextPaint(android.text.TextPaint) Paint(android.graphics.Paint) SuppressLint(android.annotation.SuppressLint) Point(org.telegram.ui.Components.Point) CharacterStyle(android.text.style.CharacterStyle)

Example 5 with LinkPath

use of org.telegram.ui.Components.LinkPath in project Telegram-FOSS by Telegram-FOSS-Team.

the class ChatMessageCell method obtainNewUrlPath.

private LinkPath obtainNewUrlPath(boolean text) {
    LinkPath linkPath;
    if (!urlPathCache.isEmpty()) {
        linkPath = urlPathCache.get(0);
        urlPathCache.remove(0);
    } else {
        linkPath = new LinkPath();
        linkPath.setUseRoundRect(true);
    }
    linkPath.reset();
    if (text) {
        urlPathSelection.add(linkPath);
    } else {
        urlPath.add(linkPath);
    }
    return linkPath;
}
Also used : LinkPath(org.telegram.ui.Components.LinkPath)

Aggregations

LinkPath (org.telegram.ui.Components.LinkPath)8 Paint (android.graphics.Paint)7 SuppressLint (android.annotation.SuppressLint)6 TextPaint (android.text.TextPaint)6 Point (org.telegram.ui.Components.Point)5 Spannable (android.text.Spannable)4 URLSpanBotCommand (org.telegram.ui.Components.URLSpanBotCommand)4 ClickableSpan (android.text.style.ClickableSpan)3 Spanned (android.text.Spanned)2 CharacterStyle (android.text.style.CharacterStyle)2 URLSpan (android.text.style.URLSpan)2 MessageObject (org.telegram.messenger.MessageObject)2 TLRPC (org.telegram.tgnet.TLRPC)2 URLSpanMono (org.telegram.ui.Components.URLSpanMono)2 Animator (android.animation.Animator)1 AnimatorListenerAdapter (android.animation.AnimatorListenerAdapter)1 AnimatorSet (android.animation.AnimatorSet)1 ObjectAnimator (android.animation.ObjectAnimator)1 Intent (android.content.Intent)1 Bitmap (android.graphics.Bitmap)1