Пример #1
0
  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    if (currentMessageObject == null) {
      setMeasuredDimension(
          MeasureSpec.getSize(widthMeasureSpec), textHeight + AndroidUtilities.dp(14));
      return;
    }
    int width = Math.max(AndroidUtilities.dp(30), MeasureSpec.getSize(widthMeasureSpec));
    if (width != previousWidth) {
      previousWidth = width;

      textLayout =
          new StaticLayout(
              currentMessageObject.messageText,
              textPaint,
              width - AndroidUtilities.dp(30),
              Layout.Alignment.ALIGN_CENTER,
              1.0f,
              0.0f,
              false);
      textHeight = 0;
      textWidth = 0;
      try {
        int linesCount = textLayout.getLineCount();
        for (int a = 0; a < linesCount; a++) {
          float lineWidth;
          try {
            lineWidth = textLayout.getLineWidth(a);
            textHeight = (int) Math.max(textHeight, Math.ceil(textLayout.getLineBottom(a)));
          } catch (Exception e) {
            FileLog.e("tmessages", e);
            return;
          }
          textWidth = (int) Math.max(textWidth, Math.ceil(lineWidth));
        }
      } catch (Exception e) {
        FileLog.e("tmessages", e);
      }

      textX = (width - textWidth) / 2;
      textY = AndroidUtilities.dp(7);
      textXLeft = (width - textLayout.getWidth()) / 2;

      if (currentMessageObject.type == MessageObject.Type.MSG_ACTION) {
        imageReceiver.setImageCoords(
            (width - AndroidUtilities.dp(64)) / 2,
            textHeight + AndroidUtilities.dp(15),
            AndroidUtilities.dp(64),
            AndroidUtilities.dp(64));
      }
    }
    setMeasuredDimension(
        width,
        textHeight
            + AndroidUtilities.dp(
                14 + (currentMessageObject.type == MessageObject.Type.MSG_ACTION ? 70 : 0)));
  }
        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
        @Override
        public int onTestSize(int suggestedSize, RectF availableSPace) {
          mPaint.setTextSize(suggestedSize);
          String text = getText().toString();
          boolean singleline = getMaxLines() == 1;
          if (singleline) {
            mTextRect.bottom = mPaint.getFontSpacing();
            mTextRect.right = mPaint.measureText(text);
          } else {
            StaticLayout layout =
                new StaticLayout(
                    text,
                    mPaint,
                    mWidthLimit,
                    Alignment.ALIGN_NORMAL,
                    mSpacingMult,
                    mSpacingAdd,
                    true);
            // return early if we have more lines
            if (getMaxLines() != NO_LINE_LIMIT && layout.getLineCount() > getMaxLines()) {
              return 1;
            }
            mTextRect.bottom = layout.getHeight();
            int maxWidth = -1;
            for (int i = 0; i < layout.getLineCount(); i++) {
              if (maxWidth < layout.getLineWidth(i)) {
                maxWidth = (int) layout.getLineWidth(i);
              }
            }
            mTextRect.right = maxWidth;
          }

          mTextRect.offsetTo(0, 0);
          if (availableSPace.contains(mTextRect)) {
            // may be too small, don't worry we will find the best match
            return -1;
          } else {
            // too big
            return 1;
          }
        }
Пример #3
0
 public void setText(String text) {
   if (text == null || text.length() == 0) {
     setVisibility(GONE);
     return;
   }
   if (text != null && oldText != null && text.equals(oldText)) {
     return;
   }
   oldText = text;
   setVisibility(VISIBLE);
   if (AndroidUtilities.isTablet()) {
     width = (int) (AndroidUtilities.getMinTabletSide() * 0.7f);
   } else {
     width =
         (int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.7f);
   }
   SpannableStringBuilder stringBuilder = new SpannableStringBuilder();
   String help = LocaleController.getString("BotInfoTitle", R.string.BotInfoTitle);
   stringBuilder.append(help);
   stringBuilder.append("\n\n");
   stringBuilder.append(text);
   MessageObject.addLinks(stringBuilder);
   stringBuilder.setSpan(
       new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")),
       0,
       help.length(),
       Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
   textLayout =
       new StaticLayout(
           stringBuilder, textPaint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
   width = 0;
   height = textLayout.getHeight() + AndroidUtilities.dp(4 + 18);
   int count = textLayout.getLineCount();
   for (int a = 0; a < count; a++) {
     width =
         (int) Math.ceil(Math.max(width, textLayout.getLineWidth(a) - textLayout.getLineLeft(a)));
   }
   width += AndroidUtilities.dp(4 + 18);
 }
Пример #4
0
    private void renderBottomLabel(
        Canvas canvas, RadRect dataPointSlot, String labelText, StaticLayout textBounds) {
      RectF labelBounds = new RectF();
      double height = textBounds.getHeight() + this.labelPadding * 2;
      double top = dataPointSlot.getBottom() + this.labelMargin;
      labelBounds.set(
          (float) dataPointSlot.x,
          (float) top,
          (float) dataPointSlot.getRight(),
          (float) (top + height));

      canvas.drawRect(
          labelBounds.left, labelBounds.top, labelBounds.right, labelBounds.bottom, this.lowFill);
      canvas.drawRect(
          labelBounds.left, labelBounds.top, labelBounds.right, labelBounds.bottom, this.stroke);
      canvas.drawText(
          labelText,
          (float)
              (dataPointSlot.x + (dataPointSlot.width / 2.0) - textBounds.getLineWidth(0) / 2.0f),
          labelBounds.centerY() + textBounds.getLineBottom(0) - textBounds.getLineBaseline(0),
          paint);
    }
Пример #5
0
  private static float getAutofitTextSize(
      CharSequence text,
      TextPaint paint,
      float targetWidth,
      int maxLines,
      float low,
      float high,
      float precision,
      DisplayMetrics displayMetrics) {
    float mid = (low + high) / 2.0f;
    int lineCount = 1;
    StaticLayout layout = null;

    paint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, mid, displayMetrics));

    if (maxLines != 1) {
      layout =
          new StaticLayout(
              text, paint, (int) targetWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true);
      lineCount = layout.getLineCount();
    }

    if (SPEW)
      Log.d(
          TAG,
          "low="
              + low
              + " high="
              + high
              + " mid="
              + mid
              + " target="
              + targetWidth
              + " maxLines="
              + maxLines
              + " lineCount="
              + lineCount);

    if (lineCount > maxLines) {
      if ((high - low) < precision) {
        return low;
      }
      return getAutofitTextSize(
          text, paint, targetWidth, maxLines, low, mid, precision, displayMetrics);
    } else if (lineCount < maxLines) {
      return getAutofitTextSize(
          text, paint, targetWidth, maxLines, mid, high, precision, displayMetrics);
    } else {
      float maxLineWidth = 0;
      if (maxLines == 1) {
        maxLineWidth = paint.measureText(text, 0, text.length());
      } else {
        for (int i = 0; i < lineCount; i++) {
          if (layout.getLineWidth(i) > maxLineWidth) {
            maxLineWidth = layout.getLineWidth(i);
          }
        }
      }

      if ((high - low) < precision) {
        return low;
      } else if (maxLineWidth > targetWidth) {
        return getAutofitTextSize(
            text, paint, targetWidth, maxLines, low, mid, precision, displayMetrics);
      } else if (maxLineWidth < targetWidth) {
        return getAutofitTextSize(
            text, paint, targetWidth, maxLines, mid, high, precision, displayMetrics);
      } else {
        return mid;
      }
    }
  }
Пример #6
0
 public static StaticLayout createStaticLayout(
     CharSequence source,
     int bufstart,
     int bufend,
     TextPaint paint,
     int outerWidth,
     Layout.Alignment align,
     float spacingMult,
     float spacingAdd,
     boolean includePad,
     TextUtils.TruncateAt ellipsize,
     int ellipsisWidth,
     int maxLines) {
   /*if (Build.VERSION.SDK_INT >= 14) {
       init();
       try {
           sConstructorArgs[0] = source;
           sConstructorArgs[1] = bufstart;
           sConstructorArgs[2] = bufend;
           sConstructorArgs[3] = paint;
           sConstructorArgs[4] = outerWidth;
           sConstructorArgs[5] = align;
           sConstructorArgs[6] = sTextDirection;
           sConstructorArgs[7] = spacingMult;
           sConstructorArgs[8] = spacingAdd;
           sConstructorArgs[9] = includePad;
           sConstructorArgs[10] = ellipsize;
           sConstructorArgs[11] = ellipsisWidth;
           sConstructorArgs[12] = maxLines;
           return sConstructor.newInstance(sConstructorArgs);
       } catch (Exception e) {
           FileLog.e("tmessages", e);
       }
   }*/
   try {
     if (maxLines == 1) {
       CharSequence text =
           TextUtils.ellipsize(source, paint, ellipsisWidth, TextUtils.TruncateAt.END);
       return new StaticLayout(
           text, 0, text.length(), paint, outerWidth, align, spacingMult, spacingAdd, includePad);
     } else {
       StaticLayout layout =
           new StaticLayout(source, paint, outerWidth, align, spacingMult, spacingAdd, includePad);
       if (layout.getLineCount() <= maxLines) {
         return layout;
       } else {
         int off;
         float left = layout.getLineLeft(maxLines - 1);
         if (left != 0) {
           off = layout.getOffsetForHorizontal(maxLines - 1, left);
         } else {
           off = layout.getOffsetForHorizontal(maxLines - 1, layout.getLineWidth(maxLines - 1));
         }
         SpannableStringBuilder stringBuilder =
             new SpannableStringBuilder(source.subSequence(0, Math.max(0, off - 1)));
         stringBuilder.append("\u2026");
         return new StaticLayout(
             stringBuilder, paint, outerWidth, align, spacingMult, spacingAdd, includePad);
       }
     }
   } catch (Exception e) {
     FileLog.e("tmessages", e);
   }
   return null;
 }
Пример #7
0
  @Override
  protected void onDraw(Canvas canvas) {
    if (user == null && chat == null && encryptedChat == null) {
      return;
    }

    if (useSeparator) {
      if (LocaleController.isRTL) {
        canvas.drawLine(
            0,
            getMeasuredHeight() - 1,
            getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline),
            getMeasuredHeight() - 1,
            linePaint);
      } else {
        canvas.drawLine(
            AndroidUtilities.dp(AndroidUtilities.leftBaseline),
            getMeasuredHeight() - 1,
            getMeasuredWidth(),
            getMeasuredHeight() - 1,
            linePaint);
      }
    }

    if (drawAlpha != 1) {
      canvas.saveLayerAlpha(
          0,
          0,
          canvas.getWidth(),
          canvas.getHeight(),
          (int) (255 * drawAlpha),
          Canvas.HAS_ALPHA_LAYER_SAVE_FLAG);
    }

    if (drawNameLock) {
      setDrawableBounds(lockDrawable, nameLockLeft, nameLockTop);
      lockDrawable.draw(canvas);
    } else if (drawNameGroup) {
      setDrawableBounds(groupDrawable, nameLockLeft, nameLockTop);
      groupDrawable.draw(canvas);
    } else if (drawNameBroadcast) {
      setDrawableBounds(broadcastDrawable, nameLockLeft, nameLockTop);
      broadcastDrawable.draw(canvas);
    } else if (drawNameBot) {
      setDrawableBounds(botDrawable, nameLockLeft, nameLockTop);
      botDrawable.draw(canvas);
    }

    if (nameLayout != null) {
      canvas.save();
      canvas.translate(nameLeft, nameTop);
      nameLayout.draw(canvas);
      canvas.restore();
      if (drawCheck) {
        if (LocaleController.isRTL) {
          setDrawableBounds(
              checkDrawable,
              nameLeft - AndroidUtilities.dp(4) - checkDrawable.getIntrinsicWidth(),
              nameLockTop);
        } else {
          setDrawableBounds(
              checkDrawable,
              nameLeft + (int) nameLayout.getLineWidth(0) + AndroidUtilities.dp(4),
              nameLockTop);
        }
        checkDrawable.draw(canvas);
      }
    }

    if (onlineLayout != null) {
      canvas.save();
      canvas.translate(onlineLeft, AndroidUtilities.dp(40));
      onlineLayout.draw(canvas);
      canvas.restore();
    }

    if (countLayout != null) {
      if (MessagesController.getInstance().isDialogMuted(dialog_id)) {
        setDrawableBounds(
            countDrawableGrey,
            countLeft - AndroidUtilities.dp(5.5f),
            countTop,
            countWidth + AndroidUtilities.dp(11),
            countDrawableGrey.getIntrinsicHeight());
        countDrawableGrey.draw(canvas);
      } else {
        setDrawableBounds(
            countDrawable,
            countLeft - AndroidUtilities.dp(5.5f),
            countTop,
            countWidth + AndroidUtilities.dp(11),
            countDrawable.getIntrinsicHeight());
        countDrawable.draw(canvas);
      }
      canvas.save();
      canvas.translate(countLeft, countTop + AndroidUtilities.dp(4));
      countLayout.draw(canvas);
      canvas.restore();
    }

    avatarImage.draw(canvas);
  }
