296 lines
8.7 KiB
C++
296 lines
8.7 KiB
C++
|
#include "main.h"
|
||
|
#include <windowsx.h>
|
||
|
#include "config.h"
|
||
|
#include "../winamp/wa_dlg.h"
|
||
|
|
||
|
static int m_column_resize=0; //0=normal, 1=selected item only, 2=proportional
|
||
|
|
||
|
|
||
|
static int m_origsizes[32], m_origwidth;
|
||
|
static float m_origperc[32];
|
||
|
|
||
|
static void columnTrackStart(HWND hwnd, int item)
|
||
|
{
|
||
|
int l=Header_GetItemCount(hwnd);
|
||
|
m_origwidth=0;
|
||
|
int i;
|
||
|
for(i=item+1;i<l;i++) {
|
||
|
HD_ITEM hi;
|
||
|
hi.mask = HDI_WIDTH;
|
||
|
Header_GetItem(hwnd, i, &hi);
|
||
|
m_origwidth+=hi.cxy;
|
||
|
}
|
||
|
for(i=item;i<l;i++) {
|
||
|
if(i==-1) continue;
|
||
|
HD_ITEM hi;
|
||
|
hi.mask = HDI_WIDTH;
|
||
|
Header_GetItem(hwnd, i, &hi);
|
||
|
m_origsizes[i]=hi.cxy;
|
||
|
if(m_origwidth==0)
|
||
|
m_origperc[i]=0;
|
||
|
else
|
||
|
m_origperc[i]=(float)hi.cxy/(float)m_origwidth;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void columnAutoResizeProp(HWND hwnd, int item)
|
||
|
{
|
||
|
SendMessage(GetParent(hwnd),WM_SETREDRAW,FALSE,0);
|
||
|
int l=Header_GetItemCount(hwnd);
|
||
|
int width=0;
|
||
|
int i;
|
||
|
|
||
|
HD_ITEM hi;
|
||
|
hi.mask = HDI_WIDTH;
|
||
|
Header_GetItem(hwnd, item, &hi);
|
||
|
width=m_origwidth-(hi.cxy-m_origsizes[item]);
|
||
|
float rest=0;
|
||
|
for(i=item+1;i<l;i++) {
|
||
|
HD_ITEM hi;
|
||
|
hi.mask = HDI_WIDTH;
|
||
|
float l=m_origperc[i]*(float)width;
|
||
|
l+=rest;
|
||
|
rest=0;
|
||
|
int l2=(int)l;
|
||
|
rest+=l-(float)l2;
|
||
|
hi.cxy=l2;
|
||
|
Header_SetItem(hwnd, i, &hi);
|
||
|
}
|
||
|
SendMessage(GetParent(hwnd),WM_SETREDRAW,TRUE,0);
|
||
|
}
|
||
|
|
||
|
static void columnAutoResizeItem(HWND hwnd, int item)
|
||
|
{
|
||
|
HD_ITEM hi;
|
||
|
hi.mask = HDI_WIDTH;
|
||
|
Header_GetItem(hwnd, item, &hi);
|
||
|
int diff=hi.cxy-m_origsizes[item];
|
||
|
|
||
|
hi.mask = HDI_WIDTH;
|
||
|
if(Header_GetItem(hwnd, item+1, &hi)) {
|
||
|
SendMessage(GetParent(hwnd),WM_SETREDRAW,FALSE,0);
|
||
|
hi.cxy-=diff;
|
||
|
Header_SetItem(hwnd,item+1,&hi);
|
||
|
SendMessage(GetParent(hwnd),WM_SETREDRAW,TRUE,0);
|
||
|
}
|
||
|
m_origsizes[item]+=diff;
|
||
|
}
|
||
|
|
||
|
static void size_autoResizeStart(HWND h)
|
||
|
{
|
||
|
RECT r;
|
||
|
GetClientRect(h,&r);
|
||
|
char tmp[128];
|
||
|
wsprintf(tmp,"start:%i\n",r.right-r.left);
|
||
|
OutputDebugString(tmp);
|
||
|
}
|
||
|
|
||
|
static void size_autoResizeProp(HWND h)
|
||
|
{
|
||
|
RECT r;
|
||
|
GetClientRect(h,&r);
|
||
|
char tmp[128];
|
||
|
wsprintf(tmp,"prop:%i\n",r.right-r.left);
|
||
|
OutputDebugString(tmp);
|
||
|
}
|
||
|
|
||
|
INT_PTR handleListViewHeaderMsgs(HWND hwndDlg,
|
||
|
HWND headerWnd,
|
||
|
HWND listWnd,
|
||
|
UINT uMsg,
|
||
|
WPARAM wParam,
|
||
|
LPARAM lParam,
|
||
|
BOOL sortShow,
|
||
|
BOOL sortAscending,
|
||
|
int sortIndex)
|
||
|
{
|
||
|
if (uMsg == WM_NOTIFY) {
|
||
|
LPNMCUSTOMDRAW lpnmcd = (NMCUSTOMDRAW *)lParam;
|
||
|
if(lpnmcd->hdr.code == NM_CUSTOMDRAW && lpnmcd->hdr.hwndFrom == headerWnd) {
|
||
|
switch (lpnmcd->dwDrawStage) {
|
||
|
// prior to painting
|
||
|
case CDDS_PREPAINT:
|
||
|
return CDRF_NOTIFYITEMDRAW; // tell windows we want individual notification of each item being drawn
|
||
|
// notification of each item being drawn
|
||
|
case CDDS_ITEMPREPAINT:
|
||
|
{
|
||
|
LOGBRUSH lb={BS_SOLID,WADlg_getColor(WADLG_LISTHEADER_BGCOLOR)};
|
||
|
HBRUSH brush;
|
||
|
brush=CreateBrushIndirect(&lb);
|
||
|
HDC hdc=lpnmcd->hdc;
|
||
|
RECT *rc=&lpnmcd->rc;
|
||
|
FillRect(hdc,rc,brush);
|
||
|
DeleteObject(brush);
|
||
|
|
||
|
int selected=(lpnmcd->uItemState&CDIS_SELECTED)?1:0;
|
||
|
|
||
|
HPEN pen;
|
||
|
|
||
|
if (!selected) pen=CreatePen(PS_SOLID,1,WADlg_getColor(WADLG_LISTHEADER_FRAME_TOPCOLOR));
|
||
|
else pen=CreatePen(PS_SOLID,1,WADlg_getColor(WADLG_LISTHEADER_FRAME_BOTTOMCOLOR));
|
||
|
|
||
|
HGDIOBJ oldobj=SelectObject(hdc,pen);
|
||
|
//SelectPen(hdc,pen);
|
||
|
MoveToEx(hdc,rc->left,rc->top,NULL);
|
||
|
LineTo(hdc,rc->right,rc->top);
|
||
|
MoveToEx(hdc,rc->left,rc->top,NULL);
|
||
|
LineTo(hdc,rc->left,rc->bottom);
|
||
|
|
||
|
if (!selected)
|
||
|
{
|
||
|
SelectObject(hdc,oldobj);
|
||
|
DeleteObject(pen);
|
||
|
pen=CreatePen(PS_SOLID,1,WADlg_getColor(WADLG_LISTHEADER_FRAME_BOTTOMCOLOR));
|
||
|
oldobj=SelectObject(hdc,pen);
|
||
|
}
|
||
|
|
||
|
MoveToEx(hdc,rc->right-1,rc->top,NULL);
|
||
|
LineTo(hdc,rc->right-1,rc->bottom);
|
||
|
MoveToEx(hdc,rc->right-1,rc->bottom-1,NULL);
|
||
|
LineTo(hdc,rc->left-1,rc->bottom-1);
|
||
|
|
||
|
SelectObject(hdc,oldobj);
|
||
|
DeleteObject(pen);
|
||
|
|
||
|
if(!selected) {
|
||
|
pen=CreatePen(PS_SOLID,1,WADlg_getColor(WADLG_LISTHEADER_FRAME_MIDDLECOLOR));
|
||
|
oldobj=SelectObject(hdc,pen);
|
||
|
MoveToEx(hdc,rc->right-2,rc->top+1,NULL);
|
||
|
LineTo(hdc,rc->right-2,rc->bottom-2);
|
||
|
MoveToEx(hdc,rc->right-2,rc->bottom-2,NULL);
|
||
|
LineTo(hdc,rc->left,rc->bottom-2);
|
||
|
SelectObject(hdc,oldobj);
|
||
|
DeleteObject(pen);
|
||
|
}
|
||
|
|
||
|
DWORD_PTR i=lpnmcd->dwItemSpec;
|
||
|
char txt[128];
|
||
|
LVCOLUMN lv={LVCF_TEXT,0,0,txt,sizeof(txt)-1,};
|
||
|
ListView_GetColumn(listWnd,i,&lv);
|
||
|
SetBkMode(hdc,TRANSPARENT);
|
||
|
SetTextColor(hdc,WADlg_getColor(WADLG_LISTHEADER_FONTCOLOR));
|
||
|
RECT rc2=*rc;
|
||
|
rc2.left+=5; rc2.right-=3;
|
||
|
rc2.top+=2; rc2.bottom-=2;
|
||
|
if(selected) {
|
||
|
rc2.left++;
|
||
|
rc2.top++;
|
||
|
}
|
||
|
|
||
|
if (sortShow && (i == sortIndex) && ((rc->right - rc->left) > 40) )
|
||
|
{
|
||
|
rc2.right -= 14;
|
||
|
HPEN penDark;
|
||
|
pen=CreatePen(PS_SOLID,1,WADlg_getColor(WADLG_LISTHEADER_FRAME_TOPCOLOR));
|
||
|
penDark=CreatePen(PS_SOLID,1,WADlg_getColor(WADLG_LISTHEADER_EMPTY_BGCOLOR));
|
||
|
oldobj=SelectObject(hdc,pen);
|
||
|
if (sortAscending)
|
||
|
{
|
||
|
//strcpy(txt, " /\\ ");
|
||
|
// Draw triangle pointing upwards
|
||
|
MoveToEx(hdc, rc->right - 10, rc->top + 5, NULL);
|
||
|
LineTo(hdc, rc->right - 6, rc->bottom - 6);
|
||
|
LineTo(hdc, rc->right - 15, rc->bottom - 6 );
|
||
|
MoveToEx(hdc, rc->right - 14, rc->bottom - 7, NULL );
|
||
|
|
||
|
SelectObject(hdc, penDark);
|
||
|
LineTo(hdc, rc->right - 10, rc->top + 5);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Draw triangle pointing downwords
|
||
|
MoveToEx(hdc, rc->right - 7, rc->top + 7, NULL);
|
||
|
LineTo(hdc, rc->right - 11, rc->bottom - 6 );
|
||
|
MoveToEx(hdc, rc->right - 11, rc->bottom - 6, NULL);
|
||
|
|
||
|
SelectObject(hdc, penDark);
|
||
|
LineTo(hdc, rc->right - 15, rc->top + 6 );
|
||
|
LineTo(hdc, rc->right - 6, rc->top + 6);
|
||
|
}
|
||
|
SelectObject(hdc,oldobj);
|
||
|
DeleteObject(pen);
|
||
|
DeleteObject(penDark);
|
||
|
}
|
||
|
DrawText(hdc,txt,-1,&rc2,DT_VCENTER|DT_SINGLELINE|DT_LEFT);
|
||
|
|
||
|
}
|
||
|
return CDRF_SKIPDEFAULT;
|
||
|
}
|
||
|
}
|
||
|
HD_NOTIFY *pHDN = (HD_NOTIFY*)lParam;
|
||
|
if(pHDN->hdr.code == HDN_BEGINTRACKW || pHDN->hdr.code == HDN_BEGINTRACKA)
|
||
|
{
|
||
|
m_column_resize=g_config->ReadInt("column_resize_mode",m_column_resize);
|
||
|
if(m_column_resize) columnTrackStart(pHDN->hdr.hwndFrom, pHDN->iItem);
|
||
|
}
|
||
|
|
||
|
if(pHDN->hdr.code==HDN_ENDTRACKW || pHDN->hdr.code==HDN_ENDTRACKA || pHDN->hdr.code==HDN_ITEMCHANGINGW || pHDN->hdr.code==HDN_ITEMCHANGINGA) {
|
||
|
static int disable=0;
|
||
|
if(disable) return FALSE;
|
||
|
disable=1;
|
||
|
if(m_column_resize==1) columnAutoResizeItem(pHDN->hdr.hwndFrom, pHDN->iItem);
|
||
|
if(m_column_resize==2) columnAutoResizeProp(pHDN->hdr.hwndFrom, pHDN->iItem);
|
||
|
disable=0;
|
||
|
SendMessage(hwndDlg,WM_USER+0x3443,0,0); //update ScrollWnd
|
||
|
}
|
||
|
}
|
||
|
/*if(uMsg==WM_WINDOWPOSCHANGING) {
|
||
|
HWND h=ListView_GetHeader(hwndDlg);
|
||
|
if(h) size_autoResizeStart(h);
|
||
|
}
|
||
|
if(uMsg==WM_SIZE) {
|
||
|
HWND h=ListView_GetHeader(hwndDlg);
|
||
|
if(h) size_autoResizeProp(h);
|
||
|
}*/
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int RectInRect(RECT *rect1, RECT *rect2)
|
||
|
{
|
||
|
// this has a bias towards true
|
||
|
|
||
|
// this could probably be optimized a lot
|
||
|
return ((rect1->top >= rect2->top && rect1->top <= rect2->bottom) ||
|
||
|
(rect1->bottom >= rect2->top && rect1->bottom <= rect2->bottom) ||
|
||
|
(rect2->top >= rect1->top && rect2->top <= rect1->bottom) ||
|
||
|
(rect2->bottom >= rect1->top && rect2->bottom <= rect1->bottom)) // vertical intersect
|
||
|
&&
|
||
|
((rect1->left >= rect2->left && rect1->left <= rect2->right) ||
|
||
|
(rect1->right >= rect2->left && rect1->right <= rect2->right) ||
|
||
|
(rect2->left >= rect1->left && rect2->left <= rect1->right) ||
|
||
|
(rect2->right >= rect1->left && rect2->right <= rect1->right)) // horiz intersect
|
||
|
;
|
||
|
}
|
||
|
|
||
|
INT_PTR handleListViewHeaderPaintMsgs(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||
|
if(uMsg==WM_ERASEBKGND)
|
||
|
{
|
||
|
return 1; //we erase the background below
|
||
|
}
|
||
|
if(uMsg==WM_PAINT)
|
||
|
{
|
||
|
//process the grey area with our color
|
||
|
RECT r;
|
||
|
GetClientRect(hwndDlg,&r);
|
||
|
int n=Header_GetItemCount(hwndDlg);
|
||
|
if(n)
|
||
|
{
|
||
|
RECT r2;
|
||
|
Header_GetItemRect(hwndDlg,n-1,&r2);
|
||
|
r.left=r2.right;
|
||
|
}
|
||
|
RECT ur;
|
||
|
GetUpdateRect(hwndDlg,&ur,FALSE);
|
||
|
if(RectInRect(&r,&ur))
|
||
|
{
|
||
|
HDC hdc=GetDC(hwndDlg);
|
||
|
HBRUSH b=CreateSolidBrush(WADlg_getColor(WADLG_LISTHEADER_EMPTY_BGCOLOR));
|
||
|
FillRect(hdc,&r,b);
|
||
|
DeleteObject(b);
|
||
|
ReleaseDC(hwndDlg,hdc);
|
||
|
ValidateRect(hwndDlg,&r);
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|