Opened 12 years ago

Closed 12 years ago

#1858 closed enhancement (fixed)

Gradient patterns

Reported by: denis washington Owned by: stippi
Priority: normal Milestone: R1
Component: Kits/Interface Kit Version: R1/pre-alpha1
Keywords: Cc:
Blocked By: Blocking:
Platform: All


BView's Fill*() functions should also support gradients as patterns. Many modern-looking effects cannot be done easily without being able to draw gradients.

Change History (6)

comment:1 by stippi, 12 years ago

Owner: changed from axeld to stippi
Status: newassigned

Yes, this is somewhere on my TODO list. It is easy to implement actually with AGG as backend. I just have not thought of a good API. For example, I was considering custom gradient functions. But this is tricky with a cross application design like client -> server. In any case, have a look at libs/icon/style/Gradient.* and tell me what you think. I might just extend that class a bit and reuse it in the interface kit.

comment:2 by denis washington, 12 years ago

The nicest way would be to have all Fill/Stroke functions to be overloaded, like this:

FillRect(BRect& rect, pattern aPattern); FillRect(BRect& rect, BGradient& gradient);

Actually, one could think about deprecating the pattern version then, as BGradient would support mostly everything that "classic" patterns can do (naturally deprecation only, not removing - for R5 compatibility). Maybe even call BGradient BPattern instead?

Independent from that issue, I think the Gradient API you pointed me to is already pretty good. I have some things though:

  • Are the offsets from 0.0 to 1.0? I guess so, but I wasn't sure when I looked at the API. If not, they should be, as that makes the gradient independent of the size of the area it is drawn to.
  • How does one define further gradient parameters, like e.g. the direction of a linear gradient or the circle position and radius of a circular gradient? I guess there should be some method(s) to set this information (in 0.0..1.0 coordinates)? If the parameters are very different for some types of gradients, it might make sense to subclass Gradient (BGradientLinear, BGradientCircular...), although this is a bit more complicated than just a SetType() method. A compromise between those two solutions would be to replace SetType() with methods like SetLinear() and SetCircular() which set the type _and_ the required parameters. They could have static CreateLinear(), CreateCircular() etc complements to quickly create BGradient/BPattern objects.
  • SetColor() should also accept a color_step instead of an index. The ability to specify the color as color_step feels a bit strange though, as the color_step stores more than just a color. As library user I would ask myself if the offset is also taken from the color_step.
  • I think SetInterpolation() should be SetInterpolationType(). Just feels better for me.
  • What are SetInheritTransformation() and FitToBounds() for?

You might want to look at the API of Cairo's cairo_pattern_t type, it's nicely made IMO.

comment:3 by stippi, 12 years ago

Eventually, I would like something like this:

BView::DrawSomething(..., const BStyle& style);

where style is the complete graphical appearance. Ie fill, and/or outline plus other stuff like drop shadows and so on. "Something" is then a shape defined by a vector path (possibly composed of subpaths).

The Gradient class you looked has an embedded transformation matrix which defines its location in the 2D pixel grid.

Yes, offsets are from 0.0 to 1.0.

Gradient parameters are "implicit", ie all gradients generate in 0,0->100,100 which is then modified by the embedded gradient. But this will need to change in order to support more parameters like focal point and so on.

comment:4 by denis washington, 12 years ago

That would indeed be cool. I would recommend you to look at the Cairo API, it is very well thought out and nice to work with.

comment:5 by jackburton, 12 years ago

Isn't this done now ?

comment:6 by stippi, 12 years ago

Resolution: fixed
Status: assignedclosed

Yes, for now. We may or may not want to have Stroke*() version which take a BGradient as well (a copy&paste job). But this ticket should probably not be used to track such important post-R1 API changes such as DrawSomething(..., const BStyle& style). So I guess I can close this. Kudos to Artur for implementing/integrating BGradients!

Note: See TracTickets for help on using tickets.