Пример #8
0
  public void buildLayout() {
    CharSequence nameString;
    TextPaint currentNamePaint;

    drawNameBroadcast = false;
    drawNameLock = false;
    drawNameGroup = false;
    drawCheck = false;
    drawNameBot = false;

    if (encryptedChat != null) {
      drawNameLock = true;
      dialog_id = ((long) encryptedChat.id) << 32;
      if (!LocaleController.isRTL) {
        nameLockLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
        nameLeft =
            AndroidUtilities.dp(AndroidUtilities.leftBaseline + 4)
                + lockDrawable.getIntrinsicWidth();
      } else {
        nameLockLeft =
            getMeasuredWidth()
                - AndroidUtilities.dp(AndroidUtilities.leftBaseline + 2)
                - lockDrawable.getIntrinsicWidth();
        nameLeft = AndroidUtilities.dp(11);
      }
      nameLockTop = AndroidUtilities.dp(16.5f);
    } else {
      if (chat != null) {
        if (chat.id < 0) {
          dialog_id = AndroidUtilities.makeBroadcastId(chat.id);
          drawNameBroadcast = true;
          nameLockTop = AndroidUtilities.dp(28.5f);
        } else {
          dialog_id = -chat.id;
          if (ChatObject.isChannel(chat) && !chat.megagroup) {
            drawNameBroadcast = true;
            nameLockTop = AndroidUtilities.dp(28.5f);
          } else {
            drawNameGroup = true;
            nameLockTop = AndroidUtilities.dp(30);
          }
        }
        drawCheck = chat.verified;
        if (!LocaleController.isRTL) {
          nameLockLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
          nameLeft =
              AndroidUtilities.dp(AndroidUtilities.leftBaseline + 4)
                  + (drawNameGroup
                      ? groupDrawable.getIntrinsicWidth()
                      : broadcastDrawable.getIntrinsicWidth());
        } else {
          nameLockLeft =
              getMeasuredWidth()
                  - AndroidUtilities.dp(AndroidUtilities.leftBaseline + 2)
                  - (drawNameGroup
                      ? groupDrawable.getIntrinsicWidth()
                      : broadcastDrawable.getIntrinsicWidth());
          nameLeft = AndroidUtilities.dp(11);
        }
      } else {
        dialog_id = user.id;
        if (!LocaleController.isRTL) {
          nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
        } else {
          nameLeft = AndroidUtilities.dp(11);
        }
        if (user.bot) {
          drawNameBot = true;
          if (!LocaleController.isRTL) {
            nameLockLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
            nameLeft =
                AndroidUtilities.dp(AndroidUtilities.leftBaseline + 4)
                    + botDrawable.getIntrinsicWidth();
          } else {
            nameLockLeft =
                getMeasuredWidth()
                    - AndroidUtilities.dp(AndroidUtilities.leftBaseline + 2)
                    - botDrawable.getIntrinsicWidth();
            nameLeft = AndroidUtilities.dp(11);
          }
          nameLockTop = AndroidUtilities.dp(16.5f);
        } else {
          nameLockTop = AndroidUtilities.dp(17);
        }
        drawCheck = user.verified;
      }
    }

    if (currentName != null) {
      nameString = currentName;
    } else {
      String nameString2 = "";
      if (chat != null) {
        nameString2 = chat.title;
      } else if (user != null) {
        nameString2 = UserObject.getUserName(user);
      }
      nameString = nameString2.replace('\n', ' ');
    }
    if (nameString.length() == 0) {
      if (user != null && user.phone != null && user.phone.length() != 0) {
        nameString = PhoneFormat.getInstance().format("+" + user.phone);
      } else {
        nameString = LocaleController.getString("HiddenName", R.string.HiddenName);
      }
    }
    if (encryptedChat != null) {
      currentNamePaint = nameEncryptedPaint;
    } else {
      currentNamePaint = namePaint;
    }

    int onlineWidth;
    int nameWidth;
    if (!LocaleController.isRTL) {
      onlineWidth = nameWidth = getMeasuredWidth() - nameLeft - AndroidUtilities.dp(14);
    } else {
      onlineWidth =
          nameWidth =
              getMeasuredWidth() - nameLeft - AndroidUtilities.dp(AndroidUtilities.leftBaseline);
    }
    if (drawNameLock) {
      nameWidth -= AndroidUtilities.dp(6) + lockDrawable.getIntrinsicWidth();
    } else if (drawNameBroadcast) {
      nameWidth -= AndroidUtilities.dp(6) + broadcastDrawable.getIntrinsicWidth();
    } else if (drawNameGroup) {
      nameWidth -= AndroidUtilities.dp(6) + groupDrawable.getIntrinsicWidth();
    } else if (drawNameBot) {
      nameWidth -= AndroidUtilities.dp(6) + botDrawable.getIntrinsicWidth();
    }

    if (drawCount) {
      TLRPC.TL_dialog dialog = MessagesController.getInstance().dialogs_dict.get(dialog_id);
      if (dialog != null && dialog.unread_count != 0) {
        lastUnreadCount = dialog.unread_count;
        String countString = String.format("%d", dialog.unread_count);
        countWidth =
            Math.max(AndroidUtilities.dp(12), (int) Math.ceil(countPaint.measureText(countString)));
        countLayout =
            new StaticLayout(
                countString,
                countPaint,
                countWidth,
                Layout.Alignment.ALIGN_CENTER,
                1.0f,
                0.0f,
                false);
        int w = countWidth + AndroidUtilities.dp(18);
        nameWidth -= w;
        if (!LocaleController.isRTL) {
          countLeft = getMeasuredWidth() - countWidth - AndroidUtilities.dp(19);
        } else {
          countLeft = AndroidUtilities.dp(19);
          nameLeft += w;
        }
      } else {
        lastUnreadCount = 0;
        countLayout = null;
      }
    } else {
      lastUnreadCount = 0;
      countLayout = null;
    }

    CharSequence nameStringFinal =
        TextUtils.ellipsize(
            nameString,
            currentNamePaint,
            nameWidth - AndroidUtilities.dp(12),
            TextUtils.TruncateAt.END);
    nameLayout =
        new StaticLayout(
            nameStringFinal,
            currentNamePaint,
            nameWidth,
            Layout.Alignment.ALIGN_NORMAL,
            1.0f,
            0.0f,
            false);

    if (chat == null || subLabel != null) {
      if (!LocaleController.isRTL) {
        onlineLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
      } else {
        onlineLeft = AndroidUtilities.dp(11);
      }

      CharSequence onlineString = "";
      TextPaint currentOnlinePaint = offlinePaint;

      if (subLabel != null) {
        onlineString = subLabel;
      } else if (user != null) {
        if (user.bot) {
          onlineString = LocaleController.getString("Bot", R.string.Bot);
        } else {
          onlineString = LocaleController.formatUserStatus(user);
          if (user != null
              && (user.id == UserConfig.getClientUserId()
                  || user.status != null
                      && user.status.expires > ConnectionsManager.getInstance().getCurrentTime())) {
            currentOnlinePaint = onlinePaint;
            onlineString = LocaleController.getString("Online", R.string.Online);
          }
        }
      }

      CharSequence onlineStringFinal =
          TextUtils.ellipsize(
              onlineString,
              currentOnlinePaint,
              onlineWidth - AndroidUtilities.dp(12),
              TextUtils.TruncateAt.END);
      onlineLayout =
          new StaticLayout(
              onlineStringFinal,
              currentOnlinePaint,
              onlineWidth,
              Layout.Alignment.ALIGN_NORMAL,
              1.0f,
              0.0f,
              false);
      nameTop = AndroidUtilities.dp(13);
      if (subLabel != null && chat != null) {
        nameLockTop -= AndroidUtilities.dp(12);
      }
    } else {
      onlineLayout = null;
      nameTop = AndroidUtilities.dp(25);
    }

    int avatarLeft;
    if (!LocaleController.isRTL) {
      avatarLeft = AndroidUtilities.dp(AndroidUtilities.isTablet() ? 13 : 9);
    } else {
      avatarLeft = getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.isTablet() ? 65 : 61);
    }

    avatarImage.setImageCoords(
        avatarLeft, AndroidUtilities.dp(10), AndroidUtilities.dp(52), AndroidUtilities.dp(52));

    double widthpx;
    float left;
    if (LocaleController.isRTL) {
      if (nameLayout.getLineCount() > 0) {
        left = nameLayout.getLineLeft(0);
        if (left == 0) {
          widthpx = Math.ceil(nameLayout.getLineWidth(0));
          if (widthpx < nameWidth) {
            nameLeft += (nameWidth - widthpx);
          }
        }
      }
      if (onlineLayout != null && onlineLayout.getLineCount() > 0) {
        left = onlineLayout.getLineLeft(0);
        if (left == 0) {
          widthpx = Math.ceil(onlineLayout.getLineWidth(0));
          if (widthpx < onlineWidth) {
            onlineLeft += (onlineWidth - widthpx);
          }
        }
      }
    } else {
      if (nameLayout.getLineCount() > 0) {
        left = nameLayout.getLineRight(0);
        if (left == nameWidth) {
          widthpx = Math.ceil(nameLayout.getLineWidth(0));
          if (widthpx < nameWidth) {
            nameLeft -= (nameWidth - widthpx);
          }
        }
      }
      if (onlineLayout != null && onlineLayout.getLineCount() > 0) {
        left = onlineLayout.getLineRight(0);
        if (left == onlineWidth) {
          widthpx = Math.ceil(onlineLayout.getLineWidth(0));
          if (widthpx < onlineWidth) {
            onlineLeft -= (onlineWidth - widthpx);
          }
        }
      }
    }
  }
Пример #9
0
    public void build(MessageWireframe wireframe, int desiredWidth, StelsApplication application) {

      Logger.d(TAG, "Build layout start");

      checkResources(application);

      senderPaint = initTextPaint();
      senderPaint.setTypeface(FontController.loadTypeface(application, "regular"));
      senderPaint.setTextSize(bodyPaint.getTextSize());
      senderPaint.setColor(0xff000000);

      forwardingPaint = initTextPaint();
      forwardingPaint.setTypeface(FontController.loadTypeface(application, "light"));
      forwardingPaint.setTextSize(bodyPaint.getTextSize());
      forwardingPaint.setColor(0xff000000);

      this.layoutDesiredWidth = desiredWidth;
      this.isOut = wireframe.message.isOut();
      this.showState = isOut;
      this.isGroup = wireframe.message.getPeerType() == PeerType.PEER_CHAT && !isOut;
      if (isGroup) {
        User user = wireframe.senderUser;
        this.senderName = user.getDisplayName();
        if (!wireframe.message.isForwarded()) {
          senderPaint.setColor(
              Placeholders.USER_PLACEHOLDERS_COLOR[
                  wireframe.message.getSenderId() % Placeholders.USER_PLACEHOLDERS_COLOR.length]);
          forwardingPaint.setColor(
              Placeholders.USER_PLACEHOLDERS_COLOR[
                  wireframe.message.getSenderId() % Placeholders.USER_PLACEHOLDERS_COLOR.length]);
        }
      }

      if (wireframe.message.isForwarded()) {
        isForwarded = true;
        this.forwarderName = wireframe.forwardUser.getDisplayName();
        if (isOut) {
          forwardingPaint.setColor(0xff739f53);
          senderPaint.setColor(0xff739f53);
        } else {
          forwardingPaint.setColor(0xff4884cf);
          senderPaint.setColor(0xff4884cf);
        }
      } else {
        isForwarded = false;
      }

      if (isGroup) {
        User user = application.getEngine().getUser(wireframe.message.getSenderId());
        this.senderName = user.getDisplayName();
      }
      if (wireframe.message.isForwarded()) {
        isForwarded = true;
        this.forwarderName = wireframe.forwardUser.getDisplayName();
      } else {
        isForwarded = false;
      }

      layoutDesiredWidth = desiredWidth;
      long start = SystemClock.uptimeMillis();

      this.spannable =
          application
              .getEmojiProcessor()
              .processEmojiCompatMutable(
                  wireframe.message.getMessage(), EmojiProcessor.CONFIGURATION_BUBBLES);

      // spannable = new SpannableString(wireframe.message.getMessage());
      Logger.d(TAG, "Emoji processed in " + (SystemClock.uptimeMillis() - start) + " ms");
      start = SystemClock.uptimeMillis();
      Linkify.addLinks(
          this.spannable, Linkify.WEB_URLS | Linkify.PHONE_NUMBERS | Linkify.EMAIL_ADDRESSES);
      fixLinks(spannable);
      Logger.d(TAG, "Added links in " + (SystemClock.uptimeMillis() - start) + " ms");
      start = SystemClock.uptimeMillis();
      layout =
          new StaticLayout(
              spannable, bodyPaint, desiredWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true);
      Logger.d(TAG, "Built base layout in " + (SystemClock.uptimeMillis() - start) + " ms");

      if (layout.getLineCount() < 20) {
        int layoutTextWidth = 0;

        for (int i = 0; i < layout.getLineCount(); i++) {
          layoutTextWidth = (int) Math.max(layout.getLineWidth(i), layoutTextWidth);
        }

        if (layoutTextWidth < layout.getWidth() - px(10)) {
          layout =
              new StaticLayout(
                  spannable,
                  bodyPaint,
                  layoutTextWidth + px(2),
                  Layout.Alignment.ALIGN_NORMAL,
                  1.0f,
                  0.0f,
                  true);
        }
      }

      layoutRealWidth = layout.getWidth();

      timeWidth = (int) clockOutPaint.measureText(wireframe.date) + px((showState ? 23 : 0) + 6);

      if (layout.getLineCount() == 1) {
        boolean isLastRtl = layout.getParagraphDirection(0) == Layout.DIR_RIGHT_TO_LEFT;
        if (!isLastRtl && desiredWidth - layoutRealWidth > timeWidth) {
          layoutRealWidth += timeWidth;
          layoutHeight = layout.getHeight() + px(3);
        } else if (isLastRtl && desiredWidth - layout.getWidth() > timeWidth) {
          layoutRealWidth = layout.getWidth() + timeWidth;
          layoutHeight = layout.getHeight() + px(3);
        } else {
          if (isLastRtl) {
            layoutRealWidth = layout.getWidth();
          }

          layoutHeight = layout.getHeight() + px(17);
        }
      } else {
        boolean isLastRtl =
            layout.getParagraphDirection(layout.getLineCount() - 1) == Layout.DIR_RIGHT_TO_LEFT;
        if (!isLastRtl
            && (desiredWidth - layout.getLineWidth(layout.getLineCount() - 1) > timeWidth)) {
          layoutRealWidth =
              (int)
                  Math.max(
                      layoutRealWidth, layout.getLineWidth(layout.getLineCount() - 1) + timeWidth);
          layoutHeight = layout.getHeight() + px(3);
        } else if (isLastRtl && (desiredWidth - layout.getWidth() > timeWidth)) {
          layoutRealWidth = (int) Math.max(layoutRealWidth, layout.getWidth() + timeWidth);
          layoutHeight = layout.getHeight() + px(3);
        } else {
          layoutHeight = layout.getHeight() + px(17);
        }
      }

      if (layoutRealWidth < timeWidth) {
        layoutRealWidth = timeWidth;
      }

      if (isForwarded) {
        layoutHeight += px(19) * 2;
        forwardOffset = (int) forwardingPaintBase.measureText("From ");
        layoutRealWidth =
            (int) Math.max(layoutRealWidth, forwardingPaintBase.measureText("Forwarded message"));
        forwarderNameMeasured =
            TextUtils.ellipsize(
                    forwarderName,
                    senderPaintBase,
                    desiredWidth - forwardOffset,
                    TextUtils.TruncateAt.END)
                .toString();
        layoutRealWidth =
            (int)
                Math.max(
                    layoutRealWidth,
                    forwardOffset + senderPaintBase.measureText(forwarderNameMeasured));
      }

      if (isGroup && !isOut && !isForwarded) {
        layoutHeight += px(19);
        senderNameMeasured =
            TextUtils.ellipsize(senderName, senderPaintBase, desiredWidth, TextUtils.TruncateAt.END)
                .toString();
        int width = (int) senderPaintBase.measureText(senderNameMeasured);
        layoutRealWidth = Math.max(layoutRealWidth, width);
      }

      Logger.d(TAG, "Build layout end");
    }
