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)
|
||||
{
|
||||
uiTable *t = uiTable(c);
|
||||
|
@ -119,7 +181,8 @@ static void uiTableDestroy(uiControl *c)
|
|||
for (auto col : *(t->columns))
|
||||
uiprivFree(col);
|
||||
delete t->columns;
|
||||
// t->smallImages will be automatically destroyed
|
||||
// t->imagelist will be automatically destroyed
|
||||
delete t->indeterminatePositions;
|
||||
uiFreeControl(uiControl(t));
|
||||
}
|
||||
|
||||
|
@ -283,5 +346,9 @@ uiTable *uiNewTable(uiTableModel *model)
|
|||
// 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;
|
||||
}
|
||||
|
|
|
@ -31,8 +31,10 @@ struct uiTable {
|
|||
int backgroundColumn;
|
||||
// TODO make sure replacing images while selected in the listview is even allowed
|
||||
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
|
||||
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) {
|
||||
data = (*(t->model->mh->CellValue))(t->model->mh, t->model, nm->item.iItem, p->progressBarModelColumn);
|
||||
progress = uiTableDataInt(data);
|
||||
uiFreeTableData(data);
|
||||
progress = uiprivTableProgress(t, nm->item.iItem, p->progressBarModelColumn, NULL);
|
||||
|
||||
if (progress == -1) {
|
||||
// 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)
|
||||
{
|
||||
uiTableData *data;
|
||||
int progress;
|
||||
LONG indeterminatePos;
|
||||
HTHEME theme;
|
||||
RECT r;
|
||||
RECT rBorder, rFill[2];
|
||||
|
@ -327,9 +327,7 @@ static HRESULT drawProgressBarPart(struct drawState *s)
|
|||
|
||||
if (s->p->progressBarModelColumn == -1)
|
||||
return S_OK;
|
||||
data = (*(s->m->mh->CellValue))(s->m->mh, s->m, s->iItem, s->p->progressBarModelColumn);
|
||||
progress = uiTableDataInt(data);
|
||||
uiFreeTableData(data);
|
||||
progress = uiprivTableProgress(s->t, s->iItem, s->p->progressBarModelColumn, &indeterminatePos);
|
||||
|
||||
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
|
||||
barWidth = rFill[0].right - rFill[0].left;
|
||||
pieceWidth = barWidth / indeterminateSegments;
|
||||
rFill[0].left += s->t->indeterminatePosition % barWidth;
|
||||
rFill[0].left += indeterminatePos % barWidth;
|
||||
if ((rFill[0].left + pieceWidth) >= rFill[0].right) {
|
||||
// make this piece wrap back around
|
||||
nFill++;
|
||||
|
|
|
@ -60,4 +60,5 @@
|
|||
#include <unordered_map>
|
||||
#include <sstream>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue