icon alignment algorithms

svn path=/trunk/; revision=7782
This commit is contained in:
Martin Fuchs 2004-01-20 00:17:24 +00:00
parent f14c8d5e08
commit 1d8c431643
9 changed files with 167 additions and 25 deletions

View file

@ -37,7 +37,7 @@ exe explorer :
dialogs/searchprogram.cpp
dialogs/settings.cpp
i386-stub-win32.c
: <define>WIN32 <define>_ROS_ <define>_WIN32_IE=0x0501 <define>_WIN32_WINNT=0x0501
: <define>WIN32 <define>_WIN32_IE=0x0501 <define>_WIN32_WINNT=0x0501
<cxxflags>-I$(INCLUDE)
#nur für GCC: <cxxflags>-fexceptions <cxxflags>-Wall
<find-shared-library>gdi32

View file

@ -8,8 +8,8 @@ CC = gcc
CXX = g++
LINK = g++
CFLAGS = -DWIN32 -D_ROS_ -D_WIN32_IE=0x0501 -D_WIN32_WINNT=0x0501 -fexceptions -Wall
RCFLAGS = -DWIN32 -D_ROS_
CFLAGS = -DWIN32 -D_WIN32_IE=0x0501 -D_WIN32_WINNT=0x0501 -fexceptions -Wall
RCFLAGS = -DWIN32
LFLAGS = -Wl,--subsystem,windows
ifdef DEBUG

View file

@ -173,6 +173,8 @@ LRESULT DesktopWindow::Init(LPCREATESTRUCT pcs)
///@todo use IShellBrowser::GetViewStateStream() to restore previous view state -> see SHOpenRegStream()
if (SUCCEEDED(hr)) {
g_Globals._hwndShellView = hWndView;
// subclass shellview window
new DesktopShellView(hWndView, _pShellView);
@ -205,17 +207,6 @@ LRESULT DesktopWindow::Init(LPCREATESTRUCT pcs)
hr = pFolderView->SetCurrentViewMode(FVM_DETAILS);
}
*/
HWND hwndFolderView = ::GetNextWindow(hWndView, GW_CHILD);
SetWindowStyle(hwndFolderView, (GetWindowStyle(hwndFolderView)&~LVS_ALIGNLEFT)|LVS_ALIGNTOP|LVS_AUTOARRANGE);
// work around for Windows NT, Win 98, ...
// Without this the desktop has mysteriously only a size of 800x600 pixels.
MoveWindow(hwndFolderView, 0, 0, rect.right, rect.bottom, TRUE);
// subclass background window
new BackgroundWindow(hwndFolderView);
}
}
@ -288,6 +279,21 @@ DesktopShellView::DesktopShellView(HWND hwnd, IShellView* pShellView)
: super(hwnd),
_pShellView(pShellView)
{
_hwndListView = ::GetNextWindow(hwnd, GW_CHILD);
SetWindowStyle(_hwndListView, GetWindowStyle(_hwndListView)&~LVS_ALIGNMASK);//|LVS_ALIGNTOP|LVS_AUTOARRANGE);
// work around for Windows NT, Win 98, ...
// Without this the desktop has mysteriously only a size of 800x600 pixels.
ClientRect rect(hwnd);
MoveWindow(_hwndListView, 0, 0, rect.right, rect.bottom, TRUE);
// subclass background window
new BackgroundWindow(_hwndListView);
_alignment = 0;
PositionIcons(_alignment);
InitDragDrop();
}
@ -330,6 +336,11 @@ LRESULT DesktopShellView::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
DoDesktopContextMenu(GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam));
break;
case PM_POSITION_ICONS:
PositionIcons(wparam);
_alignment = wparam;
break;
default:
return super::WndProc(nmsg, wparam, lparam);
}
@ -429,3 +440,117 @@ HRESULT DesktopShellView::DoDesktopContextMenu(int x, int y)
return hr;
}
static const POINTS s_align_start[8] = {
{0, 0}, // left/top
{0, 0},
{1, 0}, // right/top
{1, 0},
{0, 1}, // left/bottom
{0, 1},
{1, 1}, // right/bottom
{1, 1}
};
static const POINTS s_align_dir1[8] = {
{ 0, +1}, // down
{+1, 0}, // right
{-1, 0}, // left
{ 0, +1}, // down
{ 0, -1}, // up
{+1, 0}, // right
{-1, 0}, // left
{ 0, -1} // up
};
static const POINTS s_align_dir2[8] = {
{+1, 0}, // right
{ 0, +1}, // down
{ 0, +1}, // down
{-1, 0}, // left
{+1, 0}, // right
{ 0, -1}, // up
{ 0, -1}, // up
{-1, 0} // left
};
typedef pair<int,int> IconPos;
typedef map<IconPos, int> IconMap;
void DesktopShellView::PositionIcons(int alignment, int dir)
{
DWORD spacing = ListView_GetItemSpacing(_hwndListView, FALSE);
RECT work_area;
SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0);
const POINTS& dir1 = s_align_dir1[alignment];
const POINTS& dir2 = s_align_dir2[alignment];
const POINTS& start_pos = s_align_start[alignment];
int dir_x1 = dir1.x;
int dir_y1 = dir1.y;
int dir_x2 = dir2.x;
int dir_y2 = dir2.y;
int cx = LOWORD(spacing);
int cy = HIWORD(spacing);
int dx1 = dir_x1 * cx;
int dy1 = dir_y1 * cy;
int dx2 = dir_x2 * cx;
int dy2 = dir_y2 * cy;
int start_x = start_pos.x * work_area.right + (cx-32)/2;
int start_y = start_pos.y * work_area.bottom + 4/*(cy-32)/2*/;
if (start_x >= work_area.right)
start_x -= cx;
if (start_y >= work_area.bottom)
start_y -= cy;
int x = start_x;
int y = start_y;
int cnt = ListView_GetItemCount(_hwndListView);
int i1, i2;
if (dir > 0) {
i1 = 0;
i2 = cnt;
} else {
i1 = cnt-1;
i2 = -1;
}
IconMap pos_idx;
for(int idx=i1; idx!=i2; idx+=dir) {
pos_idx[IconPos(y, x)] = idx;
x += dx1;
y += dy1;
if (x<0 || x>=work_area.right) {
x = start_x;
y += dy2;
} else if (y<0 || y>=work_area.bottom) {
y = start_y;
x += dx2;
}
}
for(IconMap::const_iterator it=pos_idx.end(); --it!=pos_idx.begin(); ) {
const IconPos& pos = it->first;
ListView_SetItemPosition32(_hwndListView, it->second, pos.second, pos.first);
}
for(IconMap::const_iterator it=pos_idx.begin(); it!=pos_idx.end(); ++it) {
const IconPos& pos = it->first;
ListView_SetItemPosition32(_hwndListView, it->second, pos.second, pos.first);
}
}

View file

@ -26,6 +26,9 @@
//
#define PM_POSITION_ICONS (WM_APP+0x19)
/// subclassed Background window behind the visible desktop window
struct BackgroundWindow : public SubclassedWindow
{
@ -173,6 +176,9 @@ protected:
bool DoContextMenu(int x, int y);
HRESULT DoDesktopContextMenu(int x, int y);
void PositionIcons(int alignment, int dir=1);
DesktopDropTarget* _pDropTarget;
HWND _hwndListView;
int _alignment;
};

View file

@ -34,6 +34,7 @@
#include "../globals.h"
#include "../externals.h"
#include "../explorer_intres.h"
#include "../desktop/desktop.h"
#include "settings.h"
@ -113,7 +114,10 @@ int DesktopSettingsDlg::Command(int id, int code)
if (alignment != _alignment) {
_alignment = alignment;
PropSheet_Changed(GetParent(_hwnd), _hwnd);
SendMessage(g_Globals._hwndShellView, PM_POSITION_ICONS, alignment, 0);
}
}

View file

@ -64,6 +64,8 @@ ExplorerGlobals::ExplorerGlobals()
#ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003)
_SHRestricted = 0;
#endif
_hwndDesktopBar = 0;
_hwndShellView = 0;
}

View file

@ -49,7 +49,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O1 /D "NDEBUG" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O1 /D "NDEBUG" /D "WIN32" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /YX /FD /c
# ADD BASE RSC /l 0x407 /d "NDEBUG"
# ADD RSC /l 0x407 /d "NDEBUG"
BSC32=bscmake.exe
@ -74,7 +74,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
@ -100,7 +100,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "_ROS_" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /Zi /O2 /D "NDEBUG" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /Zi /O2 /D "NDEBUG" /D "WIN32" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /c
# ADD BASE RSC /l 0x407 /d "NDEBUG"
# ADD RSC /l 0x407 /d "NDEBUG"
BSC32=bscmake.exe
@ -126,7 +126,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D "UNICODE" /D "_ROS_" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /D "NDEBUG" /D "UNICODE" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /YX /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /D "NDEBUG" /D "UNICODE" /D "WIN32" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /YX /FD /c
# ADD BASE RSC /l 0x407 /d "NDEBUG"
# ADD RSC /l 0x407 /d "NDEBUG"
BSC32=bscmake.exe
@ -152,7 +152,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "UNICODE" /D "_ROS_" /FR /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D "_DEBUG" /D "UNICODE" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D "_DEBUG" /D "UNICODE" /D "WIN32" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
@ -178,7 +178,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /D "_NO_COMUTIL" /FR /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D "_DEBUG" /D "_NO_COMUTIL" /D "WIN32" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
@ -205,7 +205,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D "_DEBUG" /D "UNICODE" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D "_DEBUG" /D "UNICODE" /D "WIN32" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
@ -232,7 +232,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MDd /W3 /Gm /GR /GX /ZI /Od /D "_DEBUG" /D "UNICODE" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FR /YX /FD /GZ /c
# ADD CPP /nologo /MT /W3 /GR /GX /O2 /D "NDEBUG" /D "UNICODE" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FD /c
# ADD CPP /nologo /MT /W3 /GR /GX /O2 /D "NDEBUG" /D "UNICODE" /D "WIN32" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FD /c
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe
@ -259,7 +259,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GR /GX /O2 /D "NDEBUG" /D "UNICODE" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /D "NDEBUG" /D "UNICODE" /D "WIN32" /D "_ROS_" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FD /c
# ADD CPP /nologo /MD /W3 /GR /GX /O2 /D "NDEBUG" /D "UNICODE" /D "WIN32" /D _WIN32_IE=0x0501 /D _WIN32_WINNT=0x0501 /FD /c
# ADD BASE RSC /l 0x407 /d "_DEBUG"
# ADD RSC /l 0x407 /d "_DEBUG"
BSC32=bscmake.exe

View file

@ -161,6 +161,7 @@ extern struct ExplorerGlobals
IconCache _icon_cache;
HWND _hwndDesktopBar;
HWND _hwndShellView;
} g_Globals;

View file

@ -1272,13 +1272,17 @@ int PropertySheetDialog::DoModal(int start_page)
HWND hwndPropSheet = *pwnd;
*/
HWND hwndPropSheet = (HWND) PropertySheet(this);
int ret = PropertySheet(this);
if (ret == -1)
return -1;
HWND hwndPropSheet = (HWND) ret;
HWND hwndparent = GetParent(hwndPropSheet);
if (hwndparent)
EnableWindow(hwndparent, FALSE);
int ret = 0;
ret = 0;
MSG msg;
while(GetMessage(&msg, 0, 0, 0)) {