From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18901 invoked by alias); 5 Aug 2018 22:12:14 -0000 Mailing-List: contact cygwin-apps-help@cygwin.com; run by ezmlm Precedence: bulk Sender: cygwin-apps-owner@cygwin.com List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Mail-Followup-To: cygwin-apps@cygwin.com Received: (qmail 18775 invoked by uid 89); 5 Aug 2018 22:12:13 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-24.9 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=UD:pt X-HELO: rgout01.bt.lon5.cpcloud.co.uk Received: from rgout01.bt.lon5.cpcloud.co.uk (HELO rgout01.bt.lon5.cpcloud.co.uk) (65.20.0.178) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 05 Aug 2018 22:12:11 +0000 X-OWM-Source-IP: 86.151.121.200 (GB) X-OWM-Env-Sender: jonturney@btinternet.com X-VadeSecure-score: verdict=clean score=0/300, class=clean X-SNCR-VADESECURE: CLEAN Received: from localhost.localdomain (86.151.121.200) by rgout01.bt.lon5.cpcloud.co.uk (9.0.019.26-1) (authenticated as jonturney@btinternet.com) id 5B321EA003A9687B; Sun, 5 Aug 2018 23:12:11 +0100 From: Jon Turney To: cygwin-apps@cygwin.com Cc: Jon Turney Subject: [PATCH setup 13/13] Add ldesc tooltips to sdesc column of listview Date: Sun, 05 Aug 2018 22:12:00 -0000 Message-Id: <20180805220851.270212-14-jon.turney@dronecode.org.uk> In-Reply-To: <20180805220851.270212-1-jon.turney@dronecode.org.uk> References: <20180805220851.270212-1-jon.turney@dronecode.org.uk> X-SW-Source: 2018-08/txt/msg00020.txt.bz2 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