linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #04208
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2546: draw sub-menu arrows; other misc painting changes
------------------------------------------------------------
revno: 2546
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Wed 2011-06-01 21:02:45 +0200
message:
draw sub-menu arrows; other misc painting changes
modified:
dwt/include/dwt/Theme.h
dwt/include/dwt/dwt_vsstyle.h
dwt/include/dwt/widgets/Menu.h
dwt/include/dwt/widgets/TabView.h
dwt/src/Theme.cpp
dwt/src/widgets/Control.cpp
dwt/src/widgets/Menu.cpp
dwt/src/widgets/TabView.cpp
dwt/src/widgets/Table.cpp
--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk
Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'dwt/include/dwt/Theme.h'
--- dwt/include/dwt/Theme.h 2011-05-28 16:06:47 +0000
+++ dwt/include/dwt/Theme.h 2011-06-01 19:02:45 +0000
@@ -63,6 +63,7 @@
* @param color text color, or NaC for the default theme color.
*/
void drawText(Canvas& canvas, int part, int state, const tstring& text, unsigned textFlags, const Rectangle& rect, COLORREF color = NaC);
+ void formatRect(Canvas& canvas, int part, int state, Rectangle& rect);
/// @param textFlags see the DrawText doc for possible values.
void formatTextRect(Canvas& canvas, int part, int state, const tstring& text, unsigned textFlags, Rectangle& rect);
/**
=== modified file 'dwt/include/dwt/dwt_vsstyle.h'
--- dwt/include/dwt/dwt_vsstyle.h 2011-05-27 18:05:51 +0000
+++ dwt/include/dwt/dwt_vsstyle.h 2011-06-01 19:02:45 +0000
@@ -47,6 +47,7 @@
#define MENU_POPUPCHECKBACKGROUND 12
#define MENU_POPUPITEM 14
#define MENU_POPUPSEPARATOR 15
+#define MENU_POPUPSUBMENU 16
#define MB_ACTIVE 1
#define MBI_NORMAL 1
#define MBI_HOT 2
@@ -58,6 +59,8 @@
#define MPI_HOT 2
#define MPI_DISABLED 3
#define MPI_DISABLEDHOT 4
+#define MSM_NORMAL 1
+#define MSM_DISABLED 2
#define VSCLASS_TAB L"TAB"
#define TABP_TABITEM 1
@@ -68,7 +71,6 @@
#define VSCLASS_WINDOW L"WINDOW"
#define WP_CAPTION 1
#define CS_ACTIVE 1
-#define CS_INACTIVE 2
#else
#include <vsstyle.h>
=== modified file 'dwt/include/dwt/widgets/Menu.h'
--- dwt/include/dwt/widgets/Menu.h 2011-05-31 17:39:38 +0000
+++ dwt/include/dwt/widgets/Menu.h 2011-06-01 19:02:45 +0000
@@ -255,9 +255,9 @@
virtual ~Menu();
template<typename T>
- static bool handlePainting(T t) {
- ItemDataWrapper* wrapper = reinterpret_cast<ItemDataWrapper*>(t->itemData);
- return wrapper->menu->handlePainting(t, wrapper);
+ static bool handlePainting(T& t) {
+ ItemDataWrapper* wrapper = reinterpret_cast<ItemDataWrapper*>(t.itemData);
+ return wrapper->menu->handlePainting(t, *wrapper);
}
protected:
@@ -308,25 +308,8 @@
{}
};
- /// Setting event handler for Draw Item Event
- /** The Draw Item Event will be raised when the menu needs to draw itself, if you
- * wish to truly be creative and be 100% in control you must handle this Event
- * and do the actualy drawing of the Menu yourself, but for most people it will
- * be enough to just manipulate the background colors etc of the MenuItemData
- * given to the menu in the appendItem function <br>
- * Note! <br>
- * If this event is handled you also MUST handle the Measure Item Event!!
- */
- bool handlePainting(LPDRAWITEMSTRUCT drawInfo, ItemDataWrapper* wrapper);
-
- /// Setting event handler for Measure Item Event
- /** The Measure Item Event is nessecary to handle if you want to draw the menu
- * yourself since it is inside this Event Handler you're telling the system how
- * much space you need to actually do the drawing <br>
- * Note! <br>
- * If this event is handled you also MUST handle the Draw Item Event!!
- */
- bool handlePainting(LPMEASUREITEMSTRUCT measureInfo, ItemDataWrapper* wrapper);
+ bool handlePainting(DRAWITEMSTRUCT& drawInfo, ItemDataWrapper& wrapper);
+ bool handlePainting(MEASUREITEMSTRUCT& measureInfo, ItemDataWrapper& wrapper);
LRESULT handleNCPaint(UINT message, WPARAM wParam, long menuWidth);
=== modified file 'dwt/include/dwt/widgets/TabView.h'
--- dwt/include/dwt/widgets/TabView.h 2011-03-30 20:13:51 +0000
+++ dwt/include/dwt/widgets/TabView.h 2011-06-01 19:02:45 +0000
@@ -131,11 +131,11 @@
using Widget::layout;
// tab controls only use WM_DRAWITEM
- static bool handlePainting(LPDRAWITEMSTRUCT t) {
- TabInfo* ti = reinterpret_cast<TabInfo*>(t->itemData);
+ static bool handlePainting(DRAWITEMSTRUCT& t) {
+ TabInfo* ti = reinterpret_cast<TabInfo*>(t.itemData);
return ti->control->handlePainting(t, ti);
}
- static bool handlePainting(LPMEASUREITEMSTRUCT) { return false; }
+ static bool handlePainting(MEASUREITEMSTRUCT) { return false; }
protected:
explicit TabView(Widget* parent);
@@ -202,7 +202,7 @@
bool handleXMouseUp(const MouseEvent& mouseEvent);
bool handleMouseMove(const MouseEvent& mouseEvent);
void handleMouseLeave();
- bool handlePainting(LPDRAWITEMSTRUCT info, TabInfo* ti);
+ bool handlePainting(DRAWITEMSTRUCT& info, TabInfo* ti);
void handlePainting(PaintCanvas& canvas);
tstring formatTitle(tstring title);
=== modified file 'dwt/src/Theme.cpp'
--- dwt/src/Theme.cpp 2011-05-28 16:06:47 +0000
+++ dwt/src/Theme.cpp 2011-06-01 19:02:45 +0000
@@ -141,19 +141,24 @@
}
}
-void Theme::formatTextRect(Canvas& canvas, int part, int state, const tstring& text, unsigned textFlags, Rectangle& rect) {
+void Theme::formatRect(Canvas& canvas, int part, int state, Rectangle& rect) {
::RECT rc = rect;
-
MARGINS margins = { 0 };
if(GetThemeMargins(theme, canvas.handle(), part, state, TMT_CONTENTMARGINS, &rc, &margins) == S_OK) {
rc.left += margins.cxLeftWidth; rc.right -= margins.cxRightWidth;
rc.top += margins.cyTopHeight; rc.bottom -= margins.cyBottomHeight;
+ rect = Rectangle(rc);
}
-
+}
+
+void Theme::formatTextRect(Canvas& canvas, int part, int state, const tstring& text, unsigned textFlags, Rectangle& rect) {
+ formatRect(canvas, part, state, rect);
+
+ ::RECT rc = rect;
::RECT rcOut;
- rect = Rectangle(
- (GetThemeTextExtent(theme, canvas.handle(), part, state, text.c_str(), text.size(), textFlags, &rc, &rcOut) == S_OK)
- ? rcOut : rc);
+ if(GetThemeTextExtent(theme, canvas.handle(), part, state, text.c_str(), text.size(), textFlags, &rc, &rcOut) == S_OK) {
+ rect = Rectangle(rcOut);
+ }
}
COLORREF Theme::getColor(int part, int state, int specifier) {
=== modified file 'dwt/src/widgets/Control.cpp'
--- dwt/src/widgets/Control.cpp 2011-01-02 17:12:02 +0000
+++ dwt/src/widgets/Control.cpp 2011-06-01 19:02:45 +0000
@@ -84,13 +84,13 @@
template<typename T>
static bool forwardPainting(const MSG& msg) {
- T t = reinterpret_cast<T>(msg.lParam);
+ T* t = reinterpret_cast<T*>(msg.lParam);
if(!t)
return false;
switch(t->CtlType) {
- case ODT_MENU: if(msg.wParam == 0) return Menu::handlePainting(t); break;
- case ODT_TAB: return TabView::handlePainting(t); break;
+ case ODT_MENU: if(msg.wParam == 0) return Menu::handlePainting(*t); break;
+ case ODT_TAB: return TabView::handlePainting(*t); break;
}
return false;
}
@@ -103,13 +103,13 @@
switch(msg.message)
{
case WM_DRAWITEM:
- if(forwardPainting<LPDRAWITEMSTRUCT>(msg)) {
+ if(forwardPainting<DRAWITEMSTRUCT>(msg)) {
retVal = TRUE;
return true;
}
break;
case WM_MEASUREITEM:
- if(forwardPainting<LPMEASUREITEMSTRUCT>(msg)) {
+ if(forwardPainting<MEASUREITEMSTRUCT>(msg)) {
retVal = TRUE;
return true;
}
=== modified file 'dwt/src/widgets/Menu.cpp'
--- dwt/src/widgets/Menu.cpp 2011-05-31 17:39:38 +0000
+++ dwt/src/widgets/Menu.cpp 2011-06-01 19:02:45 +0000
@@ -68,7 +68,7 @@
text = Color::predefined(COLOR_MENUTEXT);
gray = Color::predefined(COLOR_GRAYTEXT);
background = Color::predefined(COLOR_MENU);
- menuBar = Color::predefined(util::win32::ensureVersion(util::win32::VISTA) ? COLOR_MENUBAR : COLOR_3DFACE);
+ menuBar = Color::predefined(util::win32::ensureVersion(util::win32::SEVEN) ? COLOR_MENUBAR : COLOR_3DFACE);
stripBar = Color::darken(background, 0.06);
highlightBackground = Color::predefined(COLOR_HIGHLIGHT);
highlightText = Color::predefined(COLOR_HIGHLIGHTTEXT);
@@ -115,7 +115,10 @@
getParent()->addCallback(Message(WM_SYSCOLORCHANGE), Dispatchers::VoidVoid<0, false>([] { colors.reset(); }));
}
- theme.load(VSCLASS_MENU, getParent(), !popup);
+ if(!parentMenu) {
+ // only the root menu manages the theme.
+ theme.load(VSCLASS_MENU, getParent(), !popup);
+ }
}
}
@@ -183,6 +186,7 @@
const MSG msg = { getParent()->handle(), message, wParam, 0 };
getParent()->getDispatcher().chain(msg);
+ auto& theme = getRootMenu()->theme;
if(!theme)
return TRUE;
@@ -214,21 +218,19 @@
if(!::SetMenu(getParent()->handle(), handle()))
throw Win32Exception("SetMenu in Menu::setMenu failed");
- if(theme) {
- // get the width that current items will occupy
- long menuWidth = 0;
- const unsigned count = getCount();
- for(size_t i = 0; i < count; ++i) {
- ::RECT rect;
- ::GetMenuItemRect(getParent()->handle(), handle(), i, &rect);
- menuWidth += Rectangle(rect).width();
- }
-
- Control* control = static_cast<Control*>(getParent());
- control->onRaw([this, menuWidth](WPARAM wParam, LPARAM) { return handleNCPaint(WM_NCPAINT, wParam, menuWidth); }, Message(WM_NCPAINT));
- control->onRaw([this, menuWidth](WPARAM wParam, LPARAM) { return handleNCPaint(WM_NCACTIVATE, wParam, menuWidth); }, Message(WM_NCACTIVATE));
- ::DrawMenuBar(control->handle());
+ // get the width that current items will occupy
+ long menuWidth = 0;
+ const unsigned count = getCount();
+ for(size_t i = 0; i < count; ++i) {
+ ::RECT rect;
+ ::GetMenuItemRect(getParent()->handle(), handle(), i, &rect);
+ menuWidth += Rectangle(rect).width();
}
+
+ Control* control = static_cast<Control*>(getParent());
+ control->onRaw([this, menuWidth](WPARAM wParam, LPARAM) { return handleNCPaint(WM_NCPAINT, wParam, menuWidth); }, Message(WM_NCPAINT));
+ control->onRaw([this, menuWidth](WPARAM wParam, LPARAM) { return handleNCPaint(WM_NCACTIVATE, wParam, menuWidth); }, Message(WM_NCACTIVATE));
+ ::DrawMenuBar(control->handle());
}
Menu::ObjectType Menu::appendPopup(const tstring& text, const IconPtr& icon, bool subTitle) {
@@ -417,35 +419,30 @@
}
}
-bool Menu::handlePainting(LPDRAWITEMSTRUCT drawInfo, ItemDataWrapper* wrapper) {
- // init struct for menu item info
- MENUITEMINFO info = { sizeof(MENUITEMINFO), MIIM_CHECKMARKS | MIIM_FTYPE | MIIM_DATA | MIIM_STATE | MIIM_STRING };
-
- if(::GetMenuItemInfo(handle(), wrapper->index, TRUE, &info) == FALSE)
- throw Win32Exception ( "Couldn't get menu item info in Menu::handleDrawItem" );
-
- // check if item is owner drawn
- dwtassert( ( info.fType & MFT_OWNERDRAW ) != 0, _T( "Not an owner-drawn item in Menu::handleDrawItem" ) );
+bool Menu::handlePainting(DRAWITEMSTRUCT& drawInfo, ItemDataWrapper& wrapper) {
+ MENUITEMINFO info = { sizeof(MENUITEMINFO), MIIM_CHECKMARKS | MIIM_FTYPE | MIIM_DATA | MIIM_STATE | MIIM_STRING | MIIM_SUBMENU };
+ if(!::GetMenuItemInfo(handle(), wrapper.index, TRUE, &info))
+ throw Win32Exception("Couldn't get menu item info when drawing");
+
+ dwtassert((info.fType & MFT_OWNERDRAW) != 0, _T("Trying to draw a menu item that is not owner-drawn"));
// get state info
- bool isGrayed = ( drawInfo->itemState & ODS_GRAYED ) == ODS_GRAYED;
- bool isChecked = ( drawInfo->itemState & ODS_CHECKED ) == ODS_CHECKED;
- bool isDisabled = ( drawInfo->itemState & ODS_DISABLED ) == ODS_DISABLED;
- bool isSelected = ( drawInfo->itemState & ODS_SELECTED ) == ODS_SELECTED;
- bool isHighlighted = ( drawInfo->itemState & ODS_HOTLIGHT ) == ODS_HOTLIGHT;
+ bool isGrayed = ( drawInfo.itemState & ODS_GRAYED ) == ODS_GRAYED;
+ bool isChecked = ( drawInfo.itemState & ODS_CHECKED ) == ODS_CHECKED;
+ bool isDisabled = ( drawInfo.itemState & ODS_DISABLED ) == ODS_DISABLED;
+ bool isSelected = ( drawInfo.itemState & ODS_SELECTED ) == ODS_SELECTED;
+ bool isHighlighted = ( drawInfo.itemState & ODS_HOTLIGHT ) == ODS_HOTLIGHT;
// find item icon
/// @todo add support for HBITMAPs embedded in MENUITEMINFOs (hbmpChecked, hbmpUnchecked, hbmpItem)
- const IconPtr& icon = wrapper->icon;
+ const IconPtr& icon = wrapper.icon;
- // compute strip width
int stripWidth = iconSize.x + textIconGap;
- // prepare item rectangle
- Rectangle itemRectangle(drawInfo->rcItem);
+ Rectangle rect(drawInfo.rcItem);
- // setup buffered canvas
- BufferedCanvas<FreeCanvas> canvas(drawInfo->hDC, itemRectangle.left(), itemRectangle.top());
+ auto& theme = getRootMenu()->theme;
+ BufferedCanvas<FreeCanvas> canvas(drawInfo.hDC, rect.left(), rect.top());
// this will contain adjusted sidebar width
int sidebarWidth = 0;
@@ -465,10 +462,10 @@
sidebarWidth = canvas.getTextExtent(itsTitle).y;
// adjust item rectangle and item background
- itemRectangle.pos.x += sidebarWidth;
- itemRectangle.size.x -= sidebarWidth;
+ rect.pos.x += sidebarWidth;
+ rect.size.x -= sidebarWidth;
- if((drawInfo->itemAction & ODA_DRAWENTIRE) && !itsTitle.empty()) {
+ if((drawInfo.itemAction & ODA_DRAWENTIRE) && !itsTitle.empty()) {
// draw sidebar with menu title
// select title color
@@ -478,19 +475,19 @@
auto bkMode(canvas.setBkMode(true));
// get rect for sidebar
- RECT rect;
- ::GetClipBox( drawInfo->hDC, & rect );
- //rect.left -= borderGap;
+ ::RECT rc;
+ ::GetClipBox(drawInfo.hDC, &rc);
+ //rc.left -= borderGap;
// set title rectangle
- Rectangle textRectangle( 0, 0, sidebarWidth, rect.bottom - rect.top );
+ Rectangle textRect(0, 0, sidebarWidth, rc.bottom - rc.top);
// draw background
- canvas.fill(textRectangle, Brush(colors.stripBar));
+ canvas.fill(textRect, Brush(colors.stripBar));
// draw title
- textRectangle.pos.y += 10;
- canvas.drawText(itsTitle, textRectangle, DT_BOTTOM | DT_SINGLELINE);
+ textRect.pos.y += 10;
+ canvas.drawText(itsTitle, textRect, DT_BOTTOM | DT_SINGLELINE);
// clear
canvas.setTextColor( oldColor );
@@ -502,7 +499,7 @@
int part, state;
if(theme) {
int part_bg, state_bg;
- if(popup && !wrapper->isTitle) {
+ if(popup && !wrapper.isTitle) {
part = MENU_POPUPITEM;
state = (isDisabled || isGrayed) ? ((isSelected || isHighlighted) ? MPI_DISABLEDHOT : MPI_DISABLED) :
highlight ? MPI_HOT : MPI_NORMAL;
@@ -510,67 +507,66 @@
state_bg = 0;
} else {
part = MENU_BARITEM;
- state = wrapper->isTitle ? MBI_NORMAL : isSelected ? MBI_PUSHED : isHighlighted ? MBI_HOT : MBI_NORMAL;
+ state = wrapper.isTitle ? MBI_NORMAL : isSelected ? MBI_PUSHED : isHighlighted ? MBI_HOT : MBI_NORMAL;
part_bg = MENU_BARBACKGROUND;
state_bg = MB_ACTIVE;
}
if(theme.isBackgroundPartiallyTransparent(part, state)) {
- Rectangle rect = itemRectangle;
+ Rectangle bgRect = rect;
if(part_bg == MENU_BARBACKGROUND) {
// avoid non-drawn edges
- rect.pos.x -= 1;
- rect.size.x += 2;
+ bgRect.pos.x -= 1;
+ bgRect.size.x += 2;
}
- theme.drawBackground(canvas, part_bg, state_bg, rect, false);
+ theme.drawBackground(canvas, part_bg, state_bg, bgRect, false);
}
- theme.drawBackground(canvas, part, state, itemRectangle, false);
+ theme.drawBackground(canvas, part, state, rect, false);
} else {
- canvas.fill(itemRectangle, Brush(
+ canvas.fill(rect, Brush(
highlight ? colors.highlightBackground :
!popup ? colors.menuBar :
- wrapper->isTitle ? colors.stripBar :
+ wrapper.isTitle ? colors.stripBar :
colors.background));
}
- Rectangle stripRectangle(itemRectangle);
- stripRectangle.size.x = stripWidth;
+ Rectangle stripRect(rect);
+ stripRect.size.x = stripWidth;
- if(!(theme ? (isSelected || isHighlighted) : highlight) && popup && !wrapper->isTitle) {
+ if(!(theme ? (isSelected || isHighlighted) : highlight) && popup && !wrapper.isTitle) {
// paint the strip bar (on the left, where icons go)
- canvas.fill(stripRectangle, Brush(colors.stripBar));
+ canvas.fill(stripRect, Brush(colors.stripBar));
}
if(isChecked && theme) {
/// @todo we should also support bullets
- theme.drawBackground(canvas, MENU_POPUPCHECKBACKGROUND, icon ? MCB_BITMAP : MCB_NORMAL, stripRectangle, false);
+ theme.drawBackground(canvas, MENU_POPUPCHECKBACKGROUND, icon ? MCB_BITMAP : MCB_NORMAL, stripRect, false);
if(!icon)
- theme.drawBackground(canvas, MENU_POPUPCHECK, MC_CHECKMARKNORMAL, stripRectangle, false);
+ theme.drawBackground(canvas, MENU_POPUPCHECK, MC_CHECKMARKNORMAL, stripRect, false);
}
if(popup && info.fType & MFT_SEPARATOR) {
// separator
- Rectangle rectangle(itemRectangle);
- rectangle.pos.x += stripWidth + textIconGap;
+ Rectangle sepRect(rect);
+ sepRect.pos.x += stripWidth + textIconGap;
if(theme) {
Point pt;
if(theme.getPartSize(canvas, MENU_POPUPSEPARATOR, 0, pt)) {
- rectangle.size.y = std::min(rectangle.size.y, pt.y);
+ sepRect.size.y = std::min(sepRect.size.y, pt.y);
}
- theme.drawBackground(canvas, MENU_POPUPSEPARATOR, 0, rectangle, false);
+ theme.drawBackground(canvas, MENU_POPUPSEPARATOR, 0, sepRect, false);
} else {
// center in the item rectangle
- rectangle.pos.y += rectangle.height() / 2 - 1;
-
- // select color
- auto select(canvas.select(*PenPtr(new Pen(colors.gray))));
-
- // draw separator
- canvas.moveTo( rectangle.left(), rectangle.top() );
- canvas.lineTo( rectangle.width(), rectangle.top() );
+ sepRect.pos.y += sepRect.height() / 2 - 1;
+
+ // draw the separator as a line
+ Pen pen(colors.gray);
+ auto select(canvas.select(pen));
+ canvas.moveTo(sepRect.pos);
+ canvas.lineTo(sepRect.width(), sepRect.top());
}
} else {
@@ -579,7 +575,7 @@
// get item text
const int length = info.cch + 1;
std::vector< TCHAR > buffer( length );
- int count = ::GetMenuString(handle(), wrapper->index, &buffer[0], length, MF_BYPOSITION);
+ int count = ::GetMenuString(handle(), wrapper.index, &buffer[0], length, MF_BYPOSITION);
tstring itemText( buffer.begin(), buffer.begin() + count );
if(!itemText.empty()) {
@@ -597,123 +593,158 @@
// Select item font
auto select(canvas.select(*(
- wrapper->isTitle ? itsTitleFont :
- wrapper->isDefault ? boldFont :
+ wrapper.isTitle ? itsTitleFont :
+ wrapper.isDefault ? boldFont :
font)));
// compute text rectangle
- Rectangle textRectangle(itemRectangle);
+ Rectangle textRect = rect;
if(popup) {
- if(!wrapper->isTitle || icon) {
- textRectangle.pos.x += stripWidth + textIconGap;
- textRectangle.size.x -= stripWidth + textIconGap;
+ if(!wrapper.isTitle || icon) {
+ textRect.pos.x += stripWidth + textIconGap;
+ textRect.size.x -= stripWidth + textIconGap;
}
- textRectangle.size.x -= borderGap;
+ textRect.size.x -= borderGap;
}
unsigned drawTextFormat = DT_VCENTER | DT_SINGLELINE;
- if((drawInfo->itemState & ODS_NOACCEL) == ODS_NOACCEL)
+ if((drawInfo.itemState & ODS_NOACCEL) == ODS_NOACCEL)
drawTextFormat |= DT_HIDEPREFIX;
unsigned drawAccelFormat = drawTextFormat | DT_RIGHT;
- drawTextFormat |= (popup && !wrapper->isTitle) ? DT_LEFT : DT_CENTER;
+ drawTextFormat |= (popup && !wrapper.isTitle) ? DT_LEFT : DT_CENTER;
if(getRootMenu()->popup) // menus not in the menu bar may get cropped
drawTextFormat |= DT_WORD_ELLIPSIS;
if(theme) {
- theme.drawText(canvas, part, state, text, drawTextFormat, textRectangle);
+ theme.drawText(canvas, part, state, text, drawTextFormat, textRect);
if(!accelerator.empty())
- theme.drawText(canvas, part, state, accelerator, drawAccelFormat, textRectangle);
+ theme.drawText(canvas, part, state, accelerator, drawAccelFormat, textRect);
} else {
auto bkMode(canvas.setBkMode(true));
canvas.setTextColor(
isGrayed ? colors.gray :
- wrapper->isTitle ? colors.titleText :
+ wrapper.isTitle ? colors.titleText :
highlight ? colors.highlightText :
colors.text);
- canvas.drawText(text, textRectangle, drawTextFormat);
+ canvas.drawText(text, textRect, drawTextFormat);
if(!accelerator.empty())
- canvas.drawText(accelerator, textRectangle, drawAccelFormat);
+ canvas.drawText(accelerator, textRect, drawAccelFormat);
}
}
// set up icon rectangle
- Rectangle iconRectangle(itemRectangle.pos, iconSize);
- iconRectangle.pos.x += (stripWidth - iconSize.x) / 2;
- iconRectangle.pos.y += (itemRectangle.height() - iconSize.y) / 2;
+ Rectangle iconRect(rect.pos, iconSize);
+ iconRect.pos.x += (stripWidth - iconSize.x) / 2;
+ iconRect.pos.y += (rect.height() - iconSize.y) / 2;
if(isSelected && !isDisabled && !isGrayed) {
// selected and active item; adjust icon position
- iconRectangle.pos.x--;
- iconRectangle.pos.y--;
+ iconRect.pos.x--;
+ iconRect.pos.y--;
}
if(icon) {
// the item has an icon; draw it
- canvas.drawIcon(icon, iconRectangle);
+ canvas.drawIcon(icon, iconRect);
} else if(isChecked && !theme) {
// the item has no icon set but it is checked; draw the check mark or radio bullet
// background color
- canvas.fill(iconRectangle, Brush(highlight ? colors.highlightBackground : colors.stripBar));
-
- // create memory DC and set bitmap on it
- CompatibleCanvas canvas_compat(canvas.handle());
- BitmapPtr bitmap_compat(new Bitmap(::CreateCompatibleBitmap(canvas.handle(), iconSize.x, iconSize.y)));
- auto select_compat(canvas_compat.select(*bitmap_compat));
-
- // draw into memory
- RECT rc( Rectangle( 0, 0, iconSize.x, iconSize.y ) );
- ::DrawFrameControl(canvas_compat.handle(), & rc, DFC_MENU, ( info.fType & MFT_RADIOCHECK ) == 0 ? DFCS_MENUCHECK : DFCS_MENUBULLET );
+ canvas.fill(iconRect, Brush(highlight ? colors.highlightBackground : colors.stripBar));
+
+ CompatibleCanvas boxCanvas(canvas.handle());
+ Bitmap bitmap(::CreateCompatibleBitmap(canvas.handle(), iconSize.x, iconSize.y));
+ auto select(boxCanvas.select(bitmap));
+
+ ::RECT rc = Rectangle(iconSize);
+ ::DrawFrameControl(boxCanvas.handle(), &rc, DFC_MENU, (info.fType & MFT_RADIOCHECK) ? DFCS_MENUBULLET : DFCS_MENUCHECK);
const int adjustment = 2; // adjustment for mark to be in the center
- // bit - blast into out canvas
- ::BitBlt(canvas.handle(), iconRectangle.left() + adjustment, iconRectangle.top(),
- iconSize.x, iconSize.y, canvas_compat.handle(), 0, 0, SRCAND);
- }
-
- if(isChecked && !theme && popup && !wrapper->isTitle) {
- // must draw the surrounding rect after the check-mark
- stripRectangle.pos.x += 1;
- stripRectangle.pos.y += 1;
- stripRectangle.size.x -= 2;
- stripRectangle.size.y -= 2;
- auto select(canvas.select(*PenPtr(new Pen(colors.gray))));
- canvas.line(stripRectangle);
- }
+ ::BitBlt(canvas.handle(), iconRect.left() + adjustment, iconRect.top(), iconSize.x, iconSize.y,
+ boxCanvas.handle(), 0, 0, SRCAND);
+ }
+
+ if(isChecked && !theme && popup && !wrapper.isTitle) {
+ // draw the surrounding rect after the check-mark
+ stripRect.pos.x += 1;
+ stripRect.pos.y += 1;
+ stripRect.size.x -= 2;
+ stripRect.size.y -= 2;
+
+ Pen pen(colors.gray);
+ auto select(canvas.select(pen));
+ canvas.line(stripRect);
+ }
+
+ // draw the sub-menu arrow.
+ if(popup && info.hSubMenu) {
+ if(theme) {
+ int part_arrow = MENU_POPUPSUBMENU, state_arrow = (isDisabled || isGrayed) ? MSM_DISABLED : MSM_NORMAL;
+ Point pt(9, 9);
+ theme.getPartSize(canvas, part_arrow, state_arrow, pt);
+ Rectangle arrowRect = rect;
+ theme.formatRect(canvas, part_arrow, state_arrow, arrowRect);
+ theme.drawBackground(canvas, part_arrow, state_arrow,
+ Rectangle(arrowRect.pos + Point(arrowRect.size.x - pt.x, std::max(arrowRect.size.y - pt.y, 0L) / 2), pt), false);
+
+ } else {
+ Point pt(12, 12);
+ Rectangle arrowRect(rect.pos + Point(rect.size.x - pt.x - 3, std::max(rect.size.y - pt.y, 0L) / 2), pt);
+
+ CompatibleCanvas arrowCanvas(canvas.handle());
+ Bitmap bitmap(::CreateCompatibleBitmap(arrowCanvas.handle(), pt.x, pt.y));
+ auto select(arrowCanvas.select(bitmap));
+
+ ::RECT rc = Rectangle(pt);
+ ::DrawFrameControl(arrowCanvas.handle(), &rc, DFC_MENU, DFCS_MENUARROW);
+
+ // same color as the text color
+ Brush brush(isGrayed ? colors.gray :
+ wrapper.isTitle ? colors.titleText :
+ highlight ? colors.highlightText :
+ colors.text);
+ auto selectBrush(canvas.select(brush));
+
+ // DrawFrameControl returns a monochrome mask; use it with these ROPs to paint just the arrow.
+ ::MaskBlt(canvas.handle(), arrowRect.left(), arrowRect.top(), arrowRect.width(), arrowRect.height(),
+ arrowCanvas.handle(), 0, 0, bitmap.handle(), 0, 0, MAKEROP4(SRCAND, PATCOPY));
+ }
+ }
+ }
+
+ if(drawSidebar && (drawInfo.itemAction & ODA_DRAWENTIRE)) {
+ // adjust for sidebar
+ rect.pos.x -= sidebarWidth;
+ rect.size.x += sidebarWidth;
}
// blast buffer into screen
- if((drawInfo->itemAction & ODA_DRAWENTIRE) && drawSidebar) {
- // adjust for sidebar
- itemRectangle.pos.x -= sidebarWidth;
- itemRectangle.size.x += sidebarWidth;
- }
-
- canvas.blast(itemRectangle);
+ canvas.blast(rect);
+
+ // prevent Windows from painting on top of what we have painted (such as the sub-menu arrow).
+ ::ExcludeClipRect(drawInfo.hDC, rect.left(), rect.top(), rect.right(), rect.bottom());
+
return true;
}
-bool Menu::handlePainting(LPMEASUREITEMSTRUCT measureInfo, ItemDataWrapper* wrapper) {
- // this will contain item size
- UINT & itemWidth = measureInfo->itemWidth;
- UINT & itemHeight = measureInfo->itemHeight;
+bool Menu::handlePainting(MEASUREITEMSTRUCT& measureInfo, ItemDataWrapper& wrapper) {
+ // this will contain the calculated size
+ auto& itemWidth = measureInfo.itemWidth;
+ auto& itemHeight = measureInfo.itemHeight;
- // init struct for item info
MENUITEMINFO info = { sizeof(MENUITEMINFO), MIIM_FTYPE | MIIM_DATA | MIIM_CHECKMARKS | MIIM_STRING };
-
- // try to get item info
- if(::GetMenuItemInfo(handle(), wrapper->index, TRUE, &info) == FALSE)
- throw Win32Exception ( "Couldn't get item info in Menu::handleMeasureItem" );
-
- // check if item is owner drawn
- dwtassert( ( info.fType & MFT_OWNERDRAW ) != 0, _T( "Not an owner-drawn item in Menu::handleMeasureItem" ) );
+ if(!::GetMenuItemInfo(handle(), wrapper.index, TRUE, &info))
+ throw Win32Exception("Couldn't get menu item info when measuring");
+
+ dwtassert((info.fType & MFT_OWNERDRAW) != 0, _T("Trying to measure a menu item that is not owner-drawn"));
// check if separator
if(info.fType & MFT_SEPARATOR) {
+ auto& theme = getRootMenu()->theme;
if(theme) {
UpdateCanvas canvas(getParent());
Point pt;
@@ -729,17 +760,17 @@
return true;
}
- Point textSize = getTextSize(getText(wrapper->index),
- wrapper->isTitle ? itsTitleFont :
- wrapper->isDefault ? boldFont :
+ Point textSize = getTextSize(getText(wrapper.index),
+ wrapper.isTitle ? itsTitleFont :
+ wrapper.isDefault ? boldFont :
font);
- if(!wrapper->isTitle) // the title will adjust its hor size per others and add ellipsis if needed
+ if(!wrapper.isTitle) // the title will adjust its hor size per others and add ellipsis if needed
itemWidth = textSize.x;
itemHeight = textSize.y;
// find item icon
/// @todo add support for HBITMAPs embedded in MENUITEMINFOs (hbmpChecked, hbmpUnchecked, hbmpItem)
- const IconPtr& icon = wrapper->icon;
+ const IconPtr& icon = wrapper.icon;
// adjust width
if(popup || (!popup && icon)) {
=== modified file 'dwt/src/widgets/TabView.cpp'
--- dwt/src/widgets/TabView.cpp 2011-05-31 17:39:38 +0000
+++ dwt/src/widgets/TabView.cpp 2011-06-01 19:02:45 +0000
@@ -647,11 +647,11 @@
}
}
-bool TabView::handlePainting(LPDRAWITEMSTRUCT info, TabInfo* ti) {
- FreeCanvas canvas(info->hDC);
+bool TabView::handlePainting(DRAWITEMSTRUCT& info, TabInfo* ti) {
+ FreeCanvas canvas(info.hDC);
auto bkMode(canvas.setBkMode(true));
- Rectangle rect(info->rcItem);
+ Rectangle rect(info.rcItem);
if(theme) {
// remove some borders
rect.pos.x -= 1;
@@ -660,7 +660,7 @@
rect.size.y += 1;
}
- draw(canvas, info->itemID, std::move(rect), (info->itemState & ODS_SELECTED) == ODS_SELECTED);
+ draw(canvas, info.itemID, std::move(rect), (info.itemState & ODS_SELECTED) == ODS_SELECTED);
return true;
}
=== modified file 'dwt/src/widgets/Table.cpp'
--- dwt/src/widgets/Table.cpp 2011-05-07 18:52:09 +0000
+++ dwt/src/widgets/Table.cpp 2011-06-01 19:02:45 +0000
@@ -388,15 +388,16 @@
COLORREF color = theme ? theme.getColor(LVP_GROUPHEADER, LVGH_OPEN, TMT_HEADING1TEXTCOLOR) : NaC;
if(color == NaC)
color = 0; // assume black
- auto r = GetRValue(bgColor), g = GetGValue(bgColor), b = GetBValue(bgColor);
- if(abs(GetRValue(color) + GetGValue(color) + GetBValue(color) - r - g - b) < 300) {
+ if(abs(GetRValue(color) + GetGValue(color) + GetBValue(color)
+ - GetRValue(bgColor) - GetGValue(bgColor) - GetBValue(bgColor)) < 300)
+ {
/* the theme color and the bg color are too close to each other; start by
filling the canvas with an invert of the bg, then invert the whole canvas
after everything has been drawn (after CDDS_POSTPAINT). */
Rectangle rect(data.rcText);
if(!theme && util::win32::ensureVersion(util::win32::VISTA))
rect.size.y += 6;
- FreeCanvas(data.nmcd.hdc).fill(rect, Brush(RGB(255 - r, 255 - g, 255 - b)));
+ FreeCanvas(data.nmcd.hdc).fill(rect, Brush(0xFFFFFF - bgColor));
// set a flag so we don't have to re-compare colors on CDDS_POSTPAINT.
data.nmcd.lItemlParam = 1;