linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #04284
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2573: rework the tab icon cache to clean up unused icons
------------------------------------------------------------
revno: 2573
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Mon 2011-06-27 20:46:47 +0200
message:
rework the tab icon cache to clean up unused icons
modified:
dwt/include/dwt/widgets/Frame.h
dwt/include/dwt/widgets/TabView.h
dwt/src/widgets/TabView.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/Frame.h'
--- dwt/include/dwt/widgets/Frame.h 2011-04-19 20:04:13 +0000
+++ dwt/include/dwt/widgets/Frame.h 2011-06-27 18:46:47 +0000
@@ -155,12 +155,12 @@
inline void Frame::setSmallIcon(const IconPtr& icon) {
smallIcon = icon;
- sendMessage(WM_SETICON, ICON_SMALL, reinterpret_cast<LPARAM>(smallIcon->handle()));
+ sendMessage(WM_SETICON, ICON_SMALL, smallIcon ? reinterpret_cast<LPARAM>(smallIcon->handle()) : 0);
}
inline void Frame::setLargeIcon(const IconPtr& icon) {
largeIcon = icon;
- sendMessage(WM_SETICON, ICON_BIG, reinterpret_cast<LPARAM>(largeIcon->handle()));
+ sendMessage(WM_SETICON, ICON_BIG, largeIcon ? reinterpret_cast<LPARAM>(largeIcon->handle()) : 0);
}
inline Frame::Frame(Widget * parent, Dispatcher& dispatcher) :
=== modified file 'dwt/include/dwt/widgets/TabView.h'
--- dwt/include/dwt/widgets/TabView.h 2011-06-01 19:02:45 +0000
+++ dwt/include/dwt/widgets/TabView.h 2011-06-27 18:46:47 +0000
@@ -150,9 +150,12 @@
TabView* control; // for painting messages
ContainerPtr w;
tstring text;
+ IconPtr icon;
ContextMenuFunction handleContextMenu;
bool marked;
- TabInfo(TabView* control_, ContainerPtr w_) : control(control_), w(w_), handleContextMenu(0), marked(false) { }
+
+ TabInfo(TabView* control, ContainerPtr w, IconPtr icon) :
+ control(control), w(w), icon(icon), handleContextMenu(0), marked(false) { }
};
Theme theme;
@@ -176,8 +179,7 @@
typedef WindowList::iterator WindowIter;
WindowList viewOrder;
Rectangle clientSize;
- ImageListPtr imageList;
- std::vector<IconPtr> icons;
+ ImageListPtr icons;
int active;
ContainerPtr dragging;
tstring tipText;
@@ -208,10 +210,14 @@
tstring formatTitle(tstring title);
void layout();
+ /** @internal add an icon to the icon cache.
+ @param icon must be a valid icon.
+ @return the index of the icon in the icon cache. */
int addIcon(const IconPtr& icon);
+ int getImage(unsigned index);
+ void removeIcon(unsigned index);
void swapWidgets(ContainerPtr oldW, ContainerPtr newW);
- IconPtr getIcon(unsigned index) const;
void setText(unsigned idx, const tstring& text);
void redraw(unsigned index);
void draw(Canvas& canvas, unsigned index, Rectangle&& rect, bool isSelected);
@@ -231,8 +237,6 @@
// AspectSelection expectation implementation
static Message getSelectionChangedMessage();
- const ImageListPtr& getImageList() const;
-
int hitTest(const ScreenCoordinate& pt);
/// Get the area not used by the tabs
=== modified file 'dwt/src/widgets/TabView.cpp'
--- dwt/src/widgets/TabView.cpp 2011-06-01 19:02:45 +0000
+++ dwt/src/widgets/TabView.cpp 2011-06-27 18:46:47 +0000
@@ -126,9 +126,8 @@
setFont(font);
}
- imageList = new ImageList(Point(16, 16));
-
- TabCtrl_SetImageList(handle(), imageList->handle());
+ icons = new ImageList(Point(16, 16));
+ TabCtrl_SetImageList(handle(), icons->handle());
onSelectionChanged([this] { handleTabSelected(); });
onLeftMouseDown([this](const MouseEvent& me) { return handleLeftMouseDown(me); });
@@ -145,12 +144,10 @@
}
void TabView::add(ContainerPtr w, const IconPtr& icon) {
- int image = addIcon(icon);
-
- size_t tabs = size();
-
- TabInfo* ti = new TabInfo(this, w);
- TCITEM item = { TCIF_PARAM };
+ const size_t pos = size();
+
+ TabInfo* ti = new TabInfo(this, w, icon);
+ TCITEM item = { TCIF_PARAM };
item.lParam = reinterpret_cast<LPARAM>(ti);
if(!hasStyle(TCS_OWNERDRAWFIXED)) {
@@ -159,19 +156,19 @@
item.pszText = const_cast<LPTSTR>(ti->text.c_str());
}
- if(image != -1) {
+ if(icon) {
item.mask |= TCIF_IMAGE;
- item.iImage = image;
+ item.iImage = addIcon(icon);
}
- int newIdx = TabCtrl_InsertItem( handle(), tabs, &item );
+ int newIdx = TabCtrl_InsertItem(handle(), pos, &item);
if ( newIdx == - 1 ) {
throw Win32Exception("Error while trying to add page into Tab Sheet");
}
if(taskbar) {
addToTaskbar(w);
- if(image != -1) {
+ if(icon) {
setTaskbarIcon(w, icon);
}
}
@@ -184,7 +181,7 @@
} else {
swapWidgets(0, w);
}
- setActive(tabs);
+ setActive(pos);
}
layout();
@@ -198,7 +195,7 @@
}
void TabView::remove(ContainerPtr w) {
- int i = findTab(w);
+ auto i = findTab(w);
if(i == -1) {
return;
}
@@ -214,6 +211,8 @@
if(w == dragging)
dragging = 0;
+ removeIcon(i);
+
delete getTabInfo(i);
erase(i);
@@ -234,37 +233,29 @@
}
}
-IconPtr TabView::getIcon(unsigned index) const {
- TCITEM item = { TCIF_IMAGE };
- TabCtrl_GetItem(handle(), index, &item);
- if(item.iImage >= 0 && item.iImage < imageList->size())
- return imageList->getIcon(item.iImage);
- return IconPtr();
+IconPtr TabView::getIcon(ContainerPtr w) const {
+ auto ti = getTabInfo(w);
+ return ti ? ti->icon : 0;
}
void TabView::setIcon(ContainerPtr w, const IconPtr& icon) {
- int i = findTab(w);
- if(i != -1) {
- int image = addIcon(icon);
- if(image != -1) {
- TCITEM item = { TCIF_IMAGE };
- item.iImage = image;
- TabCtrl_SetItem(this->handle(), i, &item);
-
- if(taskbar) {
- setTaskbarIcon(w, icon);
- }
+ auto i = findTab(w);
+ auto ti = getTabInfo(i);
+ if(ti) {
+ removeIcon(i);
+
+ ti->icon = icon;
+
+ TCITEM item = { TCIF_IMAGE };
+ item.iImage = icon ? addIcon(icon) : -1;
+ TabCtrl_SetItem(handle(), i, &item);
+
+ if(taskbar) {
+ setTaskbarIcon(w, icon);
}
}
}
-IconPtr TabView::getIcon(ContainerPtr w) const {
- int i = findTab(w);
- if(i != -1)
- return getIcon(i);
- return IconPtr();
-}
-
void TabView::onTabContextMenu(ContainerPtr w, const ContextMenuFunction& f) {
TabInfo* ti = getTabInfo(w);
if(ti) {
@@ -368,8 +359,9 @@
TabView::TabInfo* TabView::getTabInfo(int i) const {
if(i != -1) {
TCITEM item = { TCIF_PARAM };
- TabCtrl_GetItem(handle(), i, &item);
- return reinterpret_cast<TabInfo*>(item.lParam);
+ if(TabCtrl_GetItem(handle(), i, &item)) {
+ return reinterpret_cast<TabInfo*>(item.lParam);
+ }
}
return 0;
}
@@ -468,21 +460,50 @@
}
int TabView::addIcon(const IconPtr& icon) {
- int image = -1;
- if(icon) {
- for(size_t i = 0; i < icons.size(); ++i) {
- if(*icon == *icons[i]) {
- image = i;
- break;
+ // see if one of the current tabs already has the icon; in that case, reuse it.
+ for(size_t i = 0, n = size(); i < n; ++i) {
+ auto ti = getTabInfo(i);
+ if(ti && ti->icon && *ti->icon == *icon) {
+ auto image = getImage(i);
+ if(image != -1) {
+ return image;
}
}
- if(image == -1) {
- image = icons.size();
- icons.push_back(icon);
- getImageList()->add(*icon);
- }
- }
- return image;
+ }
+
+ auto ret = icons->size();
+ icons->add(*icon);
+ return ret;
+}
+
+int TabView::getImage(unsigned index) {
+ TCITEM item = { TCIF_IMAGE };
+ if(TabCtrl_GetItem(handle(), index, &item)) {
+ return item.iImage;
+ }
+ return -1;
+}
+
+void TabView::removeIcon(unsigned index) {
+ auto t = getTabInfo(index);
+ if(!t || !t->icon)
+ return;
+
+ // make sure no other tab is still using this icon.
+ for(size_t i = 0, n = size(); i < n; ++i) {
+ if(i == index) {
+ continue;
+ }
+ auto ti = getTabInfo(i);
+ if(ti && ti->icon && *ti->icon == *t->icon) {
+ return;
+ }
+ }
+
+ auto image = getImage(index);
+ if(image != -1) {
+ TabCtrl_RemoveImage(handle(), image);
+ }
}
LRESULT TabView::handleToolTip(LPARAM lParam) {
@@ -724,13 +745,12 @@
rect.pos += margin;
rect.size -= margin + margin;
- IconPtr icon = getIcon(index);
- if(icon) {
- Point size = icon->getSize();
+ if(ti->icon) {
+ Point size = ti->icon->getSize();
Point pos = rect.pos;
if(size.y < rect.size.y)
pos.y += (rect.size.y - size.y) / 2; // center the icon vertically
- canvas.drawIcon(icon, Rectangle(pos, size));
+ canvas.drawIcon(ti->icon, Rectangle(pos, size));
size.x += margin.x;
rect.pos.x += size.x;
@@ -876,10 +896,6 @@
return rect;
}
-const ImageListPtr& TabView::getImageList() const {
- return imageList;
-}
-
int TabView::hitTest(const ScreenCoordinate& pt) {
TCHITTESTINFO tci = { ClientCoordinate(pt, this).getPoint() };
return TabCtrl_HitTest(handle(), &tci);