mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-28 21:28:55 +00:00
Bug 704784 - Tweak scrollbars to look nicer [r=pcwalton]
Scrollbars now have rounded endcaps, are a little smaller, and there is a 1-pixel gap between the bar and the edge of the viewport. Just generally making them look nicer.
This commit is contained in:
parent
891ca8a49d
commit
d8bfd1e721
@ -167,6 +167,20 @@ public abstract class Layer {
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns the power of two that is greater than or equal to value */
|
||||
protected static int nextPowerOfTwo(int value) {
|
||||
// code taken from http://acius2.blogspot.com/2007/11/calculating-next-power-of-2.html
|
||||
if (0 == value--) {
|
||||
return 1;
|
||||
}
|
||||
value = (value >> 1) | value;
|
||||
value = (value >> 2) | value;
|
||||
value = (value >> 4) | value;
|
||||
value = (value >> 8) | value;
|
||||
value = (value >> 16) | value;
|
||||
return value + 1;
|
||||
}
|
||||
|
||||
public static class RenderContext {
|
||||
public final RectF viewport;
|
||||
public final FloatSize pageSize;
|
||||
|
@ -37,7 +37,13 @@
|
||||
|
||||
package org.mozilla.gecko.gfx;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.opengl.GLES11;
|
||||
import android.opengl.GLES11Ext;
|
||||
@ -49,7 +55,16 @@ import javax.microedition.khronos.opengles.GL10;
|
||||
* Draws a small rect. This is scaled to become a scrollbar.
|
||||
*/
|
||||
public class ScrollbarLayer extends TileLayer {
|
||||
private static final int BAR_SIZE = 8; // has to be power of 2
|
||||
private static final int PADDING = 1; // gap between scrollbar and edge of viewport
|
||||
private static final int BAR_SIZE = 6;
|
||||
private static final int CAP_RADIUS = (BAR_SIZE / 2);
|
||||
private static final int SCROLLBAR_COLOR = Color.argb(127, 0, 0, 0);
|
||||
|
||||
private static final int[] CROPRECT_MIDPIXEL = new int[] { CAP_RADIUS, CAP_RADIUS, 1, 1 };
|
||||
private static final int[] CROPRECT_TOPCAP = new int[] { 0, CAP_RADIUS, BAR_SIZE, -CAP_RADIUS };
|
||||
private static final int[] CROPRECT_BOTTOMCAP = new int[] { 0, BAR_SIZE, BAR_SIZE, -CAP_RADIUS };
|
||||
private static final int[] CROPRECT_LEFTCAP = new int[] { 0, BAR_SIZE, CAP_RADIUS, -BAR_SIZE };
|
||||
private static final int[] CROPRECT_RIGHTCAP = new int[] { CAP_RADIUS, BAR_SIZE, CAP_RADIUS, -BAR_SIZE };
|
||||
|
||||
private final boolean mVertical;
|
||||
|
||||
@ -59,9 +74,22 @@ public class ScrollbarLayer extends TileLayer {
|
||||
}
|
||||
|
||||
public static ScrollbarLayer create(boolean vertical) {
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(4);
|
||||
buffer.put(3, (byte)127); // Set A to 0.5; leave R/G/B at 0.
|
||||
CairoImage image = new BufferedCairoImage(buffer, 1, 1, CairoImage.FORMAT_ARGB32);
|
||||
int imageSize = nextPowerOfTwo(BAR_SIZE);
|
||||
|
||||
Bitmap bitmap = Bitmap.createBitmap(imageSize, imageSize, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
|
||||
Paint foregroundPaint = new Paint();
|
||||
foregroundPaint.setAntiAlias(true);
|
||||
foregroundPaint.setStyle(Paint.Style.FILL);
|
||||
foregroundPaint.setColor(SCROLLBAR_COLOR);
|
||||
canvas.drawColor(Color.argb(0, 0, 0, 0), PorterDuff.Mode.CLEAR);
|
||||
canvas.drawCircle(CAP_RADIUS, CAP_RADIUS, CAP_RADIUS, foregroundPaint);
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(imageSize * imageSize * 4);
|
||||
bitmap.copyPixelsToBuffer(buffer.asIntBuffer());
|
||||
CairoImage image = new BufferedCairoImage(buffer, imageSize, imageSize, CairoImage.FORMAT_ARGB32);
|
||||
|
||||
return new ScrollbarLayer(image, vertical);
|
||||
}
|
||||
|
||||
@ -73,11 +101,31 @@ public class ScrollbarLayer extends TileLayer {
|
||||
try {
|
||||
GLES11.glEnable(GL10.GL_BLEND);
|
||||
|
||||
RectF rect = mVertical ? getVerticalRect(context) : getHorizontalRect(context);
|
||||
Rect rect = RectUtils.round(mVertical ? getVerticalRect(context) : getHorizontalRect(context));
|
||||
GLES11.glBindTexture(GL10.GL_TEXTURE_2D, getTextureID());
|
||||
|
||||
float y = context.viewport.height() - rect.bottom;
|
||||
GLES11Ext.glDrawTexfOES(rect.left, y, 0.0f, rect.width(), rect.height());
|
||||
float viewHeight = context.viewport.height();
|
||||
|
||||
// for the body of the scrollbar, we take a 1x1 pixel from the center of the image
|
||||
// and scale it to become the bar
|
||||
GLES11.glTexParameteriv(GL10.GL_TEXTURE_2D, GLES11Ext.GL_TEXTURE_CROP_RECT_OES, CROPRECT_MIDPIXEL, 0);
|
||||
GLES11Ext.glDrawTexfOES(rect.left, viewHeight - rect.bottom, 0.0f, rect.width(), rect.height());
|
||||
|
||||
if (mVertical) {
|
||||
// top endcap
|
||||
GLES11.glTexParameteriv(GL10.GL_TEXTURE_2D, GLES11Ext.GL_TEXTURE_CROP_RECT_OES, CROPRECT_TOPCAP, 0);
|
||||
GLES11Ext.glDrawTexfOES(rect.left, viewHeight - rect.top, 0.0f, BAR_SIZE, CAP_RADIUS);
|
||||
// bottom endcap
|
||||
GLES11.glTexParameteriv(GL10.GL_TEXTURE_2D, GLES11Ext.GL_TEXTURE_CROP_RECT_OES, CROPRECT_BOTTOMCAP, 0);
|
||||
GLES11Ext.glDrawTexfOES(rect.left, viewHeight - (rect.bottom + CAP_RADIUS), 0.0f, BAR_SIZE, CAP_RADIUS);
|
||||
} else {
|
||||
// left endcap
|
||||
GLES11.glTexParameteriv(GL10.GL_TEXTURE_2D, GLES11Ext.GL_TEXTURE_CROP_RECT_OES, CROPRECT_LEFTCAP, 0);
|
||||
GLES11Ext.glDrawTexfOES(rect.left - CAP_RADIUS, viewHeight - rect.bottom, 0.0f, CAP_RADIUS, BAR_SIZE);
|
||||
// right endcap
|
||||
GLES11.glTexParameteriv(GL10.GL_TEXTURE_2D, GLES11Ext.GL_TEXTURE_CROP_RECT_OES, CROPRECT_RIGHTCAP, 0);
|
||||
GLES11Ext.glDrawTexfOES(rect.right, viewHeight - rect.bottom, 0.0f, CAP_RADIUS, BAR_SIZE);
|
||||
}
|
||||
} finally {
|
||||
GLES11.glDisable(GL10.GL_BLEND);
|
||||
}
|
||||
@ -86,16 +134,26 @@ public class ScrollbarLayer extends TileLayer {
|
||||
private RectF getVerticalRect(RenderContext context) {
|
||||
RectF viewport = context.viewport;
|
||||
FloatSize pageSize = context.pageSize;
|
||||
float barStart = viewport.height() * viewport.top / pageSize.height;
|
||||
float barEnd = viewport.height() * viewport.bottom / pageSize.height;
|
||||
return new RectF(viewport.width() - BAR_SIZE, barStart, viewport.width(), barEnd);
|
||||
float barStart = (viewport.height() * viewport.top / pageSize.height) + CAP_RADIUS;
|
||||
float barEnd = (viewport.height() * viewport.bottom / pageSize.height) - CAP_RADIUS;
|
||||
if (barStart > barEnd) {
|
||||
float middle = (barStart + barEnd) / 2.0f;
|
||||
barStart = barEnd = middle;
|
||||
}
|
||||
float right = viewport.width() - PADDING;
|
||||
return new RectF(right - BAR_SIZE, barStart, right, barEnd);
|
||||
}
|
||||
|
||||
private RectF getHorizontalRect(RenderContext context) {
|
||||
RectF viewport = context.viewport;
|
||||
FloatSize pageSize = context.pageSize;
|
||||
float barStart = viewport.width() * viewport.left / pageSize.width;
|
||||
float barEnd = viewport.width() * viewport.right / pageSize.width;
|
||||
return new RectF(barStart, viewport.height() - BAR_SIZE, barEnd, viewport.height());
|
||||
float barStart = (viewport.width() * viewport.left / pageSize.width) + CAP_RADIUS;
|
||||
float barEnd = (viewport.width() * viewport.right / pageSize.width) - CAP_RADIUS;
|
||||
if (barStart > barEnd) {
|
||||
float middle = (barStart + barEnd) / 2.0f;
|
||||
barStart = barEnd = middle;
|
||||
}
|
||||
float bottom = viewport.height() - PADDING;
|
||||
return new RectF(barStart, bottom - BAR_SIZE, barEnd, bottom);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user