|
|
Home » U++ Library support » U++ Widgets - General questions or Mixed problems » State of "button"
State of "button" [message #15143] |
Wed, 02 April 2008 17:32  |
cbpporter
Messages: 1427 Registered: September 2007
|
Ultimate Contributor |
|
|
OK, I've done it again! I had to write custom code to be able to do some very basic and common things with a button.
I'm a little unhappy with the state of button classes in U++. Button is by far the most advanced of them, but it does not feature a "down" state. A lot of my buttons need a down state. You can use ButtonOption, but that class is semi useless. Or you can use ToolButton, but that need a lot of visual tweaks to get it to behave nicely. Worst of all, if you change class, you have to modify a lot of code, since interfaces are different(one has Label, other has SetLabel).
So I propose a number of changes:
1. Uniform interface. Pretty self-explanatory.
2. Get rid of ButtonOption and add down state to Button (add typedef Button ButtonOption) or make ButtonOption inherit Button, add a label property, StyleDefault, etc.
3. Either add a StyleFlat to Button, or tweak ToolButton so that it can be used as a generic button.
4. Make styles compatible between button classes.
These are just some suggestions and the list is open, but before stable 2008 I think that it would be great if buttons wouldn't cause such headaches. I implemented partially on a by need bases a lot of these ideas, and would be relatively easy to gather them and implement this, but I need to know what you think.
|
|
|
|
|
|
Re: State of "button" [message #15341 is a reply to message #15314] |
Wed, 16 April 2008 21:46   |
cbpporter
Messages: 1427 Registered: September 2007
|
Ultimate Contributor |
|
|
luzr wrote on Wed, 16 April 2008 11:17 | The trouble of ButtonOption visuals (which I do not really like too) is that needed bits are missing in theming APIs and I was not able to find a good heurestics to create them...
Other than that, I am not a big friend of "one fits all" button class. What is wrong with using specific classes for specific purposes?
Mirek
|
The problem with ButtonOption is not related to visual style, which on both XP and Vista look OK, but the lack of functionality.
I was not suggesting to make a "one fits all", but rather make other classes except Button viable. But anyway, Button still is a special class and could very well do with a "one fits all" solution, mainly because it's a button. It's not supposed to do anything fancy, just be able to respond to click, display text and optionally an Image.
So to sum of what I consider insufficient: Button has no down state. That means I have to use ButtonOption or ToolButton. ButtonOption has no label and also the interface could be much more similar to Button. IMO, It should be 100% the same, except the part related to checking and unchecking. ToolButton on the other hand has two problems. First, the visual are not good at custom sizes. Easy to fix. I proposed a fix a while ago and it was applied, and it works well, except when messing with StyleDefault. I have better fix since then. Second, interface, and especially style is not compatible, so there is a lot of extra code If you want it to not be flat. The same applies to other button classes if you want them to be flat.
|
|
|
Re: State of "button" [message #15451 is a reply to message #15341] |
Thu, 24 April 2008 13:08   |
cbpporter
Messages: 1427 Registered: September 2007
|
Ultimate Contributor |
|
|
Here is a little annoyance: doing something like this switches from the OS skin to some other skin in ToolButton:
static ToolButton::Style s = ToolButton::StyleDefault();
but.SetStyle(s);
This is actually due to my fix for skins outside a ToolBar, by adding this line to the constructor:
ToolButton::ToolButton()
{
Reset();
checked = false;
paint_checked = false;
// next line
SetStyle(ToolBar::StyleDefault().buttonstyle);
Transparent();
}
This was not the best fix, because it does not update the default style. My understanding of Chameleon is better now, and I think it would be better to update the style directly:
void ChHostSkin()
{
ChSysInit();
.................
{
ToolBar::Style& s = ToolBar::StyleDefault().Write();
Win32Look(s.buttonstyle.look, 6, XP_TOOLBAR, 1, 1);
Win32Look(ToolButton::StyleDefault().Write().look, 6, XP_TOOLBAR, 1, 1);
Win32Look(s.arealook, XP_REBAR, 0, 1);
s.breaksep.l2 = SColorLight();
}
This is also IMO better, since ToolButton has a style default, and thus should own it's style. buttonstyle from TollBar is still updated to maintain backward compatibility.
Also, would it be possible to add this style to ToolButton?
CH_STYLE(ToolButton, Style, StyleSolid)
{
const Button::Style& bs = Button::StyleNormal();
look[0] = bs.look[0];
look[1] = bs.look[1];
look[2] = bs.look[2];
look[3] = bs.look[3];
look[4] = bs.look[2];
look[5] = bs.look[1];
font = StdFont();
for(int i = 0; i < 4; i++)
textcolor[i] = Button::StyleNormal().textcolor[i];
textcolor[CTRL_CHECKED] = textcolor[CTRL_NORMAL];
textcolor[CTRL_HOTCHECKED] = textcolor[CTRL_HOT];
for(int i = 0; i < 6; i++) {
light[i] = false;
contrast[i] = 0;
}
light[CTRL_PRESSED] = light[CTRL_HOT] = light[CTRL_HOTCHECKED] = true;
}
|
|
|
|
|
Re: State of "button" [message #15563 is a reply to message #15500] |
Tue, 29 April 2008 10:17   |
cbpporter
Messages: 1427 Registered: September 2007
|
Ultimate Contributor |
|
|
I centered the image in text in ToolButton. I've done this as default for both modes that have label. I hope I did not upset some pixel perfect layout of these elements that you had in mind, but I think that they are set up the same in toolbars. Tested in UWord too and looks the same. I don't think that default center is a problem since no one would like a button like this:

Here is the code:
void ToolButton::Paint(Draw& w)
{
LTIMING("ToolButton::Paint");
paint_checked = checked;
Size sz = GetSize();
UPP::Image image = GetImage();
Size isz = image.GetSize();
// Ctrl *q = GetParent()->GetParent();
// if(!q || !q->IsTransparent())
// w.DrawRect(sz, checked && !HasMouse() ? Blend(SColorFace, SColorLight) : SColorFace);
int li = IsEnabled() ? HasMouse() ? GetMouseLeft() ? CTRL_PRESSED
: checked ? CTRL_HOTCHECKED : CTRL_HOT
: checked ? CTRL_CHECKED : CTRL_NORMAL
: CTRL_DISABLED;
ChPaint(w, sz, style->look[li]);
Point off = style->offset[li];
Point ip = (sz - isz) / 2 + off;
Size tsz;
if(kind != NOLABEL)
tsz = GetTextSize(text, style->font);
if(kind == BOTTOMLABEL) {
ip.y -= tsz.cy / 2 + 1;
w.DrawText((sz.cx - tsz.cx) / 2 + off.x, ip.y + isz.cy + 2 + off.y, text, style->font, style->textcolor[li]);
}
if(kind == RIGHTLABEL) {
ip.x -= tsz.cx / 2 + 2;
w.DrawText(ip.x + isz.cx + 3 + off.x, (sz.cy - tsz.cy) / 2 + off.y, text, style->font, style->textcolor[li]);
}
UPP::Image img = CachedContrast(image, style->contrast[li]);
if(!IsEnabled())
img = DisabledImage(img);
if(IsEnabled() && style->light[li])
DrawHighlightImage(w, ip.x, ip.y, img, true);
else
w.DrawImage(ip.x, ip.y, img);
}
Also, some extra stuff for checking:
Bar::Item& ToolButton::Check(bool check)
{
checked = check;
Refresh();
return *this;
}
ToolButton& Label(const char *text, int kind = ToolButton::RIGHTLABEL);
bool IsChecked() { return checked; } // in header
I didn't use bool Get() since there is Radio too, and it would be ambiguous: does get return checked state or radio state? Right now they are the same, but this could change.
This about covers all there is to make ToolButton a viable ButtonOption replacement. It does not look that great checked with solid skin on Vista, but neither does ButtonOption, so I guess it's ok.
-
Attachment: Button.png
(Size: 15.20KB, Downloaded 818 times)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Goto Forum:
Current Time: Fri May 09 20:03:38 CEST 2025
Total time taken to generate the page: 0.03869 seconds
|
|
|