Skip to content

Commit

Permalink
fix(md-3822): image sizing & column ordering (#136)
Browse files Browse the repository at this point in the history
* fix: image sizing & column ordering

* fix: always fit

* fix: selections

* fix: cleanup
  • Loading branch information
gruskal authored and enell committed Feb 9, 2023
1 parent 3f907e9 commit 0ea59d8
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.view.GestureDetector;
import android.view.MenuItem;
Expand All @@ -19,7 +20,7 @@
import android.widget.RelativeLayout;

@SuppressLint("ViewConstructor")
public class CellView extends LinearLayout implements SelectionsObserver {
public class CellView extends RelativeLayout implements SelectionsObserver {
Content content = null;
DataRow row;
DataColumn column;
Expand All @@ -31,21 +32,27 @@ public class CellView extends LinearLayout implements SelectionsObserver {
int padding = (int)PixelUtils.dpToPx(16);
static int PADDING_X_2 = (int)PixelUtils.dpToPx(32);

@SuppressLint("ClickableViewAccessibility")
CellView(Context context, String type, SelectionsEngine selectionsEngine, TableView tableView, boolean isInFirstColumnRecyclerView, DataColumn dataColumn) {
super(context);
this.tableView = tableView;
this.selectionsEngine = selectionsEngine;
this.isInFirstColumnRecyclerView = isInFirstColumnRecyclerView;
this.dragBoxEventHandler = tableView.dragBoxEventHandler;

RelativeLayout wrapper = null;
RelativeLayout.LayoutParams wrapperLayout = null;
switch (type) {
case "text":
ClickableTextView textView = new ClickableTextView(context, selectionsEngine, tableView, this, dataColumn);
textView.setPadding(padding, 0, padding, 0);
content = textView;
break;
case "image":
wrapper = new RelativeLayout(context);
wrapperLayout = new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
content = new ClickableImageView(context, selectionsEngine, tableView, this);
wrapper.addView((View) content);
break;
case "miniChart":
content = new MiniChartView(context);
Expand Down Expand Up @@ -75,20 +82,29 @@ public class CellView extends LinearLayout implements SelectionsObserver {
contextMenu.add(0, 0, 0, copyString).setOnMenuItemClickListener(handleMenuItemClick);
contextMenu.add(0, 1, 1, expandString).setOnMenuItemClickListener(handleMenuItemClick);
};
View contentView = (View) content;
contentView.setOnCreateContextMenuListener(onCreateContextMenuListener);
this.addView(contentView);

if(type.equals("image")) {
wrapper.setOnCreateContextMenuListener(onCreateContextMenuListener);
this.addView(wrapper, wrapperLayout);
} else {
View contentView = (View) content;
contentView.setOnCreateContextMenuListener(onCreateContextMenuListener);
this.addView(contentView);
}
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
gestureDetector.onTouchEvent(ev);
return super.onInterceptTouchEvent(ev);
}

public void handleDragBoxDrag(Rect dragBoxBounds, int columnId) {
DataCell cell = content.getCell();
if(cell == null || columnId != cell.colIdx) {
if(cell == null || columnId != cell.rawColIdx) {
return;
}
Rect cellBounds = getBounds();
if(cellBounds == null) {
return;
}
boolean hasIntersect = dragBoxBounds.intersect(cellBounds);
if(!this.content.isSelected() && hasIntersect) {
selectCell();
Expand Down Expand Up @@ -143,7 +159,7 @@ public void handleSingleTap() {
if (cell.isDim) {
Rect bounds = getBounds();
if(!content.isSelected()) {
tableView.showDragBox(bounds, cell.colIdx);
tableView.showDragBox(bounds, cell.rawColIdx);
} else {
tableView.hideDragBoxes();
}
Expand Down Expand Up @@ -173,6 +189,18 @@ public void onRecycled() {
}
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
LinearLayout.LayoutParams layout = (LinearLayout.LayoutParams) getLayoutParams();
if(column == null) {
return;
}
layout.height = TableTheme.rowHeightFactor;
layout.width = column.width;
setLayoutParams(layout);
}

class SingleTapListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.SpannableString;
import android.text.method.MovementMethod;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
Expand All @@ -22,10 +27,10 @@ public class ClickableImageView extends androidx.appcompat.widget.AppCompatImage
boolean selected = false;
String scaleType = null;
final SelectionsEngine selectionsEngine;
GestureDetector gestureDetector;
final TableView tableView;
final CellView cellView;
Animation fadeIn;
GestureDetector gestureDetector;

ClickableImageView(Context context, SelectionsEngine selectionsEngine, TableView tableView, CellView cellView) {
super(context);
Expand All @@ -35,77 +40,61 @@ public class ClickableImageView extends androidx.appcompat.widget.AppCompatImage
fadeIn = AnimationUtils.loadAnimation(context, R.anim.catalyst_fade_in);
}

@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent e) {
gestureDetector.onTouchEvent(e);
return true;
}

private void alwaysFit() {
ViewGroup parent = (ViewGroup) cellView.getParent();
ViewGroup.LayoutParams layout = parent.getLayoutParams();
layout.height = tableView.rowHeight;
layout.width = tableView.rowHeight + parent.getPaddingLeft() + parent.getPaddingRight();
parent.setLayoutParams(layout);
this.setScaleType(ScaleType.FIT_CENTER);
RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(tableView.rowHeight, tableView.rowHeight);
this.setLayoutParams(layout);

this.setScaleType(ScaleType.FIT_XY);

scaleType = "alwaysFit";
}

private void stretchToFit(DataColumn column) {
ViewGroup parent = (ViewGroup) cellView.getParent();
ViewGroup.LayoutParams layout = parent.getLayoutParams();
layout.height = tableView.rowHeight;
layout.width = column.width;
parent.setLayoutParams(layout);
RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(tableView.rowHeight, column.width);
setLayoutParams(layout);

this.setScaleType(ScaleType.FIT_XY);
scaleType = "stretchToFit";

scaleType = "stretchToFit";
}

private void fitToHeight(Bitmap image) {
float height = image.getHeight();
float width = image.getWidth();
float aspectRatioMultiplier = width/height;

ViewGroup parent = (ViewGroup) cellView.getParent();
ViewGroup.LayoutParams layout = parent.getLayoutParams();
layout.height = tableView.rowHeight;
layout.width = Math.round(tableView.rowHeight * aspectRatioMultiplier) + parent.getPaddingLeft() + parent.getPaddingRight();
parent.setLayoutParams(layout);
RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(Math.round(tableView.rowHeight * aspectRatioMultiplier), tableView.rowHeight);
setLayoutParams(layout);

this.setScaleType(ScaleType.FIT_XY);
scaleType = "fitToHeight";

scaleType = "fitToHeight";
}

private void fitToWidth(DataColumn column, Bitmap image) {
float height = image.getHeight();
float width = image.getWidth();
float aspectRatioMultiplier = height/width;

ViewGroup parent = (ViewGroup) cellView.getParent();
RelativeLayout.LayoutParams layout = (RelativeLayout.LayoutParams) parent.getLayoutParams();
layout.width = (int)column.width;
layout.height = Math.round(column.width * aspectRatioMultiplier);
parent.setLayoutParams(layout);

ViewGroup grandparent = (ViewGroup) parent.getParent();
ViewGroup.LayoutParams grandparentLayout = grandparent.getLayoutParams();
grandparentLayout.width = column.width;
grandparentLayout.height = Math.round(column.width * aspectRatioMultiplier);
grandparent.setLayoutParams(grandparentLayout);
RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
setLayoutParams(layout);

RelativeLayout parent = (RelativeLayout) getParent();
if(parent == null) {
return;
}
RelativeLayout.LayoutParams wrapperLayout = (RelativeLayout.LayoutParams) parent.getLayoutParams();
wrapperLayout.width = column.width;
wrapperLayout.height = Math.round(column.width * aspectRatioMultiplier);
parent.setLayoutParams(wrapperLayout);

this.setScaleType(ScaleType.FIT_XY);

parent.setMinimumWidth((int)column.width);
parent.setMinimumHeight(Math.round(column.width * aspectRatioMultiplier));
scaleType = "fitToWidth";
}

public void setSizing(DataColumn column, Bitmap image) {
switch (column.representation.imageSize) {
case "alwaysFit":
alwaysFit();
break;
case "fill":
stretchToFit(column);
break;
Expand All @@ -115,27 +104,28 @@ public void setSizing(DataColumn column, Bitmap image) {
case "fitWidth":
fitToWidth(column, image);
break;
default:
case "alwaysFit":
alwaysFit();
break;
}
}

public void setAlignment(DataColumn column) {
ViewGroup container = (ViewGroup) cellView.getParent();
LinearLayout wrapper = (LinearLayout) container.getParent();
RelativeLayout wrapper = (RelativeLayout) getParent();
setTranslationY(0);

if(wrapper == null) {
return;
}

switch (column.representation.imagePosition) {
case "topCenter":
wrapper.setGravity(Gravity.LEFT);
break;
case "bottomCenter":
wrapper.setGravity(Gravity.RIGHT);
break;
case "centerCenter":
wrapper.setGravity(Gravity.CENTER);
if (scaleType.equals("fitToWidth")) {
setTranslationY(tableView.rowHeight / 2 - container.getMinimumHeight() / 2);
}
break;
case "centerLeft":
if (scaleType.equals("fitToWidth")) {
wrapper.setGravity(Gravity.TOP);
Expand All @@ -146,18 +136,24 @@ public void setAlignment(DataColumn column) {
case "centerRight":
if (scaleType.equals("fitToWidth")) {
wrapper.setGravity(Gravity.BOTTOM);
setTranslationY(tableView.rowHeight - container.getMinimumHeight());
setTranslationY(tableView.rowHeight - cellView.getMinimumHeight());
break;
}
wrapper.setGravity(Gravity.CENTER);
break;
default:
case "centerCenter":
if (scaleType.equals("fitToWidth")) {
setTranslationY((float) (tableView.rowHeight / 2 - cellView.getMinimumHeight() / 2));
}
wrapper.setGravity(Gravity.CENTER);
break;
}
}

public void updateBackgroundColor(boolean shouldAnimate) {
int color = selected ? TableTheme.selectedBackground : Color.TRANSPARENT;
ViewGroup wrapper = (ViewGroup) cellView.getParent().getParent();
wrapper.setBackgroundColor(color);
cellView.setBackgroundColor(color);
if(shouldAnimate) {
startAnimation(fadeIn);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ public boolean onTouchEvent(MotionEvent e) {
return movementMethod.onTouchEvent(this, new SpannableString(this.getText()), e);
}
}
gestureDetector.onTouchEvent(e);
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ private int resizeColumnByAverage(DataColumn column, List<DataRow> rows) {
int averageTextSize = runningTotal / rows.size();
// Create a string with max text
String tempString = new String(new char[averageTextSize]).replace("\0", "X");
if(column.representation.type.equals("image")) {
return (int) (DataProvider.minWidth * 1.5f);
}
float width = paint.measureText(tempString, 0, tempString.length());
width = Math.max(DataProvider.minWidth * 1.5f, PixelUtils.dpToPx(width));
// cast later since this is the equiv of a floor.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,11 @@ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams((int)width, tableView.rowHeight);

if (column.representation.type.equals("image")) {
RelativeLayout wrapper = new RelativeLayout(parent.getContext());
CellView cellView = new CellView(parent.getContext(), "image", this.selectionsEngine, this.tableView, recyclerView.firstColumnOnly, column);
RelativeLayout.LayoutParams cellLayoutParams = new RelativeLayout.LayoutParams(-1,-1);
wrapper.addView(cellView, cellLayoutParams);
rowView.addView(wrapper, layoutParams);
LinearLayout.LayoutParams cellLayoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT);

rowView.addView(cellView, cellLayoutParams);

} else if(column.representation.type.equals("miniChart")) {
CellView cellView = new CellView(parent.getContext(), "miniChart", this.selectionsEngine, this.tableView, recyclerView.firstColumnOnly, column);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,14 @@ public void setData(DataRow dataRow, int rowHeight, CellContentStyle cellContent
DataColumn column = dataProvider.dataColumns.get(columnIndex);

if(column.representation.type.equals("image")) {
ViewGroup wrapper = (ViewGroup) row.getChildAt(columnIndex);
CellView cellView = (CellView) wrapper.getChildAt(0);
ViewGroup.LayoutParams layout = cellView.getLayoutParams();
CellView cellView = (CellView) row.getChildAt(columnIndex);
LinearLayout.LayoutParams layout = new LinearLayout.LayoutParams(column.width, rowHeight);
layout.height = rowHeight;
layout.width = column.width;
cellView.setLayoutParams(layout);
cellView.setData(cell, dataRow, column);

Bitmap imageBitmap = dataProvider.getImageData(cell.imageUrl);
Bitmap imageBitmap = DataProvider.getImageData(cell.imageUrl);
if(imageBitmap == null) {
continue;
}
Expand All @@ -69,7 +68,7 @@ public void setData(DataRow dataRow, int rowHeight, CellContentStyle cellContent
CellView cellView = (CellView) row.getChildAt(columnIndex);
ClickableTextView textView = (ClickableTextView) cellView.content;

LinearLayout.LayoutParams textViewLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
RelativeLayout.LayoutParams textViewLayoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
textView.setLayoutParams(textViewLayoutParams);

LinearLayout.LayoutParams cellViewLayoutParams = new LinearLayout.LayoutParams(column.width, rowHeight);
Expand Down Expand Up @@ -108,10 +107,9 @@ public void updateColumnRepresentation() {
DataColumn column = dataProvider.dataColumns.get(i);

if(column.representation.type.equals("image")) {
RelativeLayout wrapper = (RelativeLayout) row.getChildAt(i);
CellView cellView = (CellView) wrapper.getChildAt(0);
CellView cellView = (CellView) row.getChildAt(i);
ClickableImageView imageView = (ClickableImageView) cellView.content;
Bitmap imageBitmap = dataProvider.getImageData(column.representation.imageUrl);
Bitmap imageBitmap = DataProvider.getImageData(column.representation.imageUrl);
if(imageBitmap == null) {
continue;
}
Expand Down

0 comments on commit 0ea59d8

Please sign in to comment.