Пример #10
0
  /**
   * Resize the text size with specified width and height
   *
   * @param width
   * @param height
   */
  public void resizeText(int width, int height) {
    CharSequence text = getText();
    // Do not resize if the view does not have dimensions or there is no
    // text
    // or if mTextSize has not been initialized
    if (text == null || text.length() == 0 || height <= 0 || width <= 0 || mTextSize == 0) {
      return;
    }

    // Get the text view's paint object
    TextPaint textPaint = getPaint();

    // Store the current text size
    float oldTextSize = textPaint.getTextSize();

    // If there is a max text size set, use the lesser of that and the
    // default text size
    float targetTextSize = mMaxTextSize > 0 ? Math.min(mTextSize, mMaxTextSize) : mTextSize;

    // Get the required text height
    int textHeight = getTextHeight(text, textPaint, width, targetTextSize);
    int textWidth = getTextWidth(text, textPaint, width, targetTextSize);
    int lineHeight = getTextHeight(text, textPaint, width * 10, targetTextSize);

    // Until we either fit within our text view or we had reached our min
    // text size, incrementally try smaller sizes
    while (((textHeight > height) || (textWidth > width) || (textHeight > lineHeight))
        && targetTextSize > mMinTextSize) {
      targetTextSize = Math.max(targetTextSize - 2, mMinTextSize);
      textHeight = getTextHeight(text, textPaint, width, targetTextSize);
      textWidth = getTextWidth(text, textPaint, width, targetTextSize);
      lineHeight = getTextHeight(text, textPaint, width * 10, targetTextSize);
    }

    // If we had reached our minimum text size and still don't fit, append
    // an ellipsis
    if (mAddEllipsis && targetTextSize == mMinTextSize && textHeight > height) {
      // Draw using a static layout
      StaticLayout layout =
          new StaticLayout(
              text, textPaint, width, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, false);
      layout.draw(sTextResizeCanvas);
      int lastLine = layout.getLineForVertical(height) - 1;
      int start = layout.getLineStart(lastLine);
      int end = layout.getLineEnd(lastLine);
      float lineWidth = layout.getLineWidth(lastLine);
      float ellipseWidth = textPaint.measureText(mEllipsis);

      // Trim characters off until we have enough room to draw the
      // ellipsis
      while (width < lineWidth + ellipseWidth) {
        lineWidth = textPaint.measureText(text.subSequence(start, --end + 1).toString());
      }
      setText(text.subSequence(0, end) + mEllipsis);
    }

    // Some devices try to auto adjust line spacing, so force default line
    // spacing
    // and invalidate the layout as a side effect
    textPaint.setTextSize(targetTextSize);
    setLineSpacing(mSpacingAdd, mSpacingMult);

    // Notify the listener if registered
    if (mTextResizeListener != null) {
      mTextResizeListener.onTextResize(this, oldTextSize, targetTextSize);
    }

    // Reset force resize flag
    mNeedsResize = false;
  }
  private void build(int width) {

    positions.clear();
    width = width - getPaddingLeft() - getPaddingRight();

    if (width <= 0 || TextUtils.isEmpty(text)) {
      truncatedLayout = expandedLayout = null;
      return;
    }

    for (BubbleSpan span : spans) {
      span.resetWidth(width);
    }

    try {

      truncatedLayout =
          expandedLayout =
              new StaticLayout(
                  text, textPaint, width, Layout.Alignment.ALIGN_NORMAL, lineSpacing, 1, false);

      if (maxLines > 0 && truncatedLayout.getLineCount() > maxLines) {

        int lineEnd = truncatedLayout.getLineEnd(maxLines - 1);
        int offset = -1;
        StaticLayout sl =
            new StaticLayout(
                moreText, textPaint, width, Layout.Alignment.ALIGN_NORMAL, lineSpacing, 1, false);

        sl.getWidth();
        while (truncatedLayout.getLineCount() > maxLines && lineEnd > 0) {

          if (offset == -1
              && truncatedLayout.getLineWidth(maxLines - 1) + sl.getLineWidth(0) > width) {

            offset =
                truncatedLayout.getOffsetForHorizontal(maxLines - 1, width - sl.getLineWidth(0));

            lineEnd = offset;

          } else if (offset > 0) {
            lineEnd--;
          }

          SpannableStringBuilder textTruncated =
              new SpannableStringBuilder(text.subSequence(0, lineEnd));
          textTruncated.append(moreText);

          truncatedLayout =
              new StaticLayout(
                  textTruncated,
                  textPaint,
                  width,
                  Layout.Alignment.ALIGN_NORMAL,
                  lineSpacing,
                  1,
                  false);
        }
      }
    } catch (java.lang.ArrayIndexOutOfBoundsException e) {
      return;
    }

    if (truncated) {
      recomputeSpans((Spannable) truncatedLayout.getText());
    } else {
      recomputeSpans((Spannable) expandedLayout.getText());
    }

    for (BubbleSpan span : spans) {
      positions.put(span, span.rect(this));
    }
  }
