summaryrefslogtreecommitdiff
path: root/wintable
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2015-01-08 01:45:06 -0500
committerPietro Gagliardi <[email protected]>2015-01-08 01:45:06 -0500
commit1dcdcd522cf1e63fd61f4ca376d4108a775a1565 (patch)
tree5133c81d0638edc99f5af6f9e57716d8c3ddcdba /wintable
parent224bdb40874ff65880f21bda2b85ceebb4a69312 (diff)
Collected all of the metric updating stuff into a single update() function. Far from optimal, but much better.
Diffstat (limited to 'wintable')
-rw-r--r--wintable/api.h13
-rw-r--r--wintable/header.h41
-rw-r--r--wintable/main.h4
-rw-r--r--wintable/resize.h23
-rw-r--r--wintable/test.c3
-rw-r--r--wintable/update.h44
6 files changed, 65 insertions, 63 deletions
diff --git a/wintable/api.h b/wintable/api.h
index bf259ad..260202e 100644
--- a/wintable/api.h
+++ b/wintable/api.h
@@ -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;
}
diff --git a/wintable/header.h b/wintable/header.h
index 5652029..863d3d0 100644
--- a/wintable/header.h
+++ b/wintable/header.h
@@ -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;
}
diff --git a/wintable/main.h b/wintable/main.h
index c8ba30c..ba85e7a 100644
--- a/wintable/main.h
+++ b/wintable/main.h
@@ -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,
diff --git a/wintable/resize.h b/wintable/resize.h
index 2ffaad7..ae669e3 100644
--- a/wintable/resize.h
+++ b/wintable/resize.h
@@ -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;
}
diff --git a/wintable/test.c b/wintable/test.c
index 6d38bd1..d3f75ab 100644
--- a/wintable/test.c
+++ b/wintable/test.c
@@ -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;
diff --git a/wintable/update.h b/wintable/update.h
new file mode 100644
index 0000000..c4beea7
--- /dev/null
+++ b/wintable/update.h
@@ -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/?
+}