Collected all of the metric updating stuff into a single update() function. Far from optimal, but much better.
This commit is contained in:
parent
224bdb4087
commit
1dcdcd522c
|
@ -9,7 +9,7 @@ static void addColumn(struct table *t, WPARAM wParam, LPARAM lParam)
|
|||
if (t->columnTypes[t->nColumns - 1] >= nTableColumnTypes)
|
||||
panic("invalid column type passed to tableAddColumn");
|
||||
headerAddColumn(t, (WCHAR *) lParam);
|
||||
updateTableWidth(t);
|
||||
update(t, TRUE);
|
||||
}
|
||||
|
||||
HANDLER(apiHandlers)
|
||||
|
@ -21,8 +21,11 @@ HANDLER(apiHandlers)
|
|||
// don't free the old font; see http://blogs.msdn.com/b/oldnewthing/archive/2008/09/12/8945692.aspx
|
||||
t->font = (HFONT) wParam;
|
||||
SendMessageW(t->header, WM_SETFONT, wParam, lParam);
|
||||
// TODO how to properly handle LOWORD(lParam) != FALSE?
|
||||
// TODO depending on the result of the above, update table width to refresh t->headerHeight?
|
||||
update(t, LOWORD(lParam) != FALSE);
|
||||
// TODO is this needed?
|
||||
if (LOWORD(lParam) != FALSE)
|
||||
// TODO check error
|
||||
InvalidateRect(t->hwnd, NULL, TRUE);
|
||||
*lResult = 0;
|
||||
return TRUE;
|
||||
case WM_GETFONT:
|
||||
|
@ -35,8 +38,8 @@ HANDLER(apiHandlers)
|
|||
case tableSetRowCount:
|
||||
rcp = (intptr_t *) lParam;
|
||||
t->count = *rcp;
|
||||
// TODO refresh table in this way?
|
||||
updateTableWidth(t);
|
||||
// TODO shouldn't we just redraw everything?
|
||||
update(t, TRUE);
|
||||
*lResult = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,9 @@ static void destroyHeader(struct table *t)
|
|||
panic("error destroying Table header");
|
||||
}
|
||||
|
||||
// to avoid weird bugs, the only functions allowed to call this one are the horizontal scroll functions
|
||||
// when we need to reposition the header in a situation other than a user-initiated scroll, we use a dummy scroll (hscrollby(t, 0))
|
||||
// see update() in update.h
|
||||
static void repositionHeader(struct table *t)
|
||||
{
|
||||
RECT r;
|
||||
|
@ -58,40 +61,6 @@ static void headerAddColumn(struct table *t, WCHAR *name)
|
|||
panic("error adding column to Table header");
|
||||
}
|
||||
|
||||
// TODO make a better name for this?
|
||||
// TODO move to hscroll.h?
|
||||
// TODO organize this in general...
|
||||
// TODO because of this function's new extended functionality only hscrollto() is allowed to call repositionHeader()
|
||||
static void updateTableWidth(struct table *t)
|
||||
{
|
||||
HDITEMW item;
|
||||
intptr_t i;
|
||||
RECT client;
|
||||
|
||||
t->width = 0;
|
||||
// TODO count dividers?
|
||||
// TODO use columnWidth()
|
||||
for (i = 0; i < t->nColumns; i++) {
|
||||
ZeroMemory(&item, sizeof (HDITEMW));
|
||||
item.mask = HDI_WIDTH;
|
||||
if (SendMessageW(t->header, HDM_GETITEM, (WPARAM) i, (LPARAM) (&item)) == FALSE)
|
||||
panic("error getting Table column width for updateTableWidth()");
|
||||
t->width += item.cxy;
|
||||
}
|
||||
|
||||
if (GetClientRect(t->hwnd, &client) == 0)
|
||||
panic("error getting Table client rect in updateTableWidth()");
|
||||
t->hpagesize = client.right - client.left;
|
||||
|
||||
// this part is critical: if we resize the columns to less than the client area width, then the following hscrollby() will make t->hscrollpos negative, which does very bad things
|
||||
// note to self: do this regardless of whether the table width or the client area width was changed
|
||||
if (t->hpagesize > t->width)
|
||||
t->hpagesize = t->width;
|
||||
|
||||
// do a dummy scroll to update the horizontal scrollbar to use the new width
|
||||
hscrollby(t, 0);
|
||||
}
|
||||
|
||||
HANDLER(headerNotifyHandler)
|
||||
{
|
||||
NMHDR *nmhdr = (NMHDR *) lParam;
|
||||
|
@ -100,10 +69,10 @@ HANDLER(headerNotifyHandler)
|
|||
return FALSE;
|
||||
if (nmhdr->code != HDN_ITEMCHANGED)
|
||||
return FALSE;
|
||||
updateTableWidth(t);
|
||||
update(t, TRUE);
|
||||
// TODO make more intelligent
|
||||
// (TODO is it actually needed?)
|
||||
InvalidateRect(t->hwnd, NULL, TRUE);
|
||||
// TODO UpdateWindow()?
|
||||
*lResult = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -103,6 +103,9 @@ struct table {
|
|||
// forward declaration (TODO needed?)
|
||||
static LRESULT notify(struct table *, UINT, intptr_t, intptr_t, uintptr_t);
|
||||
|
||||
// necessary forward declaration
|
||||
static void update(struct table *, BOOL);
|
||||
|
||||
#include "util.h"
|
||||
#include "coord.h"
|
||||
#include "scroll.h"
|
||||
|
@ -117,6 +120,7 @@ static LRESULT notify(struct table *, UINT, intptr_t, intptr_t, uintptr_t);
|
|||
#include "draw.h"
|
||||
#include "api.h"
|
||||
#include "accessibility.h"
|
||||
#include "update.h"
|
||||
|
||||
static const handlerfunc handlers[] = {
|
||||
eventHandlers,
|
||||
|
|
|
@ -3,37 +3,18 @@
|
|||
// TODO why doesn't this trigger on first show?
|
||||
// TODO see if there's anything not metaphor related in the last bits of the scrollbar series
|
||||
// TODO rename this to boot
|
||||
// TODO merge with update.h?
|
||||
|
||||
HANDLER(resizeHandler)
|
||||
{
|
||||
WINDOWPOS *wp;
|
||||
RECT client;
|
||||
intptr_t height;
|
||||
|
||||
if (uMsg != WM_WINDOWPOSCHANGED)
|
||||
return FALSE;
|
||||
wp = (WINDOWPOS *) lParam;
|
||||
if ((wp->flags & SWP_NOSIZE) != 0)
|
||||
return FALSE;
|
||||
|
||||
// TODO does wp store the window rect or the client rect?
|
||||
if (GetClientRect(t->hwnd, &client) == 0)
|
||||
panic("error getting Table client rect in resizeHandler()");
|
||||
// TODO do this after calling updateTableWidth() (which calls repositionHeader()?)?
|
||||
client.top += t->headerHeight;
|
||||
|
||||
// update the width...
|
||||
// this will call repositionHeader(); there's a good reason... (see comments)
|
||||
// TODO when I clean that mess up, remove this comment
|
||||
updateTableWidth(t);
|
||||
|
||||
// ...and the height
|
||||
// TODO find out if order matters
|
||||
height = client.bottom - client.top;
|
||||
t->vpagesize = height / rowht(t);
|
||||
// do a dummy scroll to reflect those changes
|
||||
vscrollby(t, 0);
|
||||
|
||||
update(t, TRUE);
|
||||
*lResult = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -117,7 +117,8 @@ int main(int argc, char *argv[])
|
|||
INITCOMMONCONTROLSEX icc;
|
||||
WNDCLASSW wc;
|
||||
|
||||
mkbitmap();
|
||||
if (argc != 1)
|
||||
msgfont = TRUE;
|
||||
ZeroMemory(&icc, sizeof (INITCOMMONCONTROLSEX));
|
||||
icc.dwSize = sizeof (INITCOMMONCONTROLSEX);
|
||||
icc.dwICC = ICC_LISTVIEW_CLASSES;
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
// 8 january 2015
|
||||
|
||||
// Whenever a number of things in the Table changes, the update() function needs to be called to update any metrics and scrolling positions.
|
||||
// The control font changing is the big one, as that comes with a flag that decides whether or not to redraw everything. We'll need to respect that here.
|
||||
|
||||
// TODO actually use redraw here
|
||||
static void update(struct table *t, int redraw)
|
||||
{
|
||||
RECT client;
|
||||
intptr_t i;
|
||||
intptr_t height;
|
||||
|
||||
// before we do anything we need the client rect
|
||||
if (GetClientRect(t->hwnd, &client) == 0)
|
||||
panic("error getting Table client rect in update()");
|
||||
|
||||
// the first step is to figure out how wide the whole table is
|
||||
// TODO count dividers?
|
||||
t->width = 0;
|
||||
for (i = 0; i < t->nColumns; i++)
|
||||
t->width += columnWidth(t, i);
|
||||
|
||||
// now we need to figure out how much of the width of the table can be seen at once
|
||||
t->hpagesize = client.right - client.left;
|
||||
// this part is critical: if we resize the columns to less than the client area width, then the following hscrollby() will make t->hscrollpos negative, which does very bad things
|
||||
// we do this regardless of which of the two has changed, just to be safe
|
||||
if (t->hpagesize > t->width)
|
||||
t->hpagesize = t->width;
|
||||
|
||||
// now we do a dummy horizontal scroll to apply the new width and horizontal page size
|
||||
// this will also reposition and resize the header (the latter in case the font changed), which will be important for the next step
|
||||
hscrollby(t, 0);
|
||||
|
||||
// now that we have the new height of the header, we can fix up vertical scrolling
|
||||
// so let's take the header height away from the client area
|
||||
client.top += t->headerHeight;
|
||||
// and update our page size appropriately
|
||||
height = client.bottom - client.top;
|
||||
t->vpagesize = height / rowht(t);
|
||||
// and do a dummy vertical scroll to apply that
|
||||
vscrollby(t, 0);
|
||||
|
||||
// TODO invalidate /everything/?
|
||||
}
|
Loading…
Reference in New Issue