summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2015-02-16 15:34:48 -0500
committerPietro Gagliardi <[email protected]>2015-02-16 15:34:48 -0500
commit8e4145b00cd72c09b17fb0dbf58c3231c3305c22 (patch)
tree90798f41c61c39890800175fd5551fc4573c6a47
parent9338743e5d6e0829edb1e8df33d7d46acb5c48dd (diff)
Implemented accNavigate().
-rw-r--r--wintable/accessibility.h130
1 files changed, 127 insertions, 3 deletions
diff --git a/wintable/accessibility.h b/wintable/accessibility.h
index a8ddb35..9289b22 100644
--- a/wintable/accessibility.h
+++ b/wintable/accessibility.h
@@ -4,6 +4,8 @@
// - TODO figure out what to do about header
// - a row extends as far right as the right edge of the last cell in the row; anything to the right of that is treated as table space (just like with mouse selection)
// - this has the added effect that hit-testing can only ever return either the table or a cell, never a row
+// - cells have no children; checkbox cells are themselves the accessible object
+// - TODO if we ever add combobox columns, this will need to change somehow
// TODOs:
// - make sure E_POINTER and RPC_E_DISCONNECTED are correct returns for IAccessible
@@ -384,11 +386,133 @@ static HRESULT STDMETHODCALLTYPE tableAccaccLocation(IAccessible *this, long *px
static HRESULT STDMETHODCALLTYPE tableAccaccNavigate(IAccessible *this, long navDir, VARIANT varStart, VARIANT *pvarEndUpAt)
{
- if (TA->t == NULL || TA->std == NULL) {
- // TODO set values on error
+ HRESULT hr;
+ tableAccWhat what;
+ intptr_t row = -1;
+ intptr_t column = -1;
+
+ if (pvarEndUpAt == NULL)
+ return E_POINTER;
+ // TODO set pvarEndUpAt to an invalid value?
+ if (TA->t == NULL || TA->std == NULL)
return RPC_E_DISCONNECTED;
+ what = TA->what;
+ hr = normalizeWhat(TA, varStart, &what);
+ if (hr != S_OK)
+ return hr;
+ switch (what.role) {
+ case ROLE_SYSTEM_TABLE:
+ switch (navDir) {
+ case NAVDIR_FIRSTCHILD:
+ // TODO header row
+ if (TA->t->count == 0)
+ goto nowhere;
+ row = 0;
+ goto specificRow;
+ case NAVDIR_LASTCHILD:
+ // TODO header row
+ if (TA->t->count == 0)
+ goto nowhere;
+ row = TA->t->count - 1;
+ goto specificRow;
+ }
+ // otherwise, defer to the standard accessible object
+ return IAccessible_accNavigate(TA->std, navDir, varStart, pvarEndUpAt);
+ case ROLE_SYSTEM_ROW:
+ row = what.row;
+ switch (navDir) {
+ case NAVDIR_UP:
+ case NAVDIR_PREVIOUS:
+ if (row == 0) // can't go up
+ goto nowhere;
+ row--;
+ // row should still be valid because normalizeWhat() returns an error if the current row is no longer valid, and if that's valid, the row above it should also be valid
+ goto specificRow;
+ case NAVDIR_DOWN:
+ case NAVDIR_NEXT:
+ if (row == TA->t->count - 1) // can't go down
+ goto nowhere;
+ row++;
+ // row should still be valid by the above conjecture
+ goto specificRow;
+ case NAVDIR_LEFT:
+ case NAVDIR_RIGHT:
+ goto nowhere;
+// TODO this doesn't actually exist yet https://msdn.microsoft.com/en-us/library/ms971325 talks about it
+// case NAVDIR_PARENT:
+// goto tableItself;
+ case NAVDIR_FIRSTCHILD:
+ if (TA->t->nColumns == 0)
+ goto nowhere;
+ column = 0;
+ goto specificCell;
+ case NAVDIR_LASTCHILD:
+ if (TA->t->nColumns == 0)
+ goto nowhere;
+ column = TA->t->nColumns - 1;
+ goto specificCell;
+ }
+ // TODO differentiate between unsupported navigation directions and invalid navigation directions
+ goto nowhere;
+ case ROLE_SYSTEM_CELL:
+ row = what.row;
+ column = what.column;
+ switch (navDir) {
+ case NAVDIR_UP:
+ if (row == 0) // can't go up
+ goto nowhere;
+ row--;
+ goto specificCell;
+ case NAVDIR_DOWN:
+ if (row == TA->t->count - 1) // can't go down
+ goto nowhere;
+ row++;
+ goto specificCell;
+ case NAVDIR_LEFT:
+ case NAVDIR_PREVIOUS:
+ if (column == 0) // can't go left
+ goto nowhere;
+ column--;
+ goto specificCell;
+ case NAVDIR_RIGHT:
+ case NAVDIR_NEXT:
+ if (column == TA->t->nColumns - 1) // can't go right
+ goto nowhere;
+ column++;
+ goto specificCell;
+// TODO this doesn't actually exist yet https://msdn.microsoft.com/en-us/library/ms971325 talks about it
+// case NAVDIR_PARENT:
+// goto specificRow;
+ case NAVDIR_FIRSTCHILD:
+ case NAVDIR_LASTCHILD:
+ goto nowhere;
+ }
+ // TODO differentiate between unsupported navigation directions and invalid navigation directions
+ goto nowhere;
}
- return IAccessible_accNavigate(TA->std, navDir, varStart, pvarEndUpAt);
+ // TODO actually do this right
+ // TODO un-GetLastError() this
+ panic("impossible blah blah blah TODO write this");
+ return E_FAIL;
+
+nowhere:
+ pvarEndUpAt->vt = VT_EMPTY;
+ return S_FALSE;
+
+tableItself:
+ pvarEndUpAt->vt = VT_DISPATCH;
+ pvarEndUpAt->pdispVal = (IDispatch *) newTableAcc(TA->t, ROLE_SYSTEM_TABLE, -1, -1);
+ return S_OK;
+
+specificRow:
+ pvarEndUpAt->vt = VT_DISPATCH;
+ pvarEndUpAt->pdispVal = (IDispatch *) newTableAcc(TA->t, ROLE_SYSTEM_ROW, row, -1);
+ return S_OK;
+
+specificCell:
+ pvarEndUpAt->vt = VT_DISPATCH;
+ pvarEndUpAt->pdispVal = (IDispatch *) newTableAcc(TA->t, ROLE_SYSTEM_CELL, row, column);
+ return S_OK;
}
// TODO should this ever return parents?