Пример #12
0
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();

    boolean result = false;
    int side = AndroidUtilities.dp(48);
    if (textLayout != null) {
      if (event.getAction() == MotionEvent.ACTION_DOWN
          || pressedLink != null && event.getAction() == MotionEvent.ACTION_UP) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
          resetPressedLink();
          try {
            int x2 = (int) (x - textX);
            int y2 = (int) (y - textY);
            final int line = textLayout.getLineForVertical(y2);
            final int off = textLayout.getOffsetForHorizontal(line, x2);

            final float left = textLayout.getLineLeft(line);
            if (left <= x2 && left + textLayout.getLineWidth(line) >= x2) {
              Spannable buffer = (Spannable) textLayout.getText();
              ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
              if (link.length != 0) {
                resetPressedLink();
                pressedLink = link[0];
                result = true;
                try {
                  int start = buffer.getSpanStart(pressedLink);
                  urlPath.setCurrentLayout(textLayout, start);
                  textLayout.getSelectionPath(start, buffer.getSpanEnd(pressedLink), urlPath);
                } catch (Exception e) {
                  FileLog.e("tmessages", e);
                }
              } else {
                resetPressedLink();
              }
            } else {
              resetPressedLink();
            }
          } catch (Exception e) {
            resetPressedLink();
            FileLog.e("tmessages", e);
          }
        } else if (pressedLink != null) {
          try {
            if (pressedLink instanceof URLSpanNoUnderline) {
              String url = ((URLSpanNoUnderline) pressedLink).getURL();
              if (url.startsWith("@") || url.startsWith("#") || url.startsWith("/")) {
                if (delegate != null) {
                  delegate.didPressUrl(url);
                }
              }
            } else {
              pressedLink.onClick(this);
            }
          } catch (Exception e) {
            FileLog.e("tmessages", e);
          }
          resetPressedLink();
          result = true;
        }
      } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
        resetPressedLink();
      }
    }
    return result || super.onTouchEvent(event);
  }
    public void build(int width, int height) {
      CharSequence nameString = "";
      TextPaint currentNamePaint;

      drawNameBroadcast = false;
      drawNameLock = false;
      drawNameGroup = false;

      if (encryptedChat != null) {
        drawNameLock = true;
        if (!LocaleController.isRTL) {
          nameLockLeft = AndroidUtilities.dp(61 + (usePadding ? 11 : 0));
          nameLeft =
              AndroidUtilities.dp(65 + (usePadding ? 11 : 0)) + lockDrawable.getIntrinsicWidth();
        } else {
          nameLockLeft =
              width
                  - AndroidUtilities.dp(63 + (usePadding ? 11 : 0))
                  - lockDrawable.getIntrinsicWidth();
          nameLeft = usePadding ? AndroidUtilities.dp(11) : 0;
        }
        nameLockTop = AndroidUtilities.dp(15);
      } else {
        if (chat != null) {
          nameLockTop = AndroidUtilities.dp(26);
          if (chat.id < 0) {
            drawNameBroadcast = true;
          } else {
            drawNameGroup = true;
          }
          if (!LocaleController.isRTL) {
            nameLockLeft = AndroidUtilities.dp(61 + (usePadding ? 11 : 0));
            nameLeft =
                AndroidUtilities.dp(65 + (usePadding ? 11 : 0))
                    + (drawNameGroup
                        ? groupDrawable.getIntrinsicWidth()
                        : broadcastDrawable.getIntrinsicWidth());
          } else {
            nameLockLeft =
                width
                    - AndroidUtilities.dp(63 + (usePadding ? 11 : 0))
                    - (drawNameGroup
                        ? groupDrawable.getIntrinsicWidth()
                        : broadcastDrawable.getIntrinsicWidth());
            nameLeft = usePadding ? AndroidUtilities.dp(11) : 0;
          }
        } else {
          if (!LocaleController.isRTL) {
            nameLeft = AndroidUtilities.dp(61 + (usePadding ? 11 : 0));
          } else {
            nameLeft = usePadding ? AndroidUtilities.dp(11) : 0;
          }
        }
      }

      if (currentName != null) {
        nameString = currentName;
      } else {
        String nameString2 = "";
        if (chat != null) {
          nameString2 = chat.title;
        } else if (user != null) {
          nameString2 = ContactsController.formatName(user.first_name, user.last_name);
        }
        nameString = nameString2.replace("\n", " ");
      }
      if (nameString.length() == 0) {
        if (user != null && user.phone != null && user.phone.length() != 0) {
          nameString = PhoneFormat.getInstance().format("+" + user.phone);
        } else {
          nameString = LocaleController.getString("HiddenName", R.string.HiddenName);
        }
      }
      if (encryptedChat != null) {
        currentNamePaint = nameEncryptedPaint;
      } else {
        currentNamePaint = namePaint;
      }

      if (!LocaleController.isRTL) {
        onlineWidth = nameWidth = width - nameLeft - AndroidUtilities.dp(3 + (usePadding ? 11 : 0));
      } else {
        onlineWidth =
            nameWidth = width - nameLeft - AndroidUtilities.dp(61 + (usePadding ? 11 : 0));
      }
      if (drawNameLock) {
        nameWidth -= AndroidUtilities.dp(6) + lockDrawable.getIntrinsicWidth();
      } else if (drawNameBroadcast) {
        nameWidth -= AndroidUtilities.dp(6) + broadcastDrawable.getIntrinsicWidth();
      }

      CharSequence nameStringFinal =
          TextUtils.ellipsize(
              nameString,
              currentNamePaint,
              nameWidth - AndroidUtilities.dp(12),
              TextUtils.TruncateAt.END);
      nameLayout =
          new StaticLayout(
              nameStringFinal,
              currentNamePaint,
              nameWidth,
              Layout.Alignment.ALIGN_NORMAL,
              1.0f,
              0.0f,
              false);

      if (chat == null) {
        if (!LocaleController.isRTL) {
          onlineLeft = AndroidUtilities.dp(61 + (usePadding ? 11 : 0));
        } else {
          onlineLeft = usePadding ? AndroidUtilities.dp(11) : 0;
        }

        CharSequence onlineString = "";
        TextPaint currentOnlinePaint = offlinePaint;

        if (subLabel != null) {
          onlineString = subLabel;
        } else {
          onlineString = LocaleController.formatUserStatus(user);
          if (user != null
              && (user.id == UserConfig.getClientUserId()
                  || user.status != null
                      && user.status.expires > ConnectionsManager.getInstance().getCurrentTime())) {
            currentOnlinePaint = onlinePaint;
            onlineString = LocaleController.getString("Online", R.string.Online);
          }
        }

        CharSequence onlineStringFinal =
            TextUtils.ellipsize(
                onlineString,
                currentOnlinePaint,
                nameWidth - AndroidUtilities.dp(12),
                TextUtils.TruncateAt.END);
        onlineLayout =
            new StaticLayout(
                onlineStringFinal,
                currentOnlinePaint,
                nameWidth,
                Layout.Alignment.ALIGN_NORMAL,
                1.0f,
                0.0f,
                false);
        nameTop = AndroidUtilities.dp(12);
      } else {
        onlineLayout = null;
        nameTop = AndroidUtilities.dp(22);
      }

      if (!LocaleController.isRTL) {
        avatarLeft = usePadding ? AndroidUtilities.dp(11) : 0;
      } else {
        avatarLeft = width - AndroidUtilities.dp(50 + (usePadding ? 11 : 0));
      }
      avatarImage.setImageCoords(
          avatarLeft, avatarTop, AndroidUtilities.dp(50), AndroidUtilities.dp(50));

      double widthpx = 0;
      float left = 0;
      if (LocaleController.isRTL) {
        if (nameLayout.getLineCount() > 0) {
          left = nameLayout.getLineLeft(0);
          if (left == 0) {
            widthpx = Math.ceil(nameLayout.getLineWidth(0));
            if (widthpx < nameWidth) {
              nameLeft += (nameWidth - widthpx);
            }
          }
        }
        if (onlineLayout != null && onlineLayout.getLineCount() > 0) {
          left = onlineLayout.getLineLeft(0);
          if (left == 0) {
            widthpx = Math.ceil(onlineLayout.getLineWidth(0));
            if (widthpx < onlineWidth) {
              onlineLeft += (onlineWidth - widthpx);
            }
          }
        }
      } else {
        if (nameLayout.getLineCount() > 0) {
          left = nameLayout.getLineRight(0);
          if (left == nameWidth) {
            widthpx = Math.ceil(nameLayout.getLineWidth(0));
            if (widthpx < nameWidth) {
              nameLeft -= (nameWidth - widthpx);
            }
          }
        }
        if (onlineLayout != null && onlineLayout.getLineCount() > 0) {
          left = onlineLayout.getLineRight(0);
          if (left == onlineWidth) {
            widthpx = Math.ceil(onlineLayout.getLineWidth(0));
            if (widthpx < onlineWidth) {
              onlineLeft -= (onlineWidth - widthpx);
            }
          }
        }
      }
    }
Пример #14
0
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    float x = event.getX();
    float y = event.getY();

    boolean result = false;
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
      if (delegate != null) {
        if (currentMessageObject.type == 11 && imageReceiver.isInsideImage(x, y)) {
          imagePressed = true;
          result = true;
        }
        if (result) {
          startCheckLongPress();
        }
      }
    } else {
      if (event.getAction() != MotionEvent.ACTION_MOVE) {
        cancelCheckLongPress();
      }
      if (imagePressed) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
          imagePressed = false;
          if (delegate != null) {
            delegate.didClickedImage(this);
            playSoundEffect(SoundEffectConstants.CLICK);
          }
        } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
          imagePressed = false;
        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
          if (!imageReceiver.isInsideImage(x, y)) {
            imagePressed = false;
          }
        }
      }
    }
    if (!result) {
      if (event.getAction() == MotionEvent.ACTION_DOWN
          || pressedLink != null && event.getAction() == MotionEvent.ACTION_UP) {
        if (x >= textX && y >= textY && x <= textX + textWidth && y <= textY + textHeight) {
          y -= textY;
          x -= textXLeft;

          final int line = textLayout.getLineForVertical((int) y);
          final int off = textLayout.getOffsetForHorizontal(line, x);
          final float left = textLayout.getLineLeft(line);
          if (left <= x
              && left + textLayout.getLineWidth(line) >= x
              && currentMessageObject.messageText instanceof Spannable) {
            Spannable buffer = (Spannable) currentMessageObject.messageText;
            URLSpan[] link = buffer.getSpans(off, off, URLSpan.class);

            if (link.length != 0) {
              if (event.getAction() == MotionEvent.ACTION_DOWN) {
                pressedLink = link[0];
                result = true;
              } else {
                if (link[0] == pressedLink) {
                  if (delegate != null) {
                    delegate.needOpenUserProfile(Integer.parseInt(link[0].getURL()));
                  }
                  result = true;
                }
              }
            } else {
              pressedLink = null;
            }
          } else {
            pressedLink = null;
          }
        } else {
          pressedLink = null;
        }
      }
    }

    if (!result) {
      result = super.onTouchEvent(event);
    }

    return result;
  }
Пример #15
0
    public void build(int width, int height) {
      CharSequence nameString = "";
      TextPaint currentNamePaint;

      if (encryptedChat != null) {
        drawNameLock = true;
        if (!LocaleController.isRTL) {
          nameLockLeft = Utilities.dp(61 + (usePadding ? 11 : 0));
          nameLeft = Utilities.dp(65 + (usePadding ? 11 : 0)) + lockDrawable.getIntrinsicWidth();
        } else {
          nameLockLeft =
              width - Utilities.dp(63 + (usePadding ? 11 : 0)) - lockDrawable.getIntrinsicWidth();
          nameLeft = usePadding ? Utilities.dp(11) : 0;
        }
      } else {
        drawNameLock = false;
        if (!LocaleController.isRTL) {
          nameLeft = Utilities.dp(61 + (usePadding ? 11 : 0));
        } else {
          nameLeft = usePadding ? Utilities.dp(11) : 0;
        }
      }

      if (currentName != null) {
        nameString = currentName;
      } else {
        String nameString2 = "";
        if (chat != null) {
          nameString2 = chat.title;
        } else if (user != null) {
          nameString2 = Utilities.formatName(user.first_name, user.last_name);
        }
        nameString = nameString2.replace("\n", " ");
      }
      if (nameString.length() == 0) {
        if (user.phone != null && user.phone.length() != 0) {
          nameString = PhoneFormat.getInstance().format("+" + user.phone);
        } else {
          nameString = LocaleController.getString("HiddenName", R.string.HiddenName);
        }
      }
      if (encryptedChat != null) {
        currentNamePaint = nameEncryptedPaint;
      } else {
        currentNamePaint = namePaint;
      }

      if (!LocaleController.isRTL) {
        onlineWidth = nameWidth = width - nameLeft - Utilities.dp(3 + (usePadding ? 11 : 0));
      } else {
        onlineWidth = nameWidth = width - nameLeft - Utilities.dp(61 + (usePadding ? 11 : 0));
      }
      if (drawNameLock) {
        nameWidth -= Utilities.dp(6) + lockDrawable.getIntrinsicWidth();
      }

      CharSequence nameStringFinal =
          TextUtils.ellipsize(
              nameString, currentNamePaint, nameWidth - Utilities.dp(12), TextUtils.TruncateAt.END);
      nameLayout =
          new StaticLayout(
              nameStringFinal,
              currentNamePaint,
              nameWidth,
              Layout.Alignment.ALIGN_NORMAL,
              1.0f,
              0.0f,
              false);

      if (chat == null) {
        if (!LocaleController.isRTL) {
          onlineLeft = Utilities.dp(61 + (usePadding ? 11 : 0));
        } else {
          onlineLeft = usePadding ? Utilities.dp(11) : 0;
        }

        String onlineString = "";
        TextPaint currentOnlinePaint = offlinePaint;

        if (subLabel != null) {
          onlineString = subLabel;
        } else {
          if (user != null) {
            if (user.status == null) {
              onlineString = getResources().getString(R.string.Offline);
            } else {
              int currentTime = ConnectionsManager.getInstance().getCurrentTime();
              if (user.id == UserConfig.clientUserId || user.status.expires > currentTime) {
                currentOnlinePaint = onlinePaint;
                onlineString = getResources().getString(R.string.Online);
              } else {
                if (user.status.expires <= 10000) {
                  onlineString = getResources().getString(R.string.Invisible);
                } else {
                  onlineString = LocaleController.formatDateOnline(user.status.expires);
                }
              }
            }
          }
        }

        CharSequence onlineStringFinal =
            TextUtils.ellipsize(
                onlineString,
                currentOnlinePaint,
                nameWidth - Utilities.dp(12),
                TextUtils.TruncateAt.END);
        onlineLayout =
            new StaticLayout(
                onlineStringFinal,
                currentOnlinePaint,
                nameWidth,
                Layout.Alignment.ALIGN_NORMAL,
                1.0f,
                0.0f,
                false);
        nameTop = Utilities.dp(12);
      } else {
        onlineLayout = null;
        nameTop = Utilities.dp(22);
      }

      if (!LocaleController.isRTL) {
        avatarLeft = usePadding ? Utilities.dp(11) : 0;
      } else {
        avatarLeft = width - Utilities.dp(50 + (usePadding ? 11 : 0));
      }
      avatarImage.imageX = avatarLeft;
      avatarImage.imageY = avatarTop;
      avatarImage.imageW = Utilities.dp(50);
      avatarImage.imageH = Utilities.dp(50);

      double widthpx = 0;
      float left = 0;
      if (LocaleController.isRTL) {
        if (nameLayout.getLineCount() > 0) {
          left = nameLayout.getLineLeft(0);
          if (left == 0) {
            widthpx = Math.ceil(nameLayout.getLineWidth(0));
            if (widthpx < nameWidth) {
              nameLeft += (nameWidth - widthpx);
            }
          }
        }
        if (onlineLayout != null && onlineLayout.getLineCount() > 0) {
          left = onlineLayout.getLineLeft(0);
          if (left == 0) {
            widthpx = Math.ceil(onlineLayout.getLineWidth(0));
            if (widthpx < onlineWidth) {
              onlineLeft += (onlineWidth - widthpx);
            }
          }
        }
      } else {
        if (nameLayout.getLineCount() > 0) {
          left = nameLayout.getLineRight(0);
          if (left == nameWidth) {
            widthpx = Math.ceil(nameLayout.getLineWidth(0));
            if (widthpx < nameWidth) {
              nameLeft -= (nameWidth - widthpx);
            }
          }
        }
        if (onlineLayout != null && onlineLayout.getLineCount() > 0) {
          left = onlineLayout.getLineRight(0);
          if (left == onlineWidth) {
            widthpx = Math.ceil(onlineLayout.getLineWidth(0));
            if (widthpx < onlineWidth) {
              onlineLeft -= (onlineWidth - widthpx);
            }
          }
        }
      }
    }
Пример #16
0
  /**
   * Resize the text size with specified width and height
   *
   * @param width
   * @param height
   */
  public void resizeText(int width, int height) {
    CharSequence text = getText();
    // Do not resize if the view does not have dimensions or there is no text
    if (text == null || text.length() == 0 || height <= 0 || width <= 0 || mTextSize == 0) {
      return;
    }

    // Get the text view's paint object
    TextPaint textPaint = getPaint();

    // Store the current text size
    float oldTextSize = textPaint.getTextSize();
    // If there is a max text size set, use the lesser of that and the default text size
    float targetTextSize = mMaxTextSize > 0 ? Math.min(mTextSize, mMaxTextSize) : mTextSize;

    // Get the required text height
    int textHeight = getTextHeight(text, textPaint, width, targetTextSize);

    // Until we either fit within our text view or we had reached our min text size, incrementally
    // try smaller sizes
    while (textHeight > height && targetTextSize > mMinTextSize) {
      targetTextSize = Math.max(targetTextSize - 2, mMinTextSize);
      textHeight = getTextHeight(text, textPaint, width, targetTextSize);
    }

    // If we had reached our minimum text size and still don't fit, append an ellipsis
    if (mAddEllipsis && targetTextSize == mMinTextSize && textHeight > height) {
      // Draw using a static layout
      StaticLayout layout =
          new StaticLayout(
              text, textPaint, width, Alignment.ALIGN_NORMAL, mSpacingMult, mSpacingAdd, false);
      // Check that we have a least one line of rendered text
      if (layout.getLineCount() > 0) {
        // Since the line at the specific vertical position would be cut off,
        // we must trim up to the previous line
        int lastLine = layout.getLineForVertical(height) - 1;
        // If the text would not even fit on a single line, clear it
        if (lastLine < 0) {
          setText("");
        }
        // Otherwise, trim to the previous line and add an ellipsis
        else {
          int start = layout.getLineStart(lastLine);
          int end = layout.getLineEnd(lastLine);
          float lineWidth = layout.getLineWidth(lastLine);
          float ellipseWidth = textPaint.measureText(mEllipsis);

          // Trim characters off until we have enough room to draw the ellipsis
          while (width < lineWidth + ellipseWidth) {
            lineWidth = textPaint.measureText(text.subSequence(start, --end + 1).toString());
          }
          setText(text.subSequence(0, end) + mEllipsis);
        }
      }
    }

    // Some devices try to auto adjust line spacing, so force default line spacing
    // and invalidate the layout as a side effect
    textPaint.setTextSize(targetTextSize);
    setLineSpacing(mSpacingAdd, mSpacingMult);

    // Notify the listener if registered
    if (mTextResizeListener != null) {
      mTextResizeListener.onTextResize(this, oldTextSize, targetTextSize);
    }

    // Reset force resize flag
    mNeedsResize = false;
  }
Пример #17
0
  @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);
    }
  }