03-15-2010 10:51 AM
I struggled quite a bit to figure out how to draw a rounded rectangle with a gradient fill using the Graphics.drawShadedFilledPath method. When I finally got it, the solution surprised me.
If you're struggling to use Graphics.drawShadedFilledPath to draw a nice-looking button, perhaps this article I wrote will prove helpful:
http://www.deepgraysea.com/bbroundedrect.htm
Offered as a thank-you for all the other helpful solutions in this forum. I'm sort of a "Google-and-paste" programmer so I'd be lost without you guys. Hope this helps someone,
Michael Micheletti
03-15-2010 11:27 AM
Very well written example!
And a lot of work for a simple button - that's how some apps get the good looks ![]()
03-15-2010 07:22 PM
I agree with simon, very well written. Helped me and gave good examples (I'm a visual learner).
03-15-2010 11:28 PM
03-16-2010 01:51 AM
Very nice write-up. Thanks for posting it!
You mentioned that you hadn't figured out the purpose of the last argument to drawShadedFilledPath. That is needed if you wanted to fill a shape that had a disconnected boundary--a donut, for instance. The last argument would be an array equal in length to the number of boundary pieces. Each entry would be the start index of each boundary piece within the other arrays.
03-16-2010 12:27 PM
Ah, thanks Ted for the clue about the last argument. Lucky I didn't need to draw a donut-shaped button or it might have taken me another week or so :-) Thanks to all for the kind word, glad the example is helpful.
03-16-2010 01:10 PM - edited 03-16-2010 01:37 PM
Very nice.
04-01-2010 08:08 AM - edited 04-01-2010 09:24 AM
Thank you for that awesomely helpful article. In return here is the generic fill routine I wrote based on your article which others may find useful:
import net.rim.device.api.ui.Graphics;
public class GraphicsEx {
static public void drawOptionallyRoundedGradientFilledBox
(Graphics g, int x, int y, int w, int h,
int r1, int r2, int r3, int r4,
int c1, int c2, int c3, int c4) {
int x2 = x+w-1;
int [] xPts = {
x, x, x+r1, x2-r2, x2, x2,
x2, x2, x2-r3, x+r4, x, x
};
int y2 = y+h-1;
int [] yPts = {
y+r1, y, y, y, y, y+r2,
y2-r3, y2, y2, y2, y2, y2-r4
};
int [] gradient = {
c1, c1, c1, c2, c2, c2,
c3, c3, c3, c4, c4, c4,
};
byte [] pointTypes = {
Graphics.CURVEDPATH_END_POINT,
r1 > 0 ? Graphics.CURVEDPATH_QUADRATIC_BEZIER_CONTROL_POINT
: Graphics.CURVEDPATH_END_POINT,
Graphics.CURVEDPATH_END_POINT,
Graphics.CURVEDPATH_END_POINT,
r2 > 0 ? Graphics.CURVEDPATH_QUADRATIC_BEZIER_CONTROL_POINT
: Graphics.CURVEDPATH_END_POINT,
Graphics.CURVEDPATH_END_POINT,
Graphics.CURVEDPATH_END_POINT,
r3 > 0 ? Graphics.CURVEDPATH_QUADRATIC_BEZIER_CONTROL_POINT
: Graphics.CURVEDPATH_END_POINT,
Graphics.CURVEDPATH_END_POINT,
Graphics.CURVEDPATH_END_POINT,
r4 > 0 ? Graphics.CURVEDPATH_QUADRATIC_BEZIER_CONTROL_POINT
: Graphics.CURVEDPATH_END_POINT,
Graphics.CURVEDPATH_END_POINT,
};
g.drawShadedFilledPath(xPts, yPts, pointTypes, gradient, null);
}
}
Where
And here is how I use it to draw the field boxes that mimic the way the UITableView works on iPhone
int c1 = hasFocus ? Color.BLUE : Color.WHITE; int c2 = hasFocus ? Color.DARKBLUE : Color.WHITE; int cornersBot = 10; int cornersTop = 10; if (index < view.getFieldCount(sectionIndex)-1) cornersBot = 0; if (index > 0) cornersTop = 0; GraphicsEx.drawOptionallyRoundedGradientFilledBox(graphics, 0, y, width, rowHeight, cornersTop, cornersTop, cornersBot, cornersBot, ct, ct, cb, cb);
04-14-2010 03:47 AM
Yes, It's really nice and also helpful.
But one thing I could not understand , How to use the offset parameter in the Graphics.drawShadedFilledPath() method.
Can anyone help me?
04-14-2010 07:29 AM
I think the offset is used as follows, based only on reading the docs, though I am not entirely sure if each offset is both the end of the previous path and the beginning of the next path or if the offset is used in start+end pairs.
The x and y points are point along your path. Imagine a picture with dots on no lines. A bit like a dot to dot picture.
The offsets specify the paths between those dots, and the paths may cross the same point several times. So the offsets specify which points to visit along its path.
So for example, two triangles (or a rectangle with triangle cut out) might be drawn as follows.
off x,y
0 0,0
1 100,0
2 200,0
3 200,50
4 0,50
offsets (path)
1, 4, 0, 1, 2, 3, 1
I would have to experiment to be sure.