------------------------------------------------------------ revno: 2717 committer: poy <p...@123gen.com> branch nick: trunk timestamp: Tue 2011-12-13 22:15:23 +0100 message: add icons next to list-view group headers modified: dwt/include/dwt/widgets/Table.h dwt/src/widgets/Table.cpp win32/FavHubsFrame.cpp win32/StylesPage.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/widgets/Table.h' --- dwt/include/dwt/widgets/Table.h 2011-11-19 00:10:54 +0000 +++ dwt/include/dwt/widgets/Table.h 2011-12-13 21:15:23 +0000 @@ -281,17 +281,13 @@ */ void setColumnWidth( unsigned columnNo, int width ); - /** Enable group support (only for ComCtrl 6), and insert each given group. The group id used - will be the position of the group in the vector. */ + /** Enable group support, and insert each given group. The group id used as the "index" param + of the insert function will be the position of the group in the vector given here. + Once a table has been set into grouped mode, it cannot be switched back to non-grouped mode. */ void setGroups(const std::vector<tstring>& groups); - tstring getGroup(unsigned id) const; bool isGrouped() const { return grouped; } - /** tell dwt to take over painting of group headers in order to allow custom colors that match - the background. the theme will be respected. */ - void handleGroupDraw(); - /// Returns the checked state of the given row /** A list view can have checkboxes in each row, if the checkbox for the given * row is CHECKED this funtion returns true. @@ -397,19 +393,22 @@ /** normalImageList is the image list that contains the images * for the data grid icons in Icon View (big icons). */ - void setNormalImageList( ImageListPtr normalImageList ); + void setNormalImageList(ImageListPtr imageList); /// Set the small image list for the Data Grid. /** smallImageList is the image list that contains the images * for the data grid icons in Report, List & Small Icon Views. */ - void setSmallImageList( ImageListPtr smallImageList ); + void setSmallImageList(ImageListPtr imageList); /// Set the state image list for the Data Grid. /** stateImageList is the image list that contains the images * for the data grid icons states. */ - void setStateImageList( ImageListPtr stateImageList ); + void setStateImageList(ImageListPtr imageList); + + /** Set the image list to find icons from when adding groups. Only available on >= Visa. */ + void setGroupImageList(ImageListPtr imageList); /// Change the view for the Data Grid. /** The view parameter can be one of LVS_ICON, LVS_SMALLICON, LVS_LIST or @@ -486,6 +485,7 @@ ImageListPtr itsNormalImageList; ImageListPtr itsSmallImageList; ImageListPtr itsStateImageList; + ImageListPtr groupImageList; // If true the grid is in "read only mode" meaning that cell values cannot be edited. // A simpler version of defining a beenValidate always returning false @@ -501,6 +501,7 @@ static int CALLBACK compareFuncCallback( LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort ); void setIndex(LVITEM& item, int index) const; + void initGroupSupport(); void updateArrow(); #ifdef PORT_ME // Private validate function, this ones returns the "read only" property of the list === modified file 'dwt/src/widgets/Table.cpp' --- dwt/src/widgets/Table.cpp 2011-11-16 18:12:07 +0000 +++ dwt/src/widgets/Table.cpp 2011-12-13 21:15:23 +0000 @@ -45,6 +45,38 @@ const TCHAR Table::windowClass[] = WC_LISTVIEW; +/* the following dance adds Vista members to LVGROUP (notably iTitleImage to have group icons) +without requiring a global switch of WINVER / _WIN32_WINNT / etc to Vista values. */ +typedef LVGROUP legacyLVGROUP; +#if(_WIN32_WINNT < 0x600) +struct LVGROUP_ : LVGROUP { + LPWSTR pszSubtitle; + UINT cchSubtitle; + LPWSTR pszTask; + UINT cchTask; + LPWSTR pszDescriptionTop; + UINT cchDescriptionTop; + LPWSTR pszDescriptionBottom; + UINT cchDescriptionBottom; + int iTitleImage; + int iExtendedImage; + int iFirstItem; + UINT cItems; + LPWSTR pszSubsetTitle; + UINT cchSubsetTitle; + LVGROUP_(const LVGROUP& lvg) : LVGROUP(lvg) { } +}; +#define LVGROUP LVGROUP_ +#define LVGF_TITLEIMAGE 0x00001000 +#define ListView_SetGroupHeaderImageList(hwnd, himl) \ + (HIMAGELIST)SNDMSG((hwnd), LVM_SETIMAGELIST, (WPARAM)LVSIL_GROUPHEADER, (LPARAM)(HIMAGELIST)(himl)) +#endif + +namespace { legacyLVGROUP makeLVGROUP() { + legacyLVGROUP lvg = { util::win32::ensureVersion(util::win32::VISTA) ? sizeof(LVGROUP) : sizeof(legacyLVGROUP) }; + return lvg; +} } + Table::Seed::Seed() : BaseType::Seed(WS_CHILD | WS_TABSTOP | LVS_REPORT), font(0), @@ -294,12 +326,16 @@ } void Table::setGroups(const std::vector<tstring>& groups) { - grouped = ListView_EnableGroupView(handle(), TRUE) >= 0; - if(!grouped) - return; - - LVGROUP group = { sizeof(LVGROUP) }; - for(std::vector<tstring>::const_iterator i = groups.begin(), iend = groups.end(); i != iend; ++i) { + if(!grouped) { + grouped = ListView_EnableGroupView(handle(), TRUE) >= 0; + if(!grouped) + return; + + initGroupSupport(); + } + + LVGROUP group = makeLVGROUP(); + for(auto i = groups.cbegin(), iend = groups.cend(); i != iend; ++i) { if(i->empty()) { group.mask = LVGF_GROUPID; group.pszHeader = 0; @@ -307,6 +343,10 @@ group.mask = LVGF_GROUPID | LVGF_HEADER; group.pszHeader = const_cast<LPWSTR>(i->c_str()); } + if(groupImageList) { + group.mask |= LVGF_TITLEIMAGE; + group.iTitleImage = group.iGroupId; + } if(ListView_InsertGroup(handle(), -1, &group) == -1) { throw DWTException("Group insertion failed in Table::setGroups"); } @@ -316,22 +356,16 @@ grouped = true; } -tstring Table::getGroup(unsigned id) const { - if(grouped) { - LVGROUP group = { sizeof(LVGROUP), LVGF_HEADER }; - if(ListView_GetGroupInfo(handle(), id, &group) == static_cast<int>(id)) { - return tstring(group.pszHeader, group.cchHeader); - } - } - return tstring(); -} +void Table::initGroupSupport() { + /* fiddle with the painting of group headers to allow custom colors that match the background (the + theme will be respected). */ -void Table::handleGroupDraw() { theme.load(VSCLASS_LISTVIEW, this); onCustomDraw([this](NMLVCUSTOMDRAW& data) -> LRESULT { - if(!grouped || data.dwItemType != LVCDI_GROUP) + if(data.dwItemType != LVCDI_GROUP) return CDRF_DODEFAULT; + switch(data.nmcd.dwDrawStage) { case CDDS_PREPAINT: { @@ -346,20 +380,57 @@ /* 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). */ + FreeCanvas canvas(data.nmcd.hdc); + Brush brush(0xFFFFFF - bgColor); + Rectangle rect(data.rcText); if(!theme && util::win32::ensureVersion(util::win32::VISTA)) rect.size.y += 6; - FreeCanvas(data.nmcd.hdc).fill(rect, Brush(0xFFFFFF - bgColor)); + + LONG iconPos = 0; + + if(groupImageList) { + // don't invert the icon. let's find out where it is placed... + if(theme) { + auto temp = rect; + theme.formatRect(canvas, LVP_GROUPHEADER, LVGH_OPEN, temp); + iconPos = temp.left() - rect.left(); + } + if(iconPos <= 0) + iconPos = 10; // assume a 10px margin for unthemed visual styles + + rect.size.x = iconPos; + canvas.fill(rect, brush); + + rect.pos.x = rect.right() + 16; + rect.size.x = data.rcText.right - rect.pos.x; + } + + canvas.fill(rect, brush); // set a flag so we don't have to re-compare colors on CDDS_POSTPAINT. - data.nmcd.lItemlParam = 1; + data.nmcd.lItemlParam = std::max(iconPos, 0L) + 1; } break; } + case CDDS_POSTPAINT: { if(data.nmcd.lItemlParam) { - FreeCanvas(data.nmcd.hdc).invert(Region(Rectangle(data.rcText))); + LONG iconPos = data.nmcd.lItemlParam - 1; + + FreeCanvas canvas(data.nmcd.hdc); + Rectangle rect(data.rcText); + + if(iconPos > 0) { + rect.size.x = iconPos; + canvas.invert(Region(rect)); + + rect.pos.x = rect.right() + 16; + rect.size.x = data.rcText.right - rect.pos.x; + } + + canvas.invert(Region(rect)); } break; } @@ -415,6 +486,13 @@ ListView_SetImageList( handle(), imageList->getImageList(), LVSIL_STATE ); } +void Table::setGroupImageList(ImageListPtr imageList) { + if(util::win32::ensureVersion(util::win32::VISTA)) { + groupImageList = imageList; + ListView_SetGroupHeaderImageList(handle(), groupImageList->handle()); + } +} + void Table::setView( int view ) { if ( ( view & LVS_TYPEMASK ) != view ) { === modified file 'win32/FavHubsFrame.cpp' --- win32/FavHubsFrame.cpp 2011-11-16 18:12:07 +0000 +++ win32/FavHubsFrame.cpp 2011-12-13 21:15:23 +0000 @@ -80,7 +80,6 @@ hubs->onDblClicked([this] { handleDoubleClick(); }); hubs->onKeyDown([this](int c) { return handleKeyDown(c); }); hubs->onContextMenu([this](const dwt::ScreenCoordinate &sc) { return handleContextMenu(sc); }); - hubs->handleGroupDraw(); } { === modified file 'win32/StylesPage.cpp' --- win32/StylesPage.cpp 2011-12-13 17:16:36 +0000 +++ win32/StylesPage.cpp 2011-12-13 21:15:23 +0000 @@ -92,7 +92,12 @@ seed.style &= ~LVS_SHOWSELALWAYS; seed.style |= LVS_SINGLESEL | LVS_NOCOLUMNHEADER; table = cur->addChild(Table::Seed(seed)); - table->handleGroupDraw(); + + dwt::ImageListPtr images(new dwt::ImageList(dwt::Point(16, 16))); + images->add(*WinUtil::createIcon(IDI_DCPP, 16)); + images->add(*WinUtil::createIcon(IDI_NET_STATS, 16)); /// @todo better icon for the "transfers" group? + images->add(*WinUtil::createIcon(IDI_USERS, 16)); + table->setGroupImageList(images); } { @@ -418,7 +423,9 @@ void StylesPage::handleCustomTextColor() { auto data = table->getSelectedData(); data->customTextColor = customTextColor->getChecked(); - data->textColor = getTextColor(data); + if(data->customTextColor) { + data->textColor = getTextColor(data); + } update(data); handleSelectionChanged(); } @@ -435,7 +442,9 @@ void StylesPage::handleCustomBgColor() { auto data = table->getSelectedData(); data->customBgColor = customBgColor->getChecked(); - data->bgColor = getBgColor(data); + if(data->customBgColor) { + data->bgColor = getBgColor(data); + } update(data); handleSelectionChanged(); }
_______________________________________________ Mailing list: https://launchpad.net/~linuxdcpp-team Post to : linuxdcpp-team@lists.launchpad.net Unsubscribe : https://launchpad.net/~linuxdcpp-team More help : https://help.launchpad.net/ListHelp