This is the mail archive of the
cygwin-apps
mailing list for the Cygwin project.
[PATCH setup 13/13] Add ldesc tooltips to sdesc column of listview
- From: Jon Turney <jon dot turney at dronecode dot org dot uk>
- To: cygwin-apps at cygwin dot com
- Cc: Jon Turney <jon dot turney at dronecode dot org dot uk>
- Date: Sun, 5 Aug 2018 23:08:51 +0100
- Subject: [PATCH setup 13/13] Add ldesc tooltips to sdesc column of listview
- References: <20180805220851.270212-1-jon.turney@dronecode.org.uk>
Listview's built-in tooltip support doesn't support subitems, so we have to
build our own
v2: Use string cache
---
ListView.cc | 94 +++++++++++++++++++++++++++++++++++++++++++++
ListView.h | 4 ++
PickCategoryLine.cc | 6 +++
PickCategoryLine.h | 1 +
PickPackageLine.cc | 11 ++++++
PickPackageLine.h | 1 +
6 files changed, 117 insertions(+)
diff --git a/ListView.cc b/ListView.cc
index b0351cd..e287270 100644
--- a/ListView.cc
+++ b/ListView.cc
@@ -67,6 +67,34 @@ ListView::init(HWND parent, int id, HeaderList headers)
// create an empty imagelist, used to reset the indent
hEmptyImgList = ImageList_Create(1, 1,
ILC_COLOR32, 2, 0);
+
+ // LVS_EX_INFOTIP/LVN_GETINFOTIP doesn't work for subitems, so we have to do
+ // our own tooltip handling
+ hWndTip = CreateWindowEx (0,
+ (LPCTSTR) TOOLTIPS_CLASS,
+ NULL,
+ WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ hWndParent,
+ (HMENU) 0,
+ GetModuleHandle(NULL),
+ NULL);
+ // must be topmost so that tooltips will display on top
+ SetWindowPos(hWndTip, HWND_TOPMOST,0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+
+ TOOLINFO ti;
+ memset ((void *)&ti, 0, sizeof(ti));
+ ti.cbSize = sizeof(ti);
+ ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
+ ti.hwnd = hWndParent;
+ ti.uId = (UINT_PTR)hWndListView;
+ ti.lpszText = LPSTR_TEXTCALLBACK; // use TTN_GETDISPINFO
+ SendMessage(hWndTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
+
+ // match long delay for tooltip to disappear used elsewhere (30s)
+ SendMessage(hWndTip, TTM_SETDELAYTIME, TTDT_AUTOPOP, (LPARAM) MAKELONG (30000, 0));
+ // match tip width used elsewhere
+ SendMessage(hWndTip, TTM_SETMAXTIPWIDTH, 0, 450);
}
void
@@ -429,6 +457,72 @@ ListView::OnNotify (NMHDR *pNmHdr, LRESULT *pResult)
}
}
}
+ break;
+
+ case LVN_HOTTRACK:
+ {
+ NMLISTVIEW *pNmListView = (NMLISTVIEW *)pNmHdr;
+ int iRow = pNmListView->iItem;
+ int iCol = pNmListView->iSubItem;
+#if DEBUG
+ Log (LOG_BABBLE) << "LVN_HOTTRACK " << iRow << " " << iCol << endLog;
+#endif
+ if (iRow < 0)
+ return true;
+
+ // if we've tracked off to a different cell
+ if ((iRow != iRow_track) || (iCol != iCol_track))
+ {
+#if DEBUG
+ Log (LOG_BABBLE) << "LVN_HOTTRACK changed cell" << endLog;
+#endif
+
+ // if the tooltip for previous cell is displayed, remove it
+ // restart the tooltip AUTOPOP timer for this cell
+ SendMessage(hWndTip, TTM_ACTIVATE, FALSE, 0);
+ SendMessage(hWndTip, TTM_ACTIVATE, TRUE, 0);
+
+ iRow_track = iRow;
+ iCol_track = iCol;
+ }
+
+ return true;
+ }
+ break;
+
+ case TTN_GETDISPINFO:
+ {
+ // convert mouse position to item/subitem
+ LVHITTESTINFO lvHitTestInfo;
+ lvHitTestInfo.flags = LVHT_ONITEM;
+ GetCursorPos(&lvHitTestInfo.pt);
+ ::ScreenToClient(hWndListView, &lvHitTestInfo.pt);
+ ListView_SubItemHitTest(hWndListView, &lvHitTestInfo);
+
+ int iRow = lvHitTestInfo.iItem;
+ int iCol = lvHitTestInfo.iSubItem;
+ if (iRow < 0)
+ return false;
+
+#if DEBUG
+ Log (LOG_BABBLE) << "TTN_GETDISPINFO " << iRow << " " << iCol << endLog;
+#endif
+
+ // get the tooltip text for that item/subitem
+ static StringCache tooltip;
+ tooltip = "";
+ if (contents)
+ tooltip = (*contents)[iRow]->get_tooltip(iCol);
+
+ // set the tooltip text
+ NMTTDISPINFO *pNmTTDispInfo = (NMTTDISPINFO *)pNmHdr;
+ pNmTTDispInfo->lpszText = tooltip;
+ pNmTTDispInfo->hinst = NULL;
+ pNmTTDispInfo->uFlags = 0;
+
+ return true;
+ }
+ break;
}
// We don't care.
diff --git a/ListView.h b/ListView.h
index 34d6267..b4fd1fd 100644
--- a/ListView.h
+++ b/ListView.h
@@ -33,6 +33,7 @@ class ListViewLine
virtual ~ListViewLine() {};
virtual const std::string get_text(int col) const = 0;
virtual State get_state() const = 0;
+ virtual const std::string get_tooltip(int col) const = 0;
virtual int get_indent() const = 0;
virtual ActionList *get_actions(int col) const = 0;
virtual int do_action(int col, int id) = 0;
@@ -76,6 +77,7 @@ class ListView
private:
HWND hWndParent;
HWND hWndListView;
+ HWND hWndTip;
HDC dc;
HIMAGELIST hImgList;
HIMAGELIST hEmptyImgList;
@@ -83,6 +85,8 @@ class ListView
ListViewContents *contents;
HeaderList headers;
const char *empty_list_text;
+ int iRow_track;
+ int iCol_track;
void initColumns(HeaderList hl);
void empty(void);
diff --git a/PickCategoryLine.cc b/PickCategoryLine.cc
index e206aee..1dbecf2 100644
--- a/PickCategoryLine.cc
+++ b/PickCategoryLine.cc
@@ -82,3 +82,9 @@ PickCategoryLine::get_indent() const
{
return indent;
}
+
+const std::string
+PickCategoryLine::get_tooltip(int col_num) const
+{
+ return "";
+}
diff --git a/PickCategoryLine.h b/PickCategoryLine.h
index a5daa8c..9c5e996 100644
--- a/PickCategoryLine.h
+++ b/PickCategoryLine.h
@@ -36,6 +36,7 @@ public:
const std::string get_text(int col) const;
State get_state() const;
+ const std::string get_tooltip(int col) const;
int get_indent() const;
ActionList *get_actions(int col) const;
int do_action(int col, int action_id);
diff --git a/PickPackageLine.cc b/PickPackageLine.cc
index a602c90..133720b 100644
--- a/PickPackageLine.cc
+++ b/PickPackageLine.cc
@@ -99,6 +99,17 @@ PickPackageLine::get_text(int col_num) const
return "unknown";
}
+const std::string
+PickPackageLine::get_tooltip(int col_num) const
+{
+ if (col_num == pkg_col)
+ {
+ return pkg.LDesc();
+ }
+
+ return "";
+}
+
int
PickPackageLine::do_action(int col_num, int action_id)
{
diff --git a/PickPackageLine.h b/PickPackageLine.h
index 53c389b..12c7636 100644
--- a/PickPackageLine.h
+++ b/PickPackageLine.h
@@ -32,6 +32,7 @@ public:
};
const std::string get_text(int col) const;
State get_state() const { return State::nothing; }
+ const std::string get_tooltip(int col) const;
int get_indent() const;
ActionList *get_actions(int col_num) const;
int do_action(int col, int action_id);
--
2.17.0