📄 feedview.cpp.svn-base
字号:
y += ht - ofsY;
ofsY = 0; // for the rest of the items, the ofsY is zero
//
memDC.SelectObject(saveBmp);
}
// delete the rest of the window
CRect rcRest(rc.left, y, rc.right, rc.bottom);
dc.FillSolidRect(rcRest, Appearance.ClrFeedViewBg);
}
else {
CString sText;
sText.LoadString(IDS_NO_ITEMS_TO_DISPLAY);
dc.FillSolidRect(rc, Appearance.ClrFeedViewBg);
rc.DeflateRect(SCALEX(8), SCALEY(8));
CFont *pFont = dc.SelectObject(&Appearance.BaseFont);
dc.SetTextColor(Appearance.ClrFeedViewFg);
dc.DrawText(sText, &rc, DT_CENTER | DT_TOP | DT_NOPREFIX | DT_WORDBREAK);
dc.SelectObject(pFont);
}
dc.RestoreDC(nSavedDC);
// Do not call CWnd::OnPaint() for painting messages
}
BOOL CFeedView::OnEraseBkgnd(CDC *pDC) {
return TRUE;
}
static DWORD WINAPI ScrollThread(LPVOID lpParam) {
CFeedView *view = (CFeedView *) lpParam;
int top = view->m_nViewTop;
while (view->m_bScrolling) {
int oldtop = view->m_nViewTop;
top += view->m_nScrollDelta;
view->m_nViewTop = top;
view->AdjustViewTop();
if (oldtop != view->m_nViewTop) {
view->ScrollWindowEx(0, oldtop - view->m_nViewTop, &view->m_rcScroll, &view->m_rcScroll,
NULL, NULL, SW_INVALIDATE);
view->m_oVScrollBar.SetScrollPos(view->m_nViewTop, TRUE);
view->UpdateWindow();
view->OnMouseMove(view->m_nOldKeys, view->m_ptOldCursorPos);
}
Sleep(SCROLL_SLEEP);
}
return 0;
}
void CFeedView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar *pScrollBar) {
int i = m_nViewTop;
switch (nSBCode) {
// FIXME
case SB_LINEDOWN: m_nViewTop += SCALEY(20); break;
case SB_LINEUP: m_nViewTop -= SCALEY(20); break;
case SB_PAGEDOWN: m_nViewTop += m_nClientHeight; break;
case SB_PAGEUP: m_nViewTop -= m_nClientHeight; break;
case SB_THUMBTRACK: {
SCROLLINFO si;
si.cbSize = sizeof(si);
si.fMask = SIF_TRACKPOS;
m_oVScrollBar.GetScrollInfo(&si);
m_nViewTop = si.nTrackPos;
}
}
AdjustViewTop();
ScrollWindowEx(0, i - m_nViewTop, &m_rcScroll, &m_rcScroll, NULL, NULL, SW_INVALIDATE);
m_oVScrollBar.SetScrollPos(m_nViewTop, TRUE);
UpdateWindow();
}
void CFeedView::UpdateScrollBars() {
LOG0(3, "CFeedView::UpdateScrollBars()");
BOOL visible = m_oVScrollBar.IsWindowVisible();
if (m_nClientHeight >= m_nTotalHeight) {
m_oVScrollBar.ShowScrollBar(FALSE);
}
else {
m_oVScrollBar.ShowScrollBar(TRUE);
SCROLLINFO sbi = { 0 };
sbi.cbSize = sizeof(sbi);
sbi.fMask = SIF_RANGE | SIF_POS | SIF_PAGE;
sbi.nMin = 0;
sbi.nMax = m_nTotalHeight - 1;
sbi.nPage = m_nClientHeight;
sbi.nPos = m_nViewTop;
m_oVScrollBar.SetScrollInfo(&sbi);
}
}
void CFeedView::OnSize(UINT nType, int cx, int cy) {
CWnd::OnSize(nType, cx, cy);
m_nClientHeight = cy;
m_nClientWidth = cx;
CRect rcClient;
GetClientRect(rcClient);
m_rcScroll = rcClient;
// place the scroll bar
CRect rcVert;
rcVert.top = -SCALEY(1);
rcVert.bottom = rcClient.bottom + SCALEY(1);
rcVert.right = rcClient.right + SCALEX(1);
rcVert.left = rcVert.right - GetSystemMetrics(SM_CXVSCROLL);
m_oVScrollBar.SetWindowPos(NULL, rcVert.left, rcVert.top, rcVert.Width(), rcVert.Height(), SWP_NOZORDER);
AdjustViewTop();
UpdateScrollBars();
Invalidate();
}
int CFeedView::ItemFromPoint(CPoint pt) {
if (m_oItemHeight.GetSize() > 0) {
int y = m_nViewTop + pt.y;
for (int i = 0; i < m_oItemHeight.GetSize(); i++)
if (m_oItemHeight[i] >= y)
return i;
return m_oItemHeight.GetSize();
}
else
return -1;
}
// Normal
void CFeedView::OnLButtonDownNormal(UINT nFlags, CPoint point) {
SetFocus();
int item = ItemFromPoint(point);
if (item >= 0 && item < m_oItems.GetSize()) {
CRect rcClient;
GetClientRect(rcClient);
if (point.x >= 0 && point.x <= SCALEY(20)) {
m_nFlagItem = item;
}
if (m_nSelectStart <= item && item <= m_nSelectEnd) {
m_nSelectFirst = item;
}
else {
// deselect
m_nSelectFirst = m_nSelectStart = m_nSelectEnd = item;
Invalidate(FALSE);
}
m_bSelecting = TRUE;
m_bClick = TRUE;
LastCursorPos = point;
// tap and hold
SHRGINFO shrg;
shrg.cbSize = sizeof(shrg);
shrg.hwndClient = GetSafeHwnd();
shrg.ptDown.x = LastCursorPos.x;
shrg.ptDown.y = LastCursorPos.y;
shrg.dwFlags = SHRG_NOTIFYPARENT | SHRG_RETURNCMD;
if (::SHRecognizeGesture(&shrg) == GN_CONTEXTMENU) {
Invalidate(FALSE);
CPoint pt = point;
ClientToScreen(&pt);
ContextMenu(&pt);
m_nFlagItem = -1;
m_bSelecting = FALSE;
}
else {
SetCapture();
Default();
}
}
else {
// tap out of items (deselect all)
m_nSelectStart = m_nSelectEnd = m_nSelectFirst = -1;
m_bSelecting = FALSE;
Invalidate(FALSE);
}
}
void CFeedView::OnMouseMoveNormal(UINT nFlags, CPoint pt) {
// Scrolling
if (m_nTotalHeight > m_nClientHeight && GetCapture() == this) {
int delta = 0;
if (pt.y < 0) {
delta = ((pt.y / SCALEY(SCROLL_SPEED)) - SCALEY(1));
pt.y = 0;
}
else if (pt.y >= m_nClientHeight) {
delta = (((pt.y - m_nClientHeight) / SCALEY(SCROLL_SPEED)) + SCALEY(1));
pt.y = m_nClientHeight - SCALEY(1);
}
if (delta) {
if (delta > SCALEY(SCROLL_MAXSPEED))
delta = SCALEY(SCROLL_MAXSPEED);
else if (delta < -SCALEY(SCROLL_MAXSPEED))
delta = -SCALEY(SCROLL_MAXSPEED);
m_nScrollDelta = delta;
if (!m_bScrolling) {
m_bScrolling = TRUE;
CloseHandle(CreateThread(NULL, 0, ScrollThread, (LPVOID) this, 0, NULL));
}
}
else
m_bScrolling = FALSE;
}
if (m_bSelecting) {
int item = ItemFromPoint(pt);
if (item < 0) item = 0;
if (item >= m_oItems.GetSize()) item = m_oItems.GetSize() - 1;
if (item <= m_nSelectFirst) {
m_nSelectStart = item;
m_nSelectEnd = m_nSelectFirst;
}
if (item >= m_nSelectFirst) {
m_nSelectStart = m_nSelectFirst;
m_nSelectEnd = item;
}
Invalidate(FALSE);
if (abs(pt.x - LastCursorPos.x) > SCALEX(3) || abs(pt.y - LastCursorPos.y) > SCALEX(3))
m_bClick = FALSE;
}
m_nOldKeys = nFlags;
m_ptOldCursorPos = pt;
}
void CFeedView::OnLButtonUpNormal(UINT nFlags, CPoint point) {
ReleaseCapture();
int item = ItemFromPoint(point);
if (item >= 0 && item < m_oItems.GetSize()) {
if (item == m_nFlagItem && point.x >= 0 && point.x <= SCALEY(20)) {
if (GetItem(item)->IsFlagged())
UnflagItem(item);
else
FlagItem(item);
m_nSelectFirst = item;
m_nSelectStart = m_nSelectEnd = item;
Invalidate(FALSE);
}
else if (m_bSelecting) {
if (item == m_nSelectFirst && m_bClick) {
OpenItem(item);
Invalidate(FALSE);
}
}
}
m_bScrolling = FALSE;
m_bSelecting = FALSE;
}
// TOUCH
void CFeedView::OnLButtonDownTouch(UINT nFlags, CPoint point) {
int item = ItemFromPoint(point);
if (item >= 0 && item < m_oItems.GetSize()) {
CRect rcClient;
GetClientRect(rcClient);
if (point.x >= 0 && point.x <= SCALEY(20)) {
m_nFlagItem = item;
}
m_bClick = TRUE;
LastCursorPos = point;
// tap and hold
SHRGINFO shrg;
shrg.cbSize = sizeof(shrg);
shrg.hwndClient = GetSafeHwnd();
shrg.ptDown.x = LastCursorPos.x;
shrg.ptDown.y = LastCursorPos.y;
shrg.dwFlags = SHRG_NOTIFYPARENT | SHRG_RETURNCMD;
if (::SHRecognizeGesture(&shrg) == GN_CONTEXTMENU) {
InvalidateItem(m_nSelectFirst, FALSE);
m_nSelectStart = m_nSelectEnd = m_nSelectFirst = item;
InvalidateItem(item, FALSE);
CPoint pt = point;
ClientToScreen(&pt);
ContextMenu(&pt);
m_nFlagItem = -1;
m_bSelecting = FALSE;
}
else {
SetCapture();
Default();
}
}
else {
// tap out of items (deselect all)
m_nSelectStart = m_nSelectEnd = m_nSelectFirst = -1;
m_bSelecting = FALSE;
Invalidate(FALSE);
}
}
void CFeedView::OnMouseMoveTouch(UINT nFlags, CPoint pt) {
if (abs(pt.x - LastCursorPos.x) > SCALEX(3) || abs(pt.y - LastCursorPos.y) > SCALEX(3))
m_bClick = FALSE;
// Scrolling
if (m_nTotalHeight > m_nClientHeight && GetCapture() == this) {
m_bScrolling = TRUE;
int delta = LastCursorPos.y - pt.y;
int top = m_nViewTop;
m_nViewTop += delta;
AdjustViewTop();
ScrollWindowEx(0, top - m_nViewTop, &m_rcScroll, &m_rcScroll, NULL, NULL, SW_INVALIDATE);
m_oVScrollBar.SetScrollPos(m_nViewTop, TRUE);
UpdateWindow();
LastCursorPos = pt;
}
}
void CFeedView::OnLButtonUpTouch(UINT nFlags, CPoint point) {
ReleaseCapture();
int item = ItemFromPoint(point);
if (item >= 0 && item < m_oItems.GetSize()) {
if (m_bClick) {
if (m_nFlagItem == item && point.x >= 0 && point.x <= SCALEY(20)) {
if (GetItem(item)->IsFlagged())
UnflagItem(item);
else
FlagItem(item);
InvalidateItem(m_nSelectFirst, FALSE);
m_nSelectFirst = item;
m_nSelectStart = m_nSelectEnd = item;
InvalidateItem(item, FALSE);
}
else if (m_bClick) {
InvalidateItem(m_nSelectFirst, FALSE);
m_nSelectFirst = item;
m_nSelectStart = m_nSelectEnd = item;
InvalidateItem(item, FALSE);
OpenItem(item);
}
}
else {
}
}
m_bClick = FALSE;
m_bScrolling = FALSE;
m_bSelecting = FALSE;
}
void CFeedView::OnLButtonDown(UINT nFlags, CPoint point) {
switch (Config.NavigationType) {
case NAVIGATION_NORMAL: OnLButtonDownNormal(nFlags, point); break;
default:
case NAVIGATION_TOUCH: OnLButtonDownTouch(nFlags, point); break;
}
}
void CFeedView::OnMouseMove(UINT nFlags, CPoint pt) {
switch (Config.NavigationType) {
case NAVIGATION_NORMAL: OnMouseMoveNormal(nFlags, pt); break;
default:
case NAVIGATION_TOUCH: OnMouseMoveTouch(nFlags, pt); break;
}
}
void CFeedView::OnLButtonUp(UINT nFlags, CPoint point) {
switch (Config.NavigationType) {
case NAVIGATION_NORMAL: OnLButtonUpNormal(nFlags, point); break;
default:
case NAVIGATION_TOUCH: OnLButtonUpTouch(nFlags, point); break;
}
}
// keys
void CFeedView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
LOG3(5, "CFeedView::OnKeyDown(%d, %d, %d)", nChar, nRepCnt, nFlags);
switch (nChar) {
case VK_UP:
MoveToPrevItem();
break;
case VK_DOWN:
MoveToNextItem();
break;
case VK_LEFT:
if (SiteItem->Type != CSiteItem::VFolder) {
int oldSiteIdx = Config.ActSiteIdx;
MoveToPrevChannel();
CMainFrame *frame = (CMainFrame *) AfxGetMainWnd();
frame->AddSiteToSave(oldSiteIdx);
frame->PreloadSite(Config.ActSiteIdx);
}
break;
case VK_RIGHT:
if (SiteItem->Type != CSiteItem::VFolder) {
int oldSiteIdx = Config.ActSiteIdx;
MoveToNextChannel();
CMainFrame *frame = (CMainFrame *) AfxGetMainWnd();
frame->AddSiteToSave(oldSiteIdx);
frame->PreloadSite(Config.ActSiteIdx);
}
break;
case VK_RETURN:
if (!(nFlags & 0x4000)) {
m_bOpenCtxMenu = FALSE;
SetTimer(CtxMenuTimer, TIMER_KEY_CTX_MENU, NULL);
}
break;
default:
break;
}
CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}
void CFeedView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) {
LOG3(5, "CFeedView::OnKeyUp(%d, %d, %d)", nChar, nRepCnt, nFlags);
switch (nChar) {
case VK_RETURN:
KillTimer(CtxMenuTimer);
if (m_bOpenCtxMenu) {
m_bOpenCtxMenu = FALSE;
if (m_oItems.GetSize() > 0 && m_nSelectFirst >= 0) {
int y;
if (m_nSelectFirst > 0) y = (m_oItemHeight[m_nSelectFirst] + m_oItemHeight[m_nSelectFirst - 1]) / 2;
else y = m_oItemHeight[m_nSelectFirst] / 2;
y -= m_nViewTop;
CPoint pt(m_nClientWidth / 2, y);
ClientToScreen(&pt);
ContextMenu(&pt);
}
else
CWnd::OnKeyUp(nChar, nRepCnt, nFlags);
}
else {
if (m_oItems.GetSize() > 0 && m_nSelectFirst >= 0)
OpenItem(m_nSelectFirst);
CWnd::OnKeyUp(nChar, nRepCnt, nFlags);
}
break;
case VK_APPS: {
CPoint pt;
int y;
if (m_nSelectFirst > 0) y = (m_oItemHeight[m_nSelectFirst] + m_oItemHeight[m_nSelectFirst - 1]) / 2;
else y = m_oItemHeight[m_nSelectFirst] / 2;
y -= m_nViewTop;
pt.x = m_nClientWidth / 2;
pt.y = y;
ClientToScreen(&pt);
ContextMenu(&pt);
} break;
default:
CWnd::OnKeyUp(nChar, nRepCnt, nFlags);
break;
}
}
void CFeedView::ContextMenu(CPoint *pt) {
LOG0(5, "CFeedView::ContextMenu()");
if (m_nSelectFirst != -1) {
CMenu popup;
popup.CreatePopupMenu();
AppendMenuFromResource(&popup, IDR_OPEN);
popup.AppendMenu(MF_SEPARATOR);
AppendMenuFromResource(&popup, IDR_FEEDITEM);
AppendMenuFromResource(&popup, IDR_CACHE);
AppendMenuFromResource(&popup, IDR_ENCLOSURES);
AppendMenuFromResource(&popup, IDR_COPY_URL);
AppendMenuFromResource(&popup, IDR_SEND_BY_EMAIL);
popup.AppendMenu(MF_SEPARATOR);
AppendMenuFromResource(&popup, IDR_ITEM_OPER);
// track popup menu
popup.TrackPopupMenu(TPM_TOPALIGN | TPM_LEFTALIGN, pt->x, pt->y, AfxGetMainWnd());
}
}
void CFeedView::OnTimer(UINT nIDEvent) {
LOG0(5, "CFeedView::OnTimer()");
if (nIDEvent == CtxMenuTimer) {
m_bOpenCtxMenu = TRUE;
KillTimer(CtxMenuTimer);
}
CWnd::OnTimer(nIDEvent);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -