Started a more flexible indeterminate-state implementation. Now to build and test it.
This commit is contained in:
parent
c978f6fece
commit
c7555dcfd3
|
@ -76,6 +76,68 @@ void uiTableModelRowDeleted(uiTableModel *m, int oldIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static LRESULT CALLBACK tableSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIDSubclass, DWORD_PTR dwRefData)
|
||||||
|
{
|
||||||
|
uiTable *t = (uiTable *) dwRefData;
|
||||||
|
|
||||||
|
switch (uMsg) {
|
||||||
|
case WM_TIMER:
|
||||||
|
if (wParam != (WPARAM) t)
|
||||||
|
break;
|
||||||
|
for (auto &i : t->indeterminatePositions) {
|
||||||
|
i->second++;
|
||||||
|
// TODO check errors
|
||||||
|
SendMessageW(hwnd, LVM_UPDATE, (WPARAM) (i->first.first), 0);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
case WM_NCDESTROY:
|
||||||
|
if (RemoveWindowSubclass(hwnd, tableSubProc, uIDSubclass) == FALSE)
|
||||||
|
logLastError(L"RemoveWindowSubclass()");
|
||||||
|
// fall through
|
||||||
|
}
|
||||||
|
return DefSubclassProc(hwnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
|
|
||||||
|
int uiprivTableProgress(uiTable *t, int item, int subitem, int modelColumn, LONG *pos)
|
||||||
|
{
|
||||||
|
uiTableData *data;
|
||||||
|
int progress;
|
||||||
|
std::pair<int, int> p;
|
||||||
|
std::map<std::pair<int, int>, LONG>::iterator iter;
|
||||||
|
bool startTimer = false;
|
||||||
|
bool stopTimer = false;
|
||||||
|
|
||||||
|
data = (*(t->model->mh->CellValue))(t->model->mh, t->model, item, modelColumn);
|
||||||
|
progress = uiTableModelInt(data);
|
||||||
|
uiFreeTableData(data);
|
||||||
|
|
||||||
|
p.first = item;
|
||||||
|
p.second = subitem;
|
||||||
|
iter = t->indeterminatePositions->find(p);
|
||||||
|
if (iter == t->indeterminatePositions->end()) {
|
||||||
|
if (progress == -1) {
|
||||||
|
startTimer = t->indeterminatePositions->size() == 0;
|
||||||
|
(*(t->indeterminatePositions))[p] = 0;
|
||||||
|
if (pos != NULL)
|
||||||
|
*pos = 0;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (progress != -1) {
|
||||||
|
t->indeterminatePositions->erase(p);
|
||||||
|
stopTimer = t->indeterminatePositions->size() == 0;
|
||||||
|
} else if (pos != NULL)
|
||||||
|
*pos = iter->second;
|
||||||
|
|
||||||
|
if (startTimer)
|
||||||
|
// the interval shown here is PBM_SETMARQUEE's default
|
||||||
|
// TODO should we pass a function here instead? it seems to be called by DispatchMessage(), not DefWindowProc(), but I'm still unsure
|
||||||
|
if (SetTimer(t->hwnd, (UINT_PTR) (&t), 30, NULL) == 0)
|
||||||
|
logLastError(L"SetTimer()");
|
||||||
|
if (stopTimer)
|
||||||
|
if (KillTimer(t->hwnd, (UINT_PTR) (&t)) == 0)
|
||||||
|
logLastError(L"KillTimer()");
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL onWM_NOTIFY(uiControl *c, HWND hwnd, NMHDR *nmhdr, LRESULT *lResult)
|
static BOOL onWM_NOTIFY(uiControl *c, HWND hwnd, NMHDR *nmhdr, LRESULT *lResult)
|
||||||
{
|
{
|
||||||
uiTable *t = uiTable(c);
|
uiTable *t = uiTable(c);
|
||||||
|
@ -119,7 +181,8 @@ static void uiTableDestroy(uiControl *c)
|
||||||
for (auto col : *(t->columns))
|
for (auto col : *(t->columns))
|
||||||
uiprivFree(col);
|
uiprivFree(col);
|
||||||
delete t->columns;
|
delete t->columns;
|
||||||
// t->smallImages will be automatically destroyed
|
// t->imagelist will be automatically destroyed
|
||||||
|
delete t->indeterminatePositions;
|
||||||
uiFreeControl(uiControl(t));
|
uiFreeControl(uiControl(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,5 +346,9 @@ uiTable *uiNewTable(uiTableModel *model)
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t->indeterminatePositions = new std::map<std::pair<int, int>, LONG>;
|
||||||
|
if (SetWindowSubclass(t->hwnd, tableSubProc, 0, (DWORD_PTR) t) == FALSE)
|
||||||
|
logLastError(L"SetWindowSubclass()");
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,10 @@ struct uiTable {
|
||||||
int backgroundColumn;
|
int backgroundColumn;
|
||||||
// TODO make sure replacing images while selected in the listview is even allowed
|
// TODO make sure replacing images while selected in the listview is even allowed
|
||||||
HIMAGELIST imagelist;
|
HIMAGELIST imagelist;
|
||||||
LONG indeterminatePosition;
|
// TODO document all this
|
||||||
|
std::map<std::pair<int, int>, LONG> *indeterminatePositions;
|
||||||
};
|
};
|
||||||
|
extern int uiprivTableProgress(uiTable *t, int item, int subitem, int modelColumn, LONG *pos);
|
||||||
|
|
||||||
// tabledispinfo.cpp
|
// tabledispinfo.cpp
|
||||||
extern HRESULT uiprivTableHandleLVN_GETDISPINFO(uiTable *t, NMLVDISPINFOW *nm, LRESULT *lResult);
|
extern HRESULT uiprivTableHandleLVN_GETDISPINFO(uiTable *t, NMLVDISPINFOW *nm, LRESULT *lResult);
|
||||||
|
|
|
@ -32,9 +32,7 @@ static HRESULT handleLVIF_TEXT(uiTable *t, NMLVDISPINFOW *nm, uiprivTableColumnP
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->progressBarModelColumn != -1) {
|
if (p->progressBarModelColumn != -1) {
|
||||||
data = (*(t->model->mh->CellValue))(t->model->mh, t->model, nm->item.iItem, p->progressBarModelColumn);
|
progress = uiprivTableProgress(t, nm->item.iItem, p->progressBarModelColumn, NULL);
|
||||||
progress = uiTableDataInt(data);
|
|
||||||
uiFreeTableData(data);
|
|
||||||
|
|
||||||
if (progress == -1) {
|
if (progress == -1) {
|
||||||
// TODO either localize this or replace it with something that's language-neutral
|
// TODO either localize this or replace it with something that's language-neutral
|
||||||
|
|
|
@ -315,8 +315,8 @@ static HRESULT drawTextPart(struct drawState *s)
|
||||||
|
|
||||||
static HRESULT drawProgressBarPart(struct drawState *s)
|
static HRESULT drawProgressBarPart(struct drawState *s)
|
||||||
{
|
{
|
||||||
uiTableData *data;
|
|
||||||
int progress;
|
int progress;
|
||||||
|
LONG indeterminatePos;
|
||||||
HTHEME theme;
|
HTHEME theme;
|
||||||
RECT r;
|
RECT r;
|
||||||
RECT rBorder, rFill[2];
|
RECT rBorder, rFill[2];
|
||||||
|
@ -327,9 +327,7 @@ static HRESULT drawProgressBarPart(struct drawState *s)
|
||||||
|
|
||||||
if (s->p->progressBarModelColumn == -1)
|
if (s->p->progressBarModelColumn == -1)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
data = (*(s->m->mh->CellValue))(s->m->mh, s->m, s->iItem, s->p->progressBarModelColumn);
|
progress = uiprivTableProgress(s->t, s->iItem, s->p->progressBarModelColumn, &indeterminatePos);
|
||||||
progress = uiTableDataInt(data);
|
|
||||||
uiFreeTableData(data);
|
|
||||||
|
|
||||||
theme = OpenThemeData(s->t->hwnd, L"TODO");
|
theme = OpenThemeData(s->t->hwnd, L"TODO");
|
||||||
|
|
||||||
|
@ -381,7 +379,7 @@ static HRESULT drawProgressBarPart(struct drawState *s)
|
||||||
rFill[1] = rFill[0]; // save in case we need it
|
rFill[1] = rFill[0]; // save in case we need it
|
||||||
barWidth = rFill[0].right - rFill[0].left;
|
barWidth = rFill[0].right - rFill[0].left;
|
||||||
pieceWidth = barWidth / indeterminateSegments;
|
pieceWidth = barWidth / indeterminateSegments;
|
||||||
rFill[0].left += s->t->indeterminatePosition % barWidth;
|
rFill[0].left += indeterminatePos % barWidth;
|
||||||
if ((rFill[0].left + pieceWidth) >= rFill[0].right) {
|
if ((rFill[0].left + pieceWidth) >= rFill[0].right) {
|
||||||
// make this piece wrap back around
|
// make this piece wrap back around
|
||||||
nFill++;
|
nFill++;
|
||||||
|
|
|
@ -60,4 +60,5 @@
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <utility>
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue