summaryrefslogtreecommitdiff
path: root/plugins/NewStory/src/history_control.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/NewStory/src/history_control.cpp')
-rw-r--r--plugins/NewStory/src/history_control.cpp810
1 files changed, 405 insertions, 405 deletions
diff --git a/plugins/NewStory/src/history_control.cpp b/plugins/NewStory/src/history_control.cpp
index d7fb75cc37..da8dcecd5b 100644
--- a/plugins/NewStory/src/history_control.cpp
+++ b/plugins/NewStory/src/history_control.cpp
@@ -1,23 +1,7 @@
#include "stdafx.h"
-LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
-
HANDLE htuLog = 0;
-void InitNewstoryControl()
-{
- htuLog = MTextRegister("Newstory", MTEXT_FANCY_DEFAULT | MTEXT_SYSTEM_HICONS);
-
- WNDCLASS wndclass = {};
- wndclass.style = /*CS_HREDRAW | CS_VREDRAW | */CS_DBLCLKS | CS_GLOBALCLASS;
- wndclass.lpfnWndProc = NewstoryListWndProc;
- wndclass.cbWndExtra = sizeof(void *);
- wndclass.hInstance = g_plugin.getInst();
- wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wndclass.lpszClassName = _T(NEWSTORYLIST_CLASS);
- RegisterClass(&wndclass);
-}
-
/////////////////////////////////////////////////////////////////////////
// Control utilities, types and constants
@@ -25,11 +9,11 @@ struct NewstoryListData : public MZeroedObject
{
HistoryArray items;
- DWORD scrollTopItem; // topmost item
+ int scrollTopItem; // topmost item
int scrollTopPixel; // y coord of topmost item, this should be negative or zero
- DWORD caret;
+ int caret;
int cachedWindowHeight;
- DWORD cachedMaxTopItem; // the largest ID of top item to avoid empty space
+ int cachedMaxTopItem; // the largest ID of top item to avoid empty space
int cachedMaxTopPixel;
RECT rcLastPaint;
@@ -40,13 +24,6 @@ struct NewstoryListData : public MZeroedObject
#define AVERAGE_ITEM_HEIGHT 100
-//static HFONT CopyFont(HFONT hfnt)
-//{
-// LOGFONT lf;
-// GetObject(hfnt, sizeof(lf), &lf);
-// return CreateFontIndirect(&lf);
-//}
-
static void ScrollListBy(HWND hwnd, NewstoryListData *data, int scrollItems, int scrollPixels);
static void EnsureVisible(HWND hwnd, NewstoryListData *data, int item);
static void FixScrollPosition(HWND hwnd, NewstoryListData *data);
@@ -56,7 +33,6 @@ static void EndEditItem(HWND hwnd, NewstoryListData *data);
static int LayoutItem(HWND hwnd, HistoryArray *items, int index);
static int PaintItem(HDC hdc, HistoryArray *items, int index, int top, int width);
-
// Edit box
static WNDPROC OldEditWndProc;
static LRESULT CALLBACK HistoryEditWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -94,7 +70,378 @@ static LRESULT CALLBACK HistoryEditWndProc(HWND hwnd, UINT msg, WPARAM wParam, L
}
/////////////////////////////////////////////////////////////////////////
+// Utilities
+
+static void ScrollListBy(HWND hwnd, NewstoryListData *data, int scrollItems, int scrollPixels)
+{
+ if (scrollItems) {
+ data->scrollTopItem += scrollItems;
+ data->scrollTopPixel = 0;
+ }
+ else if (scrollPixels) {
+ data->scrollTopPixel += scrollPixels;
+ if (data->scrollTopPixel > 0) {
+ while ((data->scrollTopPixel > 0) && data->scrollTopItem) {
+ data->scrollTopItem--;
+ int itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem);
+ data->scrollTopPixel -= itemHeight;
+ }
+
+ if (data->scrollTopPixel > 0) {
+ data->scrollTopPixel = 0;
+ }
+ }
+ else if (data->scrollTopPixel < 0) {
+ int maxItem = data->items.getCount();
+ int itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem);
+ while ((-data->scrollTopPixel > itemHeight) && (data->scrollTopItem < maxItem)) {
+ data->scrollTopPixel += itemHeight;
+ data->scrollTopItem++;
+ itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem);
+ }
+ }
+ }
+
+ FixScrollPosition(hwnd, data);
+}
+
+static void EnsureVisible(HWND hwnd, NewstoryListData *data, int item)
+{
+ if (data->scrollTopItem >= item) {
+ data->scrollTopItem = item;
+ data->scrollTopPixel = 0;
+ }
+ else {
+ RECT rc; GetClientRect(hwnd, &rc);
+ int height = rc.bottom - rc.top;
+ int top = data->scrollTopPixel;
+ int idx = data->scrollTopItem;
+ int itemHeight = LayoutItem(hwnd, &data->items, idx);
+ bool found = false;
+ while (top < height) {
+ if (idx == item) {
+ itemHeight = LayoutItem(hwnd, &data->items, idx);
+ if (top + itemHeight > height)
+ ScrollListBy(hwnd, data, 0, height - top - itemHeight);
+ found = true;
+ break;
+ }
+ top += itemHeight;
+ idx++;
+ itemHeight = LayoutItem(hwnd, &data->items, idx);
+ }
+ if (!found) {
+ data->scrollTopItem = item;
+ data->scrollTopPixel = 0;
+ }
+ }
+ FixScrollPosition(hwnd, data);
+}
+
+static void FixScrollPosition(HWND hwnd, NewstoryListData *data)
+{
+ EndEditItem(hwnd, data);
+
+ RECT rc;
+ GetWindowRect(hwnd, &rc);
+ int windowHeight = rc.bottom - rc.top;
+
+ if (windowHeight != data->cachedWindowHeight) {
+ int maxTopItem = 0;
+ int tmp = 0;
+ for (maxTopItem = data->items.getCount(); (maxTopItem > 0) && (tmp < windowHeight); maxTopItem--)
+ tmp += LayoutItem(hwnd, &data->items, maxTopItem - 1);
+ data->cachedMaxTopItem = maxTopItem;
+ data->cachedWindowHeight = windowHeight;
+ data->cachedMaxTopPixel = (windowHeight < tmp) ? windowHeight - tmp : 0;
+ }
+
+ if (data->scrollTopItem < 0) {
+ data->scrollTopItem = 0;
+ }
+
+ if ((data->scrollTopItem > data->cachedMaxTopItem) ||
+ ((data->scrollTopItem == data->cachedMaxTopItem) && (data->scrollTopPixel < data->cachedMaxTopPixel))) {
+ data->scrollTopItem = data->cachedMaxTopItem;
+ data->scrollTopPixel = data->cachedMaxTopPixel;
+ }
+ RecalcScrollBar(hwnd, data);
+}
+
+static void RecalcScrollBar(HWND hwnd, NewstoryListData *data)
+{
+ SCROLLINFO si = { 0 };
+ RECT clRect;
+ GetClientRect(hwnd, &clRect);
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_ALL;
+ si.nMin = 0;
+ si.nMax = data->items.getCount() * AVERAGE_ITEM_HEIGHT;
+ si.nPage = clRect.bottom;
+ si.nPos = data->scrollTopItem * AVERAGE_ITEM_HEIGHT;
+ SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
+}
+
+static void BeginEditItem(HWND hwnd, NewstoryListData *data, int index)
+{
+ if (data->hwndEditBox)
+ EndEditItem(hwnd, data);
+
+ if (data->scrollTopItem > index)
+ return;
+
+ RECT rc; GetClientRect(hwnd, &rc);
+ int height = rc.bottom - rc.top;
+
+ int top = data->scrollTopPixel;
+ int idx = data->scrollTopItem;
+ int itemHeight = LayoutItem(hwnd, &data->items, idx);
+ while (top < height) {
+ if (idx == index) {
+ HistoryArray::ItemData *item = data->items.get(index, ELM_DATA);
+
+ int tpl;
+ int fontid;
+ int colorid;
+ switch (item->dbe.eventType) {
+ case EVENTTYPE_MESSAGE:
+ tpl = TPL_COPY_MESSAGE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG;
+ colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INMSG : COLOR_OUTMSG;
+ break;
+
+ case EVENTTYPE_FILE:
+ tpl = TPL_COPY_FILE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE;
+ colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INFILE : COLOR_OUTFILE;
+ break;
+
+ case EVENTTYPE_STATUSCHANGE:
+ tpl = TPL_COPY_SIGN;
+ fontid = FONT_STATUS;
+ colorid = COLOR_STATUS;
+ break;
+
+ case EVENTTYPE_AUTHREQUEST:
+ tpl = TPL_COPY_AUTH;
+ fontid = FONT_INOTHER;
+ colorid = COLOR_INOTHER;
+ break;
+
+ case EVENTTYPE_ADDED:
+ tpl = TPL_COPY_ADDED;
+ fontid = FONT_INOTHER;
+ colorid = COLOR_INOTHER;
+ break;
+
+ case EVENTTYPE_JABBER_PRESENCE:
+ tpl = TPL_COPY_PRESENCE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
+ colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
+ break;
+
+ default:
+ tpl = TPL_COPY_OTHER;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
+ colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
+ break;
+ }
+
+ ptrW text(TplFormatString(tpl, item->hContact, item));
+ data->hwndEditBox = CreateWindow(L"EDIT", text, WS_CHILD | WS_BORDER | ES_READONLY | ES_MULTILINE | ES_AUTOVSCROLL, 0, top, rc.right - rc.left, itemHeight, hwnd, NULL, g_plugin.getInst(), NULL);
+ OldEditWndProc = (WNDPROC)SetWindowLongPtr(data->hwndEditBox, GWLP_WNDPROC, (LONG_PTR)HistoryEditWndProc);
+ SendMessage(data->hwndEditBox, WM_SETFONT, (WPARAM)fonts[fontid].hfnt, 0);
+ SendMessage(data->hwndEditBox, EM_SETMARGINS, EC_RIGHTMARGIN, 100);
+ SendMessage(data->hwndEditBox, EM_SETSEL, 0, (LPARAM)(-1));
+ ShowWindow(data->hwndEditBox, SW_SHOW);
+ SetFocus(data->hwndEditBox);
+ break;
+ }
+ top += itemHeight;
+ idx++;
+ itemHeight = LayoutItem(hwnd, &data->items, idx);
+ }
+}
+
+static void EndEditItem(HWND, NewstoryListData *data)
+{
+ DestroyWindow(data->hwndEditBox);
+ data->hwndEditBox = 0;
+}
+
+static int LayoutItem(HWND hwnd, HistoryArray *items, int index)
+{
+ HDC hdc = GetDC(hwnd);
+ RECT rc; GetClientRect(hwnd, &rc);
+ int width = rc.right - rc.left;
+
+ HistoryArray::ItemData *item = items->get(index, ELM_DATA);
+ if (!item) return 0;
+
+ int tpl;
+ int fontid;
+ switch (item->dbe.eventType) {
+ case EVENTTYPE_MESSAGE:
+ tpl = TPL_MESSAGE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG;
+ break;
+
+ case EVENTTYPE_FILE:
+ tpl = TPL_FILE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE;
+ break;
+
+ case EVENTTYPE_STATUSCHANGE:
+ tpl = TPL_SIGN;
+ fontid = FONT_STATUS;
+ break;
+
+ case EVENTTYPE_AUTHREQUEST:
+ tpl = TPL_AUTH;
+ fontid = FONT_INOTHER;
+ break;
+
+ case EVENTTYPE_ADDED:
+ tpl = TPL_ADDED;
+ fontid = FONT_INOTHER;
+ break;
+
+ case EVENTTYPE_JABBER_PRESENCE:
+ tpl = TPL_PRESENCE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
+ break;
+
+ default:
+ tpl = TPL_OTHER;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
+ break;
+ }
+
+ HFONT hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt);
+ if (!item->data)
+ item->data = MTextCreateW(htuLog, ptrW(TplFormatString(tpl, item->hContact, item)));
+
+ SIZE sz;
+ sz.cx = width - 6;
+ MTextMeasure(hdc, &sz, (HANDLE)item->data);
+
+ SelectObject(hdc, hfnt);
+
+ ReleaseDC(hwnd, hdc);
+ return sz.cy + 5;
+}
+
+static int PaintItem(HDC hdc, HistoryArray *items, int index, int top, int width)
+{
+ if (!items) return 0;
+ HistoryArray::ItemData *item = items->get(index, ELM_DATA);
+
+ // LOGFONT lfText;
+ COLORREF clText, clBack, clLine;
+ int tpl;
+ int fontid;
+ int colorid;
+ switch (item->dbe.eventType) {
+ case EVENTTYPE_MESSAGE:
+ tpl = TPL_MESSAGE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG;
+ colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INMSG : COLOR_OUTMSG;
+ break;
+
+ case EVENTTYPE_FILE:
+ tpl = TPL_FILE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE;
+ colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INFILE : COLOR_OUTFILE;
+ break;
+
+ case EVENTTYPE_STATUSCHANGE:
+ tpl = TPL_SIGN;
+ fontid = FONT_STATUS;
+ colorid = COLOR_STATUS;
+ break;
+
+ case EVENTTYPE_AUTHREQUEST:
+ tpl = TPL_AUTH;
+ fontid = FONT_INOTHER;
+ colorid = COLOR_INOTHER;
+ break;
+
+ case EVENTTYPE_ADDED:
+ tpl = TPL_ADDED;
+ fontid = FONT_INOTHER;
+ colorid = COLOR_INOTHER;
+ break;
+
+ case EVENTTYPE_JABBER_PRESENCE:
+ tpl = TPL_PRESENCE;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
+ colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
+ break;
+
+ default:
+ tpl = TPL_OTHER;
+ fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
+ colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
+ break;
+ }
+ clText = fonts[fontid].cl;
+ if (item->flags & HIF_SELECTED) {
+ MTextSendMessage(0, item->data, EM_SETSEL, 0, -1);
+ clText = colors[COLOR_SELTEXT].cl;
+ clLine = GetSysColor(COLOR_HIGHLIGHTTEXT);
+ clBack = GetSysColor(COLOR_HIGHLIGHT);
+ }
+ else {
+ MTextSendMessage(0, item->data, EM_SETSEL, 0, 0);
+ clLine = colors[COLOR_SELECTED].cl;
+ clBack = colors[colorid].cl;
+ }
+
+ if (!item->data) {
+ wchar_t *buf = TplFormatString(tpl, item->hContact, item);
+ item->data = MTextCreateW(htuLog, buf);
+ mir_free(buf);
+ if (!item->data)
+ return 0;
+ }
+
+ SIZE sz;
+ sz.cx = width - 6;
+ HFONT hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt);
+ MTextMeasure(hdc, &sz, (HANDLE)item->data);
+ SelectObject(hdc, hfnt);
+ int height = sz.cy + 5;
+
+ RECT rc;
+ SetRect(&rc, 0, top, width, top + height);
+
+ HBRUSH hbr;
+ hbr = CreateSolidBrush(clBack);
+ FillRect(hdc, &rc, hbr);
+
+ SetTextColor(hdc, clText);
+ SetBkMode(hdc, TRANSPARENT);
+
+ POINT pos;
+ pos.x = 3;
+ pos.y = top + 2;
+ hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt);
+ MTextDisplay(hdc, pos, sz, (HANDLE)item->data);
+ SelectObject(hdc, hfnt);
+
+ DeleteObject(hbr);
+
+ HPEN hpn = (HPEN)SelectObject(hdc, CreatePen(PS_SOLID, 1, clLine));
+ MoveToEx(hdc, rc.left, rc.bottom - 1, 0);
+ LineTo(hdc, rc.right, rc.bottom - 1);
+ DeleteObject(SelectObject(hdc, hpn));
+
+ return height;
+}
+
+/////////////////////////////////////////////////////////////////////////
// WndProc
+
LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
NewstoryListData *data = (NewstoryListData *)GetWindowLongPtr(hwnd, 0);
@@ -114,7 +461,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
InvalidateRect(hwnd, 0, FALSE);
break;
- // History list control messages
+ // History list control messages
case NSM_GETCOUNT:
return data->items.getCount();
@@ -216,19 +563,14 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
}
case NSM_SETCARET:
- {
- if ((wParam >= 0) && (wParam < data->items.getCount())) {
- data->caret = wParam;
- if (lParam) {
- SendMessage(hwnd, NSM_ENSUREVISIBLE, data->caret, 0);
- }
- }
+ if ((wParam >= 0) && (wParam < data->items.getCount())) {
+ data->caret = wParam;
+ if (lParam)
+ SendMessage(hwnd, NSM_ENSUREVISIBLE, data->caret, 0);
}
case NSM_GETCARET:
- {
- return data->caret;
- }
+ return data->caret;
case NSM_FINDNEXT:
{
@@ -250,6 +592,19 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
return id;
}
+ case NSM_SEEKTIME:
+ {
+ int eventCount = data->items.getCount();
+ for (int i = 0; i < eventCount; i++) {
+ auto *item = data->items.get(i, ELM_NOTHING);
+ if (item->dbe.timestamp >= wParam) {
+ SendMessage(hwnd, NSM_SETCARET, i, TRUE);
+ break;
+ }
+ }
+ }
+ return TRUE;
+
case NSM_COPY:
{
CMStringW res;
@@ -462,7 +817,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
case WM_MOUSEWHEEL:
{
- DWORD s_scrollTopItem = data->scrollTopItem;
+ int s_scrollTopItem = data->scrollTopItem;
int s_scrollTopPixel = data->scrollTopPixel;
UINT scrollLines;
@@ -477,7 +832,7 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
case WM_VSCROLL:
{
- DWORD s_scrollTopItem = data->scrollTopItem;
+ int s_scrollTopItem = data->scrollTopItem;
int s_scrollTopPixel = data->scrollTopPixel;
switch (LOWORD(wParam)) {
@@ -540,371 +895,16 @@ LRESULT CALLBACK NewstoryListWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
return DefWindowProc(hwnd, msg, wParam, lParam);
}
-/////////////////////////////////////////////////////////////////////////
-// Utilities
-static void ScrollListBy(HWND hwnd, NewstoryListData *data, int scrollItems, int scrollPixels)
-{
- if (scrollItems) {
- data->scrollTopItem += scrollItems;
- data->scrollTopPixel = 0;
- }
- else if (scrollPixels) {
- data->scrollTopPixel += scrollPixels;
- if (data->scrollTopPixel > 0) {
- while ((data->scrollTopPixel > 0) && data->scrollTopItem) {
- data->scrollTopItem--;
- int itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem);
- data->scrollTopPixel -= itemHeight;
- }
-
- if (data->scrollTopPixel > 0) {
- data->scrollTopPixel = 0;
- }
- }
- else if (data->scrollTopPixel < 0) {
- int maxItem = data->items.getCount();
- int itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem);
- while ((-data->scrollTopPixel > itemHeight) && (data->scrollTopItem < maxItem)) {
- data->scrollTopPixel += itemHeight;
- data->scrollTopItem++;
- itemHeight = LayoutItem(hwnd, &data->items, data->scrollTopItem);
- }
- }
- }
-
- FixScrollPosition(hwnd, data);
-}
-
-static void EnsureVisible(HWND hwnd, NewstoryListData *data, int item)
-{
- if (data->scrollTopItem >= item) {
- data->scrollTopItem = item;
- data->scrollTopPixel = 0;
- }
- else {
- RECT rc; GetClientRect(hwnd, &rc);
- int height = rc.bottom - rc.top;
- int top = data->scrollTopPixel;
- int idx = data->scrollTopItem;
- int itemHeight = LayoutItem(hwnd, &data->items, idx);
- bool found = false;
- while (top < height) {
- if (idx == item) {
- itemHeight = LayoutItem(hwnd, &data->items, idx);
- if (top + itemHeight > height)
- ScrollListBy(hwnd, data, 0, height - top - itemHeight);
- found = true;
- break;
- }
- top += itemHeight;
- idx++;
- itemHeight = LayoutItem(hwnd, &data->items, idx);
- }
- if (!found) {
- data->scrollTopItem = item;
- data->scrollTopPixel = 0;
- }
- }
- FixScrollPosition(hwnd, data);
-}
-
-static void FixScrollPosition(HWND hwnd, NewstoryListData *data)
-{
- EndEditItem(hwnd, data);
-
- RECT rc;
- GetWindowRect(hwnd, &rc);
- int windowHeight = rc.bottom - rc.top;
-
- if (windowHeight != data->cachedWindowHeight) {
- int maxTopItem = 0;
- int tmp = 0;
- for (maxTopItem = data->items.getCount(); (maxTopItem > 0) && (tmp < windowHeight); maxTopItem--)
- tmp += LayoutItem(hwnd, &data->items, maxTopItem - 1);
- data->cachedMaxTopItem = maxTopItem;
- data->cachedWindowHeight = windowHeight;
- data->cachedMaxTopPixel = (windowHeight < tmp) ? windowHeight - tmp : 0;
- }
-
- if (data->scrollTopItem < 0) {
- data->scrollTopItem = 0;
- }
-
- if ((data->scrollTopItem > data->cachedMaxTopItem) ||
- ((data->scrollTopItem == data->cachedMaxTopItem) && (data->scrollTopPixel < data->cachedMaxTopPixel))) {
- data->scrollTopItem = data->cachedMaxTopItem;
- data->scrollTopPixel = data->cachedMaxTopPixel;
- }
- RecalcScrollBar(hwnd, data);
-}
-
-static void RecalcScrollBar(HWND hwnd, NewstoryListData *data)
-{
- SCROLLINFO si = { 0 };
- RECT clRect;
- GetClientRect(hwnd, &clRect);
- si.cbSize = sizeof(si);
- si.fMask = SIF_ALL;
- si.nMin = 0;
- si.nMax = data->items.getCount() * AVERAGE_ITEM_HEIGHT;
- si.nPage = clRect.bottom;
- si.nPos = data->scrollTopItem * AVERAGE_ITEM_HEIGHT;
- SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
-}
-
-static void BeginEditItem(HWND hwnd, NewstoryListData *data, int index)
-{
- if (data->hwndEditBox)
- EndEditItem(hwnd, data);
-
- if (data->scrollTopItem > index)
- return;
-
- RECT rc; GetClientRect(hwnd, &rc);
- int height = rc.bottom - rc.top;
-
- int top = data->scrollTopPixel;
- int idx = data->scrollTopItem;
- int itemHeight = LayoutItem(hwnd, &data->items, idx);
- while (top < height) {
- if (idx == index) {
- HistoryArray::ItemData *item = data->items.get(index, ELM_DATA);
-
- int tpl;
- int fontid;
- int colorid;
- switch (item->dbe.eventType) {
- case EVENTTYPE_MESSAGE:
- tpl = TPL_COPY_MESSAGE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG;
- colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INMSG : COLOR_OUTMSG;
- break;
-
- case EVENTTYPE_FILE:
- tpl = TPL_COPY_FILE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE;
- colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INFILE : COLOR_OUTFILE;
- break;
-
- case EVENTTYPE_STATUSCHANGE:
- tpl = TPL_COPY_SIGN;
- fontid = FONT_STATUS;
- colorid = COLOR_STATUS;
- break;
-
- case EVENTTYPE_AUTHREQUEST:
- tpl = TPL_COPY_AUTH;
- fontid = FONT_INOTHER;
- colorid = COLOR_INOTHER;
- break;
-
- case EVENTTYPE_ADDED:
- tpl = TPL_COPY_ADDED;
- fontid = FONT_INOTHER;
- colorid = COLOR_INOTHER;
- break;
-
- case EVENTTYPE_JABBER_PRESENCE:
- tpl = TPL_COPY_PRESENCE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
- colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
- break;
-
- default:
- tpl = TPL_COPY_OTHER;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
- colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
- break;
- }
-
- ptrW text(TplFormatString(tpl, item->hContact, item));
- data->hwndEditBox = CreateWindow(L"EDIT", text, WS_CHILD | WS_BORDER | ES_READONLY | ES_MULTILINE | ES_AUTOVSCROLL, 0, top, rc.right - rc.left, itemHeight, hwnd, NULL, g_plugin.getInst(), NULL);
- OldEditWndProc = (WNDPROC)SetWindowLongPtr(data->hwndEditBox, GWLP_WNDPROC, (LONG_PTR)HistoryEditWndProc);
- SendMessage(data->hwndEditBox, WM_SETFONT, (WPARAM)fonts[fontid].hfnt, 0);
- SendMessage(data->hwndEditBox, EM_SETMARGINS, EC_RIGHTMARGIN, 100);
- SendMessage(data->hwndEditBox, EM_SETSEL, 0, (LPARAM)(-1));
- ShowWindow(data->hwndEditBox, SW_SHOW);
- SetFocus(data->hwndEditBox);
- break;
- }
- top += itemHeight;
- idx++;
- itemHeight = LayoutItem(hwnd, &data->items, idx);
- }
-}
-
-static void EndEditItem(HWND, NewstoryListData *data)
-{
- DestroyWindow(data->hwndEditBox);
- data->hwndEditBox = 0;
-}
-
-static int LayoutItem(HWND hwnd, HistoryArray *items, int index)
-{
- HDC hdc = GetDC(hwnd);
- RECT rc; GetClientRect(hwnd, &rc);
- int width = rc.right - rc.left;
-
- HistoryArray::ItemData *item = items->get(index, ELM_DATA);
- if (!item) return 0;
-
- int tpl;
- int fontid;
- switch (item->dbe.eventType) {
- case EVENTTYPE_MESSAGE:
- tpl = TPL_MESSAGE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG;
- break;
-
- case EVENTTYPE_FILE:
- tpl = TPL_FILE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE;
- break;
-
- case EVENTTYPE_STATUSCHANGE:
- tpl = TPL_SIGN;
- fontid = FONT_STATUS;
- break;
-
- case EVENTTYPE_AUTHREQUEST:
- tpl = TPL_AUTH;
- fontid = FONT_INOTHER;
- break;
-
- case EVENTTYPE_ADDED:
- tpl = TPL_ADDED;
- fontid = FONT_INOTHER;
- break;
-
- case EVENTTYPE_JABBER_PRESENCE:
- tpl = TPL_PRESENCE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
- break;
-
- default:
- tpl = TPL_OTHER;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
- break;
- }
-
- HFONT hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt);
- if (!item->data)
- item->data = MTextCreateW(htuLog, ptrW(TplFormatString(tpl, item->hContact, item)));
-
- SIZE sz;
- sz.cx = width - 6;
- MTextMeasure(hdc, &sz, (HANDLE)item->data);
-
- SelectObject(hdc, hfnt);
-
- ReleaseDC(hwnd, hdc);
- return sz.cy + 5;
-}
-
-static int PaintItem(HDC hdc, HistoryArray *items, int index, int top, int width)
+void InitNewstoryControl()
{
- if (!items) return 0;
- HistoryArray::ItemData *item = items->get(index, ELM_DATA);
-
- // LOGFONT lfText;
- COLORREF clText, clBack, clLine;
- int tpl;
- int fontid;
- int colorid;
- switch (item->dbe.eventType) {
- case EVENTTYPE_MESSAGE:
- tpl = TPL_MESSAGE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INMSG : FONT_OUTMSG;
- colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INMSG : COLOR_OUTMSG;
- break;
-
- case EVENTTYPE_FILE:
- tpl = TPL_FILE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INFILE : FONT_OUTFILE;
- colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INFILE : COLOR_OUTFILE;
- break;
-
- case EVENTTYPE_STATUSCHANGE:
- tpl = TPL_SIGN;
- fontid = FONT_STATUS;
- colorid = COLOR_STATUS;
- break;
-
- case EVENTTYPE_AUTHREQUEST:
- tpl = TPL_AUTH;
- fontid = FONT_INOTHER;
- colorid = COLOR_INOTHER;
- break;
-
- case EVENTTYPE_ADDED:
- tpl = TPL_ADDED;
- fontid = FONT_INOTHER;
- colorid = COLOR_INOTHER;
- break;
-
- case EVENTTYPE_JABBER_PRESENCE:
- tpl = TPL_PRESENCE;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
- colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
- break;
-
- default:
- tpl = TPL_OTHER;
- fontid = !(item->dbe.flags & DBEF_SENT) ? FONT_INOTHER : FONT_OUTOTHER;
- colorid = !(item->dbe.flags & DBEF_SENT) ? COLOR_INOTHER : COLOR_OUTOTHER;
- break;
- }
- clText = fonts[fontid].cl;
- if (item->flags & HIF_SELECTED) {
- MTextSendMessage(0, item->data, EM_SETSEL, 0, -1);
- // clText = colors[COLOR_SELTEXT].cl;
- clLine = GetSysColor(COLOR_HIGHLIGHTTEXT);
- clBack = GetSysColor(COLOR_HIGHLIGHT); //colors[COLOR_SELECTED].cl;
- }
- else {
- MTextSendMessage(0, item->data, EM_SETSEL, 0, 0);
- clLine = colors[COLOR_SELECTED].cl;
- clBack = colors[colorid].cl;
- }
-
- if (!item->data) {
- wchar_t *buf = TplFormatString(tpl, item->hContact, item);
- item->data = MTextCreateW(htuLog, buf);
- mir_free(buf);
- if (!item->data)
- return 0;
- }
-
- SIZE sz;
- sz.cx = width - 6;
- HFONT hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt);
- MTextMeasure(hdc, &sz, (HANDLE)item->data);
- SelectObject(hdc, hfnt);
- int height = sz.cy + 5;
-
- RECT rc;
- SetRect(&rc, 0, top, width, top + height);
-
- HBRUSH hbr;
- hbr = CreateSolidBrush(clBack);
- FillRect(hdc, &rc, hbr);
-
- SetTextColor(hdc, clText);
- SetBkMode(hdc, TRANSPARENT);
-
- POINT pos;
- pos.x = 3;
- pos.y = top + 2;
- hfnt = (HFONT)SelectObject(hdc, fonts[fontid].hfnt);
- MTextDisplay(hdc, pos, sz, (HANDLE)item->data);
- SelectObject(hdc, hfnt);
-
- DeleteObject(hbr);
-
- HPEN hpn = (HPEN)SelectObject(hdc, CreatePen(PS_SOLID, 1, clLine));
- MoveToEx(hdc, rc.left, rc.bottom - 1, 0);
- LineTo(hdc, rc.right, rc.bottom - 1);
- DeleteObject(SelectObject(hdc, hpn));
+ htuLog = MTextRegister("Newstory", MTEXT_FANCY_DEFAULT | MTEXT_SYSTEM_HICONS);
- return height;
+ WNDCLASS wndclass = {};
+ wndclass.style = /*CS_HREDRAW | CS_VREDRAW | */CS_DBLCLKS | CS_GLOBALCLASS;
+ wndclass.lpfnWndProc = NewstoryListWndProc;
+ wndclass.cbWndExtra = sizeof(void *);
+ wndclass.hInstance = g_plugin.getInst();
+ wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wndclass.lpszClassName = _T(NEWSTORYLIST_CLASS);
+ RegisterClass(&wndclass);
}