Move mnemonic key as a property of ui::Widget

In this was we can process the text string just one time to remove the
character preceded by '&' that will be finally acts as a mnemonic. This
simplifies the rendering and text measure code too.
This commit is contained in:
David Capello 2017-02-14 14:16:37 -03:00
parent bb4faca1d1
commit 17151cddcd
15 changed files with 131 additions and 102 deletions

View File

@ -1,5 +1,5 @@
// Aseprite // Aseprite
// Copyright (C) 2001-2016 David Capello // Copyright (C) 2001-2017 David Capello
// //
// This program is distributed under the terms of // This program is distributed under the terms of
// the End-User License Agreement for Aseprite. // the End-User License Agreement for Aseprite.
@ -231,12 +231,14 @@ Widget* AppMenus::convertXmlelemToMenuitem(TiXmlElement* elem)
// Create the item // Create the item
AppMenuItem* menuitem = new AppMenuItem(elem->Attribute("text"), command, params); AppMenuItem* menuitem = new AppMenuItem(elem->Attribute("text"), command, params);
if (!menuitem) if (!menuitem)
return NULL; return nullptr;
/* has it a ID? */ menuitem->processMnemonicFromText();
// Has it a ID?
const char* id = elem->Attribute("id"); const char* id = elem->Attribute("id");
if (id) { if (id) {
/* recent list menu */ // Recent list menu
if (strcmp(id, "recent_list") == 0) { if (strcmp(id, "recent_list") == 0) {
m_recentListMenuitem = menuitem; m_recentListMenuitem = menuitem;
} }

View File

@ -214,7 +214,7 @@ private:
g->drawUIText(text(), fg, bg, g->drawUIText(text(), fg, bg,
gfx::Point( gfx::Point(
bounds.x + m_level*16 * guiscale(), bounds.x + m_level*16 * guiscale(),
bounds.y + 2*guiscale())); bounds.y + 2*guiscale()), 0);
if (m_key && !m_key->accels().empty()) { if (m_key && !m_key->accels().empty()) {
std::string buf; std::string buf;
@ -292,12 +292,13 @@ private:
const char* label = "x"; const char* label = "x";
m_deleteButton->setBgColor(gfx::ColorNone); m_deleteButton->setBgColor(gfx::ColorNone);
m_deleteButton->setBounds(gfx::Rect( m_deleteButton->setBounds(
itemBounds.x + itemBounds.w + 2*guiscale(), gfx::Rect(
itemBounds.y, itemBounds.x + itemBounds.w + 2*guiscale(),
Graphics::measureUITextLength( itemBounds.y,
label, font()) + 4*guiscale(), Graphics::measureUITextLength(
itemBounds.h)); label, font()) + 4*guiscale(),
itemBounds.h));
m_deleteButton->setText(label); m_deleteButton->setText(label);
invalidate(); invalidate();

View File

@ -138,8 +138,7 @@ void ButtonSet::Item::onPaint(ui::PaintEvent& ev)
if (hasText()) { if (hasText()) {
g->setFont(font()); g->setFont(font());
g->drawUIText(text(), fg, gfx::ColorNone, textRc.origin(), g->drawUIText(text(), fg, gfx::ColorNone, textRc.origin(), 0);
false);
} }
} }
@ -159,7 +158,7 @@ bool ButtonSet::Item::onProcessMessage(ui::Message* msg)
if (isEnabled() && hasText()) { if (isEnabled() && hasText()) {
KeyMessage* keymsg = static_cast<KeyMessage*>(msg); KeyMessage* keymsg = static_cast<KeyMessage*>(msg);
bool mnemonicPressed = (msg->altPressed() && bool mnemonicPressed = (msg->altPressed() &&
mnemonicCharPressed(keymsg)); isMnemonicPressed(keymsg));
if (mnemonicPressed || if (mnemonicPressed ||
(hasFocus() && keymsg->scancode() == kKeySpace)) { (hasFocus() && keymsg->scancode() == kKeySpace)) {

View File

@ -230,7 +230,7 @@ void ColorButton::onPaint(PaintEvent& ev)
gfx::Rect textrc; gfx::Rect textrc;
getTextIconInfo(NULL, &textrc); getTextIconInfo(NULL, &textrc);
g->drawUIText(text(), textcolor, gfx::ColorNone, textrc.origin()); g->drawUIText(text(), textcolor, gfx::ColorNone, textrc.origin(), 0);
} }
void ColorButton::onClick(Event& ev) void ColorButton::onClick(Event& ev)

View File

@ -947,7 +947,8 @@ void SkinTheme::paintCheckBox(PaintEvent& ev)
} }
// Text // Text
drawText(g, NULL, ColorNone, ColorNone, widget, text, 0); drawText(g, nullptr, ColorNone, ColorNone, widget, text, 0,
widget->mnemonic());
// Paint the icon // Paint the icon
if (iconInterface) if (iconInterface)
@ -1136,7 +1137,7 @@ void SkinTheme::drawEntryText(ui::Graphics* g, ui::Entry* widget)
drawText( drawText(
g, widget->getSuffix().c_str(), g, widget->getSuffix().c_str(),
colors.entrySuffix(), ColorNone, colors.entrySuffix(), ColorNone,
widget, sufBounds, 0); widget, sufBounds, 0, 0);
} }
} }
@ -1227,7 +1228,7 @@ void SkinTheme::paintListItem(ui::PaintEvent& ev)
if (widget->hasText()) { if (widget->hasText()) {
bounds.shrink(widget->border()); bounds.shrink(widget->border());
drawText(g, NULL, fg, bg, widget, bounds, 0); drawText(g, nullptr, fg, bg, widget, bounds, 0, 0);
} }
} }
@ -1298,7 +1299,8 @@ void SkinTheme::paintMenuItem(ui::PaintEvent& ev)
Rect pos = bounds; Rect pos = bounds;
if (!bar) if (!bar)
pos.offset(widget->childSpacing()/2, 0); pos.offset(widget->childSpacing()/2, 0);
drawText(g, NULL, fg, ColorNone, widget, pos, 0); drawText(g, nullptr, fg, ColorNone, widget, pos, 0,
widget->mnemonic());
// For menu-box // For menu-box
if (!bar) { if (!bar) {
@ -1335,7 +1337,7 @@ void SkinTheme::paintMenuItem(ui::PaintEvent& ev)
std::string buf = appMenuItem->key()->accels().front().toString(); std::string buf = appMenuItem->key()->accels().front().toString();
widget->setAlign(RIGHT | MIDDLE); widget->setAlign(RIGHT | MIDDLE);
drawText(g, buf.c_str(), fg, ColorNone, widget, pos, 0); drawText(g, buf.c_str(), fg, ColorNone, widget, pos, 0, 0);
widget->setAlign(old_align); widget->setAlign(old_align);
} }
} }
@ -1375,7 +1377,7 @@ void SkinTheme::paintRadioButton(PaintEvent& ev)
} }
// Text // Text
drawText(g, NULL, ColorNone, ColorNone, widget, text, 0); drawText(g, nullptr, ColorNone, ColorNone, widget, text, 0, widget->mnemonic());
// Icon // Icon
if (iconInterface) if (iconInterface)
@ -1417,9 +1419,9 @@ void SkinTheme::paintSeparator(ui::PaintEvent& ev)
bounds.y + bounds.h/2 - h/2, bounds.y + bounds.h/2 - h/2,
widget->textWidth(), h); widget->textWidth(), h);
drawText(g, NULL, drawText(g, nullptr,
colors.separatorLabel(), BGCOLOR, colors.separatorLabel(), BGCOLOR,
widget, r, 0); widget, r, 0, widget->mnemonic());
} }
} }
@ -1522,18 +1524,18 @@ void SkinTheme::paintSlider(PaintEvent& ev)
{ {
IntersectClip clip(g, Rect(rc.x, rc.y, x-rc.x, rc.h)); IntersectClip clip(g, Rect(rc.x, rc.y, x-rc.x, rc.h));
if (clip) { if (clip) {
drawText(g, NULL, drawText(g, nullptr,
colors.sliderFullText(), ColorNone, colors.sliderFullText(), ColorNone,
widget, rc, 0); widget, rc, 0, widget->mnemonic());
} }
} }
{ {
IntersectClip clip(g, Rect(x+1, rc.y, rc.w-(x-rc.x+1), rc.h)); IntersectClip clip(g, Rect(x+1, rc.y, rc.w-(x-rc.x+1), rc.h));
if (clip) { if (clip) {
drawText(g, NULL, drawText(g, nullptr,
colors.sliderEmptyText(), colors.sliderEmptyText(),
ColorNone, widget, rc, 0); ColorNone, widget, rc, 0, widget->mnemonic());
} }
} }
@ -1816,7 +1818,7 @@ gfx::Color SkinTheme::getWidgetBgColor(Widget* widget)
void SkinTheme::drawText(Graphics* g, const char *t, gfx::Color fg_color, gfx::Color bg_color, void SkinTheme::drawText(Graphics* g, const char *t, gfx::Color fg_color, gfx::Color bg_color,
Widget* widget, const Rect& rc, Widget* widget, const Rect& rc,
int selected_offset) int selected_offset, int mnemonic)
{ {
if (t || widget->hasText()) { if (t || widget->hasText()) {
Rect textrc; Rect textrc;
@ -1869,18 +1871,22 @@ void SkinTheme::drawText(Graphics* g, const char *t, gfx::Color fg_color, gfx::C
if (clip) { if (clip) {
if (!widget->isEnabled()) { if (!widget->isEnabled()) {
// Draw white part // Draw white part
g->drawUIText(t, g->drawUIText(
t,
colors.background(), colors.background(),
gfx::ColorNone, gfx::ColorNone,
textrc.origin() + Point(guiscale(), guiscale())); textrc.origin() + Point(guiscale(), guiscale()),
mnemonic);
} }
g->drawUIText(t, g->drawUIText(
t,
(!widget->isEnabled() ? (!widget->isEnabled() ?
colors.disabled(): colors.disabled():
(gfx::geta(fg_color) > 0 ? fg_color : (gfx::geta(fg_color) > 0 ? fg_color :
colors.text())), colors.text())),
bg_color, textrc.origin()); bg_color, textrc.origin(),
mnemonic);
} }
} }
} }

View File

@ -135,7 +135,7 @@ namespace app {
gfx::Color getWidgetBgColor(ui::Widget* widget); gfx::Color getWidgetBgColor(ui::Widget* widget);
void drawText(ui::Graphics* g, const char *t, gfx::Color fg_color, gfx::Color bg_color, void drawText(ui::Graphics* g, const char *t, gfx::Color fg_color, gfx::Color bg_color,
ui::Widget* widget, const gfx::Rect& rc, ui::Widget* widget, const gfx::Rect& rc,
int selected_offset); int selected_offset, int mnemonic);
void drawEntryText(ui::Graphics* g, ui::Entry* widget); void drawEntryText(ui::Graphics* g, ui::Entry* widget);
void paintIcon(ui::Widget* widget, ui::Graphics* g, ui::IButtonIcon* iconInterface, int x, int y); void paintIcon(ui::Widget* widget, ui::Graphics* g, ui::IButtonIcon* iconInterface, int x, int y);

View File

@ -475,8 +475,9 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
} }
// Was the widget created? // Was the widget created?
if (widget) if (widget) {
fillWidgetWithXmlElementAttributesWithChildren(elem, root, widget); fillWidgetWithXmlElementAttributesWithChildren(elem, root, widget);
}
return widget; return widget;
} }
@ -587,6 +588,9 @@ void WidgetLoader::fillWidgetWithXmlElementAttributes(const TiXmlElement* elem,
} }
} }
} }
// Assign widget mnemonic from the character preceded by a '&'
widget->processMnemonicFromText();
} }
void WidgetLoader::fillWidgetWithXmlElementAttributesWithChildren(const TiXmlElement* elem, ui::Widget* root, ui::Widget* widget) void WidgetLoader::fillWidgetWithXmlElementAttributesWithChildren(const TiXmlElement* elem, ui::Widget* root, ui::Widget* widget)

View File

@ -1,5 +1,5 @@
// Aseprite UI Library // Aseprite UI Library
// Copyright (C) 2001-2016 David Capello // Copyright (C) 2001-2017 David Capello
// //
// This file is released under the terms of the MIT license. // This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information. // Read LICENSE.txt for more information.
@ -158,6 +158,7 @@ void Alert::processString(std::string& buf)
else if (button) { else if (button) {
char buttonId[256]; char buttonId[256];
Button* button_widget = new Button(item); Button* button_widget = new Button(item);
button_widget->processMnemonicFromText();
button_widget->setMinSize(gfx::Size(60*guiscale(), 0)); button_widget->setMinSize(gfx::Size(60*guiscale(), 0));
m_buttons.push_back(button_widget); m_buttons.push_back(button_widget);

View File

@ -101,7 +101,7 @@ bool ButtonBase::onProcessMessage(Message* msg)
if (isEnabled()) { if (isEnabled()) {
bool mnemonicPressed = bool mnemonicPressed =
((msg->altPressed() || msg->cmdPressed()) && ((msg->altPressed() || msg->cmdPressed()) &&
mnemonicCharPressed(keymsg)); isMnemonicPressed(keymsg));
// For kButtonWidget // For kButtonWidget
if (m_behaviorType == kButtonWidget) { if (m_behaviorType == kButtonWidget) {

View File

@ -237,11 +237,11 @@ namespace {
class DrawUITextDelegate : public she::DrawTextDelegate { class DrawUITextDelegate : public she::DrawTextDelegate {
public: public:
DrawUITextDelegate(she::Surface* surface, DrawUITextDelegate(she::Surface* surface,
she::Font* font, const bool drawUnderscore) she::Font* font, const int mnemonic)
: m_surface(surface) : m_surface(surface)
, m_font(font) , m_font(font)
, m_drawUnderscore(drawUnderscore) , m_mnemonic(std::tolower(mnemonic))
, m_underscoreNext(false) { , m_underscoreColor(gfx::ColorNone) {
} }
gfx::Rect bounds() const { return m_bounds; } gfx::Rect bounds() const { return m_bounds; }
@ -253,19 +253,15 @@ public:
gfx::Color& bg, gfx::Color& bg,
bool& drawChar, bool& drawChar,
bool& moveCaret) override { bool& moveCaret) override {
if (m_underscoreNext)
m_underscoreColor = fg;
if (!m_surface) if (!m_surface)
drawChar = false; drawChar = false;
else {
moveCaret = true; if (m_mnemonic && std::tolower(chr) == m_mnemonic) {
if (chr == '&') { // TODO change this with other character, maybe '_' or configurable m_underscoreColor = fg;
auto it2 = it; m_mnemonic = 0; // Just one time
++it2; }
if (it2 != end && *it2 != '&') { else {
m_underscoreNext = true; m_underscoreColor = gfx::ColorNone;
moveCaret = false;
} }
} }
} }
@ -276,40 +272,36 @@ public:
} }
void postDrawChar(const gfx::Rect& charBounds) override { void postDrawChar(const gfx::Rect& charBounds) override {
if (m_underscoreNext) { if (!gfx::is_transparent(m_underscoreColor)) {
m_underscoreNext = false; // TODO underscore height = guiscale() should be configurable from ui::Theme
if (m_drawUnderscore) { int dy = 0;
// TODO underscore height = guiscale() should be configurable from ui::Theme if (m_font->type() == she::FontType::kTrueType) // TODO use other method to locate the underline
int dy = 0; dy += guiscale();
if (m_font->type() == she::FontType::kTrueType) // TODO use other method to locate the underline gfx::Rect underscoreBounds(charBounds.x, charBounds.y+charBounds.h+dy,
dy += guiscale(); charBounds.w, guiscale());
gfx::Rect underscoreBounds(charBounds.x, charBounds.y+charBounds.h+dy, m_surface->fillRect(m_underscoreColor, underscoreBounds);
charBounds.w, guiscale()); m_bounds |= underscoreBounds;
m_surface->fillRect(m_underscoreColor, underscoreBounds);
m_bounds |= underscoreBounds;
}
} }
} }
private: private:
she::Surface* m_surface; she::Surface* m_surface;
she::Font* m_font; she::Font* m_font;
bool m_drawUnderscore; int m_mnemonic;
bool m_underscoreNext;
gfx::Color m_underscoreColor; gfx::Color m_underscoreColor;
gfx::Rect m_bounds; gfx::Rect m_bounds;
}; };
} }
void Graphics::drawUIText(const std::string& str, gfx::Color fg, gfx::Color bg, const gfx::Point& pt, void Graphics::drawUIText(const std::string& str, gfx::Color fg, gfx::Color bg,
bool drawUnderscore) const gfx::Point& pt, const int mnemonic)
{ {
she::SurfaceLock lock(m_surface); she::SurfaceLock lock(m_surface);
int x = m_dx+pt.x; int x = m_dx+pt.x;
int y = m_dy+pt.y; int y = m_dy+pt.y;
DrawUITextDelegate delegate(m_surface, m_font, drawUnderscore); DrawUITextDelegate delegate(m_surface, m_font, mnemonic);
she::draw_text(m_surface, m_font, she::draw_text(m_surface, m_font,
base::utf8_const_iterator(str.begin()), base::utf8_const_iterator(str.begin()),
base::utf8_const_iterator(str.end()), base::utf8_const_iterator(str.end()),
@ -318,7 +310,8 @@ void Graphics::drawUIText(const std::string& str, gfx::Color fg, gfx::Color bg,
dirty(delegate.bounds()); dirty(delegate.bounds());
} }
void Graphics::drawAlignedUIText(const std::string& str, gfx::Color fg, gfx::Color bg, const gfx::Rect& rc, int align) void Graphics::drawAlignedUIText(const std::string& str, gfx::Color fg, gfx::Color bg,
const gfx::Rect& rc, const int align)
{ {
doUIStringAlgorithm(str, fg, bg, rc, align, true); doUIStringAlgorithm(str, fg, bg, rc, align, true);
} }
@ -333,7 +326,7 @@ gfx::Size Graphics::measureUIText(const std::string& str)
// static // static
int Graphics::measureUITextLength(const std::string& str, she::Font* font) int Graphics::measureUITextLength(const std::string& str, she::Font* font)
{ {
DrawUITextDelegate delegate(nullptr, font, false); DrawUITextDelegate delegate(nullptr, font, 0);
she::draw_text(nullptr, font, she::draw_text(nullptr, font,
base::utf8_const_iterator(str.begin()), base::utf8_const_iterator(str.begin()),
base::utf8_const_iterator(str.end()), base::utf8_const_iterator(str.end()),

View File

@ -86,13 +86,9 @@ namespace ui {
const base::utf8_const_iterator& end, const base::utf8_const_iterator& end,
gfx::Color fg, gfx::Color bg, const gfx::Point& pt, gfx::Color fg, gfx::Color bg, const gfx::Point& pt,
she::DrawTextDelegate* delegate); she::DrawTextDelegate* delegate);
void drawText(const std::string& str, gfx::Color fg, gfx::Color bg, const gfx::Point& pt);
void drawText(const std::string& str, gfx::Color fg, gfx::Color bg, void drawUIText(const std::string& str, gfx::Color fg, gfx::Color bg, const gfx::Point& pt, const int mnemonic);
const gfx::Point& pt); void drawAlignedUIText(const std::string& str, gfx::Color fg, gfx::Color bg, const gfx::Rect& rc, const int align);
void drawUIText(const std::string& str, gfx::Color fg, gfx::Color bg,
const gfx::Point& pt, bool drawUnderscore = true);
void drawAlignedUIText(const std::string& str, gfx::Color fg, gfx::Color bg,
const gfx::Rect& rc, int align);
gfx::Size measureUIText(const std::string& str); gfx::Size measureUIText(const std::string& str);
static int measureUITextLength(const std::string& str, she::Font* font); static int measureUITextLength(const std::string& str, she::Font* font);

View File

@ -1,5 +1,5 @@
// Aseprite UI Library // Aseprite UI Library
// Copyright (C) 2001-2016 David Capello // Copyright (C) 2001-2017 David Capello
// //
// This file is released under the terms of the MIT license. // This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information. // Read LICENSE.txt for more information.
@ -1218,7 +1218,7 @@ static MenuItem* check_for_letter(Menu* menu, const KeyMessage* keymsg)
continue; continue;
MenuItem* menuitem = static_cast<MenuItem*>(child); MenuItem* menuitem = static_cast<MenuItem*>(child);
if (menuitem->mnemonicCharPressed(keymsg)) if (menuitem->isMnemonicPressed(keymsg))
return menuitem; return menuitem;
} }
return NULL; return NULL;

View File

@ -152,7 +152,8 @@ void Theme::paintLayer(Graphics* g, Widget* widget,
layer.color(), layer.color(),
gfx::ColorNone, gfx::ColorNone,
gfx::Point(rc.x+rc.w/2-textSize.w/2, gfx::Point(rc.x+rc.w/2-textSize.w/2,
rc.y+rc.h/2-textSize.h/2), true); rc.y+rc.h/2-textSize.h/2),
widget->mnemonic());
} }
break; break;

View File

@ -70,6 +70,7 @@ Widget::Widget(WidgetType type)
, m_bounds(0, 0, 0, 0) , m_bounds(0, 0, 0, 0)
, m_parent(nullptr) , m_parent(nullptr)
, m_sizeHint(nullptr) , m_sizeHint(nullptr)
, m_mnemonic(0)
, m_minSize(0, 0) , m_minSize(0, 0)
, m_maxSize(INT_MAX, INT_MAX) , m_maxSize(INT_MAX, INT_MAX)
, m_childSpacing(0) , m_childSpacing(0)
@ -1260,12 +1261,12 @@ bool Widget::offerCapture(ui::MouseMessage* mouseMsg, int widget_type)
return false; return false;
} }
bool Widget::hasFocus() bool Widget::hasFocus() const
{ {
return hasFlags(HAS_FOCUS); return hasFlags(HAS_FOCUS);
} }
bool Widget::hasMouse() bool Widget::hasMouse() const
{ {
return hasFlags(HAS_MOUSE); return hasFlags(HAS_MOUSE);
} }
@ -1275,24 +1276,43 @@ bool Widget::hasMouseOver()
return (this == pick(get_mouse_position())); return (this == pick(get_mouse_position()));
} }
bool Widget::hasCapture() bool Widget::hasCapture() const
{ {
return hasFlags(HAS_CAPTURE); return hasFlags(HAS_CAPTURE);
} }
int Widget::mnemonicChar() const void Widget::setMnemonic(int mnemonic)
{ {
if (hasText()) { m_mnemonic = mnemonic;
for (int c=0; m_text[c]; ++c)
if ((m_text[c] == '&') && (m_text[c+1] != '&'))
return std::tolower(m_text[c+1]);
}
return 0;
} }
bool Widget::mnemonicCharPressed(const KeyMessage* keyMsg) const void Widget::processMnemonicFromText(int escapeChar)
{ {
int chr = mnemonicChar(); std::string newText;
if (!m_text.empty())
newText.reserve(m_text.size());
for (base::utf8_const_iterator
it(m_text.begin()),
end(m_text.end()); it != end; ++it) {
if (*it == escapeChar) {
++it;
if (it == end) {
break; // Ill-formed string (it ends with escape character)
}
else if (*it != escapeChar) {
setMnemonic(*it);
}
}
newText.push_back(*it);
}
setText(newText);
}
bool Widget::isMnemonicPressed(const KeyMessage* keyMsg) const
{
int chr = std::tolower(mnemonic());
return return
((chr) && ((chr) &&
((chr == std::tolower(keyMsg->unicodeChar())) || ((chr == std::tolower(keyMsg->unicodeChar())) ||

View File

@ -339,10 +339,10 @@ namespace ui {
void captureMouse(); void captureMouse();
void releaseMouse(); void releaseMouse();
bool hasFocus(); bool hasFocus() const;
bool hasMouse(); bool hasMouse() const;
bool hasMouseOver(); bool hasMouseOver();
bool hasCapture(); bool hasCapture() const;
// Offer the capture to widgets of the given type. Returns true if // Offer the capture to widgets of the given type. Returns true if
// the capture was passed to other widget. // the capture was passed to other widget.
@ -350,10 +350,15 @@ namespace ui {
// Returns lower-case letter that represet the mnemonic of the widget // Returns lower-case letter that represet the mnemonic of the widget
// (the underscored character, i.e. the letter after & symbol). // (the underscored character, i.e. the letter after & symbol).
int mnemonicChar() const; int mnemonic() const { return m_mnemonic; }
void setMnemonic(int mnemonic);
// Assigns mnemonic from the character preceded by the given
// escapeChar ('&' by default).
void processMnemonicFromText(int escapeChar = '&');
// Returns true if the mnemonic character is pressed. // Returns true if the mnemonic character is pressed.
bool mnemonicCharPressed(const ui::KeyMessage* keyMsg) const; bool isMnemonicPressed(const ui::KeyMessage* keyMsg) const;
protected: protected:
// =============================================================== // ===============================================================
@ -399,6 +404,7 @@ namespace ui {
WidgetsList m_children; // Sub-widgets WidgetsList m_children; // Sub-widgets
Widget* m_parent; // Who is the parent? Widget* m_parent; // Who is the parent?
gfx::Size* m_sizeHint; gfx::Size* m_sizeHint;
int m_mnemonic; // Keyboard shortcut to access this widget like Alt+mnemonic
// Widget size limits // Widget size limits
gfx::Size m_minSize, m_maxSize; gfx::Size m_minSize, m_maxSize;