[haiku-development] Re: RoundRect ButtonFrame

  • From: John Scipione <jscipione@xxxxxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Fri, 23 Mar 2012 04:22:59 -0400

> There is already an implementation of rounded corners in BControlLook. It's
> used for the BTab rendering. The code has to handle a lot of corner cases
> including support for transparent button frames, that is why it may not be
> as straight forward as you may have hoped. But when you follow it closely,
> you should see how it works exactly. IIRC, you need to replicate the code
> for drawing the left/bottom and right/bottom corners, since tabs currently
> only need the left/top and right/top corner. It shouldn't be too hard to
> reuse the tab rendering for button frames. However, BControlLook separates
> button frame rendering from button background rendering. It may indeed be
> best to use a flag in both DrawButtonBackground() and DrawButtonFrame() and
> pass the flag from BButton, so you don't break other interface elements that
> use only one of DrawButtonFrame() and DrawButtonBackground() and combine it
> with a different background/frame that does not expect round corners.

I have finally completed implementing roundrect buttons. I implemented
them basically the way you described above by adding left/bottom and
right/bottom corner methods, clipping, and drawing them. Here is the
obligatory screenshot showing off a bunch of them:

http://imagebin.org/204780

My 2 test apps for this feature were DeskCalc, which has some
different color resizable buttons, and Keymap, which also has
multi-color resizable buttons and a non-rectangular enter key button.
Both of these apps emulate real-world devices so they are perfect
targets for roundrect buttons.

As you can see from the screenshot I also added support for activated,
disabled, focused, and default roundrect buttons for standard
BButtons.

To complete this task I added a few virtual methods to ControlLook.h:

        virtual void                            DrawButtonFrame(BView* view, 
BRect& rect,
                                                                        const 
BRect& updateRect,
                                                                        const 
rgb_color& base,
                                                                        const 
rgb_color& background,
                                                                        uint32 
flags = 0,
                                                                        uint32 
borders = B_ALL_BORDERS);

        virtual void                            DrawButtonFrame(BView* view, 
BRect& rect,
                                                                        const 
BRect& updateRect,
                                                                        float 
radius,
                                                                        const 
rgb_color& base,
                                                                        const 
rgb_color& background,
                                                                        uint32 
flags = 0,
                                                                        uint32 
borders = B_ALL_BORDERS);

        virtual void                            DrawButtonFrame(BView* view, 
BRect& rect,
                                                                        const 
BRect& updateRect,
                                                                        float 
leftTopRadius,
                                                                        float 
rightTopRadius,
                                                                        float 
leftBottomRadius,
                                                                        float 
rightBottomRadius,
                                                                        const 
rgb_color& base,
                                                                        const 
rgb_color& background,
                                                                        uint32 
flags = 0,
                                                                        uint32 
borders = B_ALL_BORDERS);

        virtual void                            DrawButtonBackground(BView* 
view, BRect& rect,
                                                                        const 
BRect& updateRect,
                                                                        const 
rgb_color& base,
                                                                        uint32 
flags = 0,
                                                                        uint32 
borders = B_ALL_BORDERS,
                                                                        enum 
orientation orientation
                                                                                
= B_HORIZONTAL);

        virtual void                            DrawButtonBackground(BView* 
view, BRect& rect,
                                                                        const 
BRect& updateRect,
                                                                        float 
radius,
                                                                        const 
rgb_color& base,
                                                                        uint32 
flags = 0,
                                                                        uint32 
borders = B_ALL_BORDERS,
                                                                        enum 
orientation orientation
                                                                                
= B_HORIZONTAL);

        virtual void                            DrawButtonBackground(BView* 
view, BRect& rect,
                                                                        const 
BRect& updateRect,
                                                                        float 
leftTopRadius,
                                                                        float 
rightTopRadius,
                                                                        float 
leftBottomRadius,
                                                                        float 
rightBottomRadius,
                                                                        const 
rgb_color& base,
                                                                        uint32 
flags = 0,
                                                                        uint32 
borders = B_ALL_BORDERS,
                                                                        enum 
orientation orientation
                                                                                
= B_HORIZONTAL);

As you can see there are the 2 original methods, DrawButtonFrame() and
DrawButtonBackground(), to which I've added 2 overloads each. These
overloads take either a single radius to set all 4 corners to have the
same radius (a common case) or you can specify the radius of each
corner individually. The latter is sometimes useful, it is how I
implemented the RoundRect enter key in Keymap for instance.

My first question is, will these additional virtual methods break apps
compiled with the existing ControlLook class break?

My second question is, what do you think of adding a radius to the
default BButton? Windows 7, Mac OS X Lion, Gnome 3, KDE 4, BeOS Dano,
and Zeta all sport roundrect buttons. They seem to be awfully popular
these days.

John Scipione

Other related posts: