19#include <wx/settings.h>
29#if wxUSE_ACCESSIBILITY
44 void SetCurrentLine(
int row);
46 bool LineToId(
int line,
int & childId);
47 bool IdToLine(
int childId,
int & line);
51 wxAccStatus
HitTest(
const wxPoint & pt,
int *childId, wxAccessible **childObject)
override;
55 wxAccStatus GetChild(
int childId, wxAccessible **child)
override;
58 wxAccStatus GetChildCount(
int *childCount)
override;
66 wxAccStatus GetDefaultAction(
int childId, wxString *actionName)
override;
69 wxAccStatus GetDescription(
int childId, wxString *description)
override;
75 wxAccStatus GetFocus(
int *childId, wxAccessible **child)
override;
78 wxAccStatus GetHelpText(
int childId, wxString *helpText)
override;
82 wxAccStatus GetKeyboardShortcut(
int childId, wxString *shortcut)
override;
86 wxAccStatus GetLocation(wxRect & rect,
int elementId)
override;
89 wxAccStatus Navigate(wxNavDir navDir,
int fromId,
90 int *toId, wxAccessible **toObject)
override;
93 wxAccStatus GetName(
int childId, wxString *
name)
override;
96 wxAccStatus GetParent(wxAccessible **parent)
override;
99 wxAccStatus GetRole(
int childId, wxAccRole *role)
override;
109 wxAccStatus GetSelections(wxVariant *selections)
override;
112 wxAccStatus GetState(
int childId,
long *state)
override;
116 wxAccStatus GetValue(
int childId, wxString *strValue)
override;
118#if defined(__WXMAC__)
120 wxAccStatus Select(
int childId, wxAccSelectionFlags selectFlags)
override;
131#define KV_BITMAP_SIZE 16
132#define KV_LEFT_MARGIN 2
133#define KV_COLUMN_SPACER 5
134#define KV_VSCROLL_WIDTH 16
139BEGIN_EVENT_TABLE(
KeyView, wxVListBox)
159: wxVListBox(parent,
id, pos,
size, wxBORDER_THEME | wxHSCROLL | wxVSCROLL),
163#if wxUSE_ACCESSIBILITY
165 SetAccessible(mAx =
safenew KeyViewAx(
this));
168 SetMinSize({-1, 150});
197 return wxVListBox::GetName();
207 if (index < 0 || index >= (
int)
mNodes.size())
210 return wxEmptyString;
213 return mNodes[index].label;
223 if (index < 0 || index >= (
int)
mNodes.size())
226 return wxEmptyString;
248 int cnt = (int)
mNodes.size();
251 for (
int i = 0; i < cnt; i++)
269 if (index < 0 || index >= (
int)
mNodes.size())
275 return mNodes[index].name;
284 int cnt = (int)
mNodes.size();
287 for (
int i = 0; i < cnt; i++)
304 int cnt = (int)
mNodes.size();
307 for (
int i = 0; i < cnt; i++)
325 if (index < 0 || index >= (
int)
mNodes.size())
341 if (index < 0 || index >= (
int)
mNodes.size())
348 return !
mNodes[index].isparent;
358 if (index < 0 || index >= (
int)
mNodes.size())
401 if (index == wxNOT_FOUND)
419 if (index != wxNOT_FOUND)
429 int depth = node.
depth;
432 for (
int i = node.
index - 1; i >= 0 && depth > 1; i--)
434 if (
mNodes[i].depth < depth)
453 if (index != wxNOT_FOUND)
460 if ((GetSelection() == wxNOT_FOUND))
486 if (index != wxNOT_FOUND)
493 if ((GetSelection() == wxNOT_FOUND))
505 int cnt = (int)
mNodes.size();
508 for (
int i = 0; i < cnt; i++)
527 int cnt = (int)
mNodes.size();
530 for (
int i = 0; i < cnt; i++)
555 int cnt = (int)
mNodes.size();
556 for (
int i = 0; i < cnt; i++)
564 GetTextExtent(node.
category, &x, &y);
569 GetTextExtent(node.
prefix, &x, &y);
586 GetTextExtent(
label, &x, &y);
605 wxRect r = GetClientRect();
615 mScrollX = GetScrollPos(wxHORIZONTAL);
617 if (
mWidth <= r.GetWidth())
620 SetScrollbar(wxHORIZONTAL, 0, 0, 0);
640 const std::vector<NormalizedKeyString> & keys,
663 int cnt = (int)
names.size();
664 for (
int i = 0; i < cnt; i++)
670 wxString cat = categories[i].Translation();
671 wxString pfx = prefixes[i].Translation();
676 cat.Append(
wxT(
" "));
712 node.
index = nodecnt++;
715 node.
depth = depth++;
723 GetTextExtent(cat, &x, &y);
752 node.
index = nodecnt++;
755 node.
depth = depth++;
782 auto label = labels[i];
789 node.
index = nodecnt++;
809 GetTextExtent(
label, &x, &y);
816 for (
int j = 0; j <
mNodes.size(); j++)
819 wxLogDebug(
wxT(
"NODE line %4d index %4d depth %1d open %1d parent %1d cat %1d pfx %1d name %s STR %s | %s | %s"),
841 if ((GetSelection()==wxNOT_FOUND) && bSort )
853 int cnt = (int)
mNodes.size();
861 for (
int i = 0; i < cnt; i++)
866 node.
line = wxNOT_FOUND;
877 searchit = node.
label.Lower() +
883 searchit = node.
label.Lower();
890 if (searchit.Find(
mFilter) == wxNOT_FOUND)
902 ((searchit.length() > 1) &&
903 ((wxString)(searchit.GetChar(searchit.length() - 2)) !=
wxT(
"+")))))
913 std::vector<KeyNode*> queue;
914 int depth = node.
depth;
928 for (
int j = node.
index - 1; j >= 0 && depth > 0; j--)
931 if (
mNodes[j].depth < depth)
936 for (
int k = (
int)
mLines.size() - 1; k >= 0; k--)
952 queue.push_back(&
mNodes[j]);
962 for (
int j = (
int) queue.size() - 1; j >= 0; j--)
964 queue[j]->isopen =
true;
965 queue[j]->line = linecnt++;
966 mLines.push_back(queue[j]);
971 node.
line = linecnt++;
978 for (
int i = 0; i < cnt; i++)
983 node.
line = wxNOT_FOUND;
995 node.
line = linecnt++;
1001 bool iscat = node.
iscat;
1002 bool ispfx = node.
ispfx;
1028 node.
line = linecnt++;
1063 for (
int i = 0; i < (int)
mLines.size(); i++)
1070 for (
int j = 0; j <
mLines.size(); j++)
1073 wxLogDebug(
wxT(
"LINE line %4d index %4d depth %1d open %1d parent %1d cat %1d pfx %1d name %s STR %s | %s | %s"),
1089 SetItemCount(
mLines.size());
1092#if wxUSE_ACCESSIBILITY
1112#if wxUSE_ACCESSIBILITY
1114 mAx->SetCurrentLine(line);
1122 wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, GetId());
1123 event.SetEventObject(
this);
1125 (void)GetEventHandler()->ProcessEvent(event);
1134 if (line < 0 || line >= (
int)
mLines.size())
1139 return mLines[line]->index;
1148 if (index < 0 || index >= (
int)
mNodes.size())
1153 return mNodes[index].line;
1184 r.width = wxMax(
mWidth, r.width);
1188 if (IsSelected(line))
1193 dc.SetPen(*wxTRANSPARENT_PEN);
1194 dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT)));
1195 dc.DrawRectangle(r);
1205 dc.DrawRectangle(r2);
1212 dc.SetPen(*wxTRANSPARENT_PEN);
1213 dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
1214 dc.DrawRectangle(r);
1216 dc.DrawRectangle(r2);
1222 dc.SetPen(wxColour(240, 240, 240));
1223 AColor::Line(dc, r.GetLeft(), r.GetBottom(), r.GetRight(), r.GetBottom());
1225 AColor::Line(dc, r2.GetLeft(), r2.GetBottom(), r2.GetRight(), r2.GetBottom());
1241 dc.SetFont(GetFont());
1244 if (IsSelected(line) &&
FindFocus() ==
this)
1246 dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOXHIGHLIGHTTEXT));
1250 dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_LISTBOXTEXT));
1262 wxCoord by = rect.y;
1269 dc.SetBrush(*wxTRANSPARENT_BRUSH);
1270 dc.SetPen(*wxBLACK_PEN);
1271 dc.DrawRectangle(bx + 3, by + 4, 9, 9);
1287 dc.DrawText(node->
key.
Display(), x , rect.y);
1296 if (!node->
prefix.empty())
1336#if wxUSE_ACCESSIBILITY
1338 mAx->SetCurrentLine(event.GetInt());
1354 if (GetSelection() != wxNOT_FOUND)
1356 RefreshRow(GetSelection());
1359#if wxUSE_ACCESSIBILITY
1361 mAx->SetCurrentLine(GetSelection());
1375 if (GetSelection() != wxNOT_FOUND)
1377 RefreshRow(GetSelection());
1398 if (event.GetOrientation() != wxHORIZONTAL)
1407 SetScrollPos(wxHORIZONTAL,
mScrollX);
1419 int line = GetSelection();
1421 int keycode =
event.GetKeyCode();
1429 if (line == wxNOT_FOUND)
1446 size_t topline = GetVisibleBegin();
1452 ScrollToRow(topline);
1460 for (
int i = line - 1; i >= 0; i--)
1463 if (
mLines[i]->depth < node->depth)
1482 if (line == wxNOT_FOUND)
1498 if (line < (
int)
mLines.size() - 1)
1510 size_t topline = GetVisibleBegin();
1516 ScrollToRow(topline);
1532 int cnt = (int)
mLines.size();
1536 if (line == wxNOT_FOUND)
1543 for (
int i = line + 1; i < cnt; i++)
1562 if (
label.Left(1).IsSameAs(keycode,
false))
1577 for (
int i = 0; i < line; i++)
1596 if (
label.Left(1).IsSameAs(keycode,
false))
1634 wxPoint pos =
event.GetPosition();
1637 int line = VirtualHitTest(pos.y);
1640 if (line != wxNOT_FOUND)
1652 size_t topline = GetVisibleBegin();
1658 ScrollToRow(topline);
1694 unsigned int k1UInt= 0xffffffff;
1695 unsigned int k2UInt= 0xffffffff;
1702 k1UInt = (
unsigned int) t1->
line;
1706 k2UInt = (
unsigned int) t2->
line;
1708 if( k1UInt < k2UInt )
1710 if( k1UInt > k2UInt )
1724 wxString k1 = t1->
label;
1725 wxString k2 = t2->
label;
1792#if wxUSE_ACCESSIBILITY
1798KeyView::HasChildren(
int line)
1801 if (line < 0 || line >= (
int)
mLines.size())
1807 return mLines[line]->isparent;
1814KeyView::IsExpanded(
int line)
1817 if (line < 0 || line >= (
int)
mLines.size())
1823 return mLines[line]->isopen;
1830KeyView::GetLineHeight(
int line)
1833 if (line < 0 || line >= (
int)
mLines.size())
1839 return OnGetRowHeight(line);
1848KeyView::GetValue(
int line)
1851 if (line < 0 || line >= (
int)
mLines.size())
1854 return wxEmptyString;
1875 value =
key +
wxT(
" ") + value;
1879 value = value +
wxT(
" ") +
key;
1890KeyView::GetViewType()
1898KeyViewAx::KeyViewAx(
KeyView *view)
1910KeyViewAx::ListUpdated()
1912 NotifyEvent(wxACC_EVENT_OBJECT_REORDER,
1923KeyViewAx::SetCurrentLine(
int line)
1929 NotifyEvent(wxACC_EVENT_OBJECT_SELECTIONREMOVE,
1939 if (line != wxNOT_FOUND)
1942 LineToId(line, mLastId);
1946 NotifyEvent(wxACC_EVENT_OBJECT_FOCUS,
1953 NotifyEvent(wxACC_EVENT_OBJECT_SELECTION,
1965KeyViewAx::IdToLine(
int childId,
int & line)
1967 if (childId == wxACC_SELF)
1976 if (line < 0 || line >= (
int) mView->GetItemCount())
1989KeyViewAx::LineToId(
int line,
int & childId)
1992 if (line < 0 || line >= (
int) mView->GetItemCount())
1995 childId = wxACC_SELF;
2011 *childObject = NULL;
2013 wxPoint pos = mView->ScreenToClient(pt);
2016 int line = mView->HitTest(pos);
2019 if (line != wxNOT_FOUND)
2021 LineToId(line, *childId);
2026 return wxACC_NOT_IMPLEMENTED;
2032KeyViewAx::GetChild(
int childId, wxAccessible** child)
2034 if (childId == wxACC_SELF)
2048KeyViewAx::GetChildCount(
int *childCount)
2050 *childCount = (int) mView->GetItemCount();
2062KeyViewAx::GetDefaultAction(
int WXUNUSED(childId), wxString *actionName)
2064 actionName->clear();
2071KeyViewAx::GetDescription(
int WXUNUSED(childId), wxString *description)
2073 description->clear();
2080KeyViewAx::GetHelpText(
int WXUNUSED(childId), wxString *helpText)
2090KeyViewAx::GetKeyboardShortcut(
int WXUNUSED(childId), wxString *shortcut)
2100KeyViewAx::GetLocation(wxRect & rect,
int elementId)
2104 if (IdToLine(elementId, line))
2106 if (!mView->IsVisible(line))
2113 rectLine.width = mView->GetClientSize().GetWidth();
2116 for (
int i = (
int) mView->GetVisibleBegin(); i <= line; i++)
2118 wxCoord hLine = mView->GetLineHeight(i);
2120 rectLine.height = hLine;
2123 wxPoint margins = mView->GetMargins();
2124 rect.Deflate(margins.x, margins.y);
2125 rectLine.y += hLine;
2128 rect.SetPosition(mView->ClientToScreen(rect.GetPosition()));
2132 rect = mView->GetRect();
2133 rect.SetPosition(mView->GetParent()->ClientToScreen(rect.GetPosition()));
2140KeyViewAx::Navigate(wxNavDir WXUNUSED(navDir),
2141 int WXUNUSED(fromId),
2142 int *WXUNUSED(toId),
2143 wxAccessible **WXUNUSED(toObject))
2145 return wxACC_NOT_IMPLEMENTED;
2150KeyViewAx::GetName(
int childId, wxString *
name)
2154 if (!IdToLine(childId, line))
2156 *
name = mView->GetName();
2160 if (IdToLine(childId, line))
2162 *
name = mView->GetValue(line);
2170KeyViewAx::GetParent(wxAccessible ** WXUNUSED(parent))
2172 return wxACC_NOT_IMPLEMENTED;
2177KeyViewAx::GetRole(
int childId, wxAccRole *role)
2179 if (childId == wxACC_SELF)
2181#if defined(__WXMSW__)
2182 *role = mView->GetViewType() ==
ViewByTree ? wxROLE_SYSTEM_OUTLINE : wxROLE_SYSTEM_LIST;
2185#if defined(__WXMAC__)
2186 *role = wxROLE_SYSTEM_GROUPING;
2191#if defined(__WXMAC__)
2192 *role = wxROLE_SYSTEM_TEXT;
2194 *role = mView->GetViewType() ==
ViewByTree ? wxROLE_SYSTEM_OUTLINEITEM : wxROLE_SYSTEM_LISTITEM;
2210KeyViewAx::GetSelections(wxVariant *selections)
2214 LineToId(mView->GetSelection(),
id);
2216 *selections = (long)
id;
2223KeyViewAx::GetState(
int childId,
long *state)
2225 int flag = wxACC_STATE_SYSTEM_FOCUSABLE;
2228 if (!IdToLine(childId, line))
2230 *state = wxACC_STATE_SYSTEM_FOCUSABLE;
2235#if defined(__WXMSW__)
2236 int selected = mView->GetSelection();
2238 flag |= wxACC_STATE_SYSTEM_SELECTABLE;
2240 if (line == selected)
2242 flag |= wxACC_STATE_SYSTEM_FOCUSED |
2243 wxACC_STATE_SYSTEM_SELECTED;
2246 if (mView->HasChildren(line))
2248 flag |= mView->IsExpanded(line) ?
2249 wxACC_STATE_SYSTEM_EXPANDED :
2250 wxACC_STATE_SYSTEM_COLLAPSED;
2254#if defined(__WXMAC__1)
2255 if (mGrid->IsInSelection(row, col))
2257 flag |= wxACC_STATE_SYSTEM_SELECTED;
2260 if (mGrid->GetGridCursorRow() == row && mGrid->GetGridCursorCol() == col)
2262 flag |= wxACC_STATE_SYSTEM_FOCUSED;
2265 if (mGrid->IsReadOnly(row, col))
2267 flag |= wxACC_STATE_SYSTEM_UNAVAILABLE;
2279KeyViewAx::GetValue(
int childId, wxString *strValue)
2285 if (!IdToLine(childId, line))
2287 return wxACC_NOT_IMPLEMENTED;
2290#if defined(__WXMSW__)
2293 KeyNode *node = mView->mLines[line];
2294 strValue->Printf(
wxT(
"%d"), node->
depth - 1);
2298 return wxACC_NOT_IMPLEMENTED;
2301#if defined(__WXMAC__)
2302 return GetName(childId, strValue);
2306#if defined(__WXMAC__)
2309KeyViewAx::Select(
int childId, wxAccSelectionFlags selectFlags)
2315 if (GetRowCol(childId, row, col))
2318 if (selectFlags & wxACC_SEL_TAKESELECTION)
2320 mGrid->SetGridCursor(row, col);
2323 mGrid->SelectBlock(row, col, row, col, selectFlags & wxACC_SEL_ADDSELECTION);
2335KeyViewAx::GetFocus(
int * WXUNUSED(childId), wxAccessible **child)
std::vector< CommandID > CommandIDs
static wxString CommandTranslated
std::vector< TranslatableString > TranslatableStrings
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
static void DrawFocus(wxDC &dc, wxRect &r)
Provides multiple views of keyboard shortcuts.
bool CanSetKey(int index) const
std::vector< KeyNode * > mLines
void OnSetFocus(wxFocusEvent &event)
void OnLeftDown(wxMouseEvent &event)
void OnDrawBackground(wxDC &dc, const wxRect &rect, size_t line) const override
int GetIndexByName(const CommandID &name) const
int GetIndexByKey(const NormalizedKeyString &key) const
void OnKillFocus(wxFocusEvent &event)
void OnDrawItem(wxDC &dc, const wxRect &rect, size_t line) const override
bool SetKey(int index, const NormalizedKeyString &key)
void OnSelected(wxCommandEvent &event)
wxString GetLabel(int index) const
void OnSize(wxSizeEvent &event)
void RefreshLines(bool bSort=true)
void SelectNode(int index)
void SetView(ViewByType type)
void SetFilter(const wxString &filter)
static bool CmpKeyNodeByTree(KeyNode *n1, KeyNode *n2)
wxCoord OnMeasureItem(size_t line) const override
void OnScroll(wxScrollWinEvent &event)
std::vector< KeyNode > mNodes
wxString GetFullLabel(int index) const
void OnKeyDown(wxKeyEvent &event)
static bool CmpKeyNodeByName(KeyNode *n1, KeyNode *n2)
int IndexToLine(int index) const
NormalizedKeyString GetKey(int index) const
void RefreshBindings(const CommandIDs &names, const TranslatableStrings &categories, const TranslatableStrings &prefixes, const TranslatableStrings &labels, const std::vector< NormalizedKeyString > &keys, bool bSort)
bool SetKeyByName(const CommandID &name, const NormalizedKeyString &key)
wxString GetName() const override
CommandID GetNameByKey(const NormalizedKeyString &key) const
int LineToIndex(int line) const
static bool CmpKeyNodeByKey(KeyNode *n1, KeyNode *n2)
TranslatableString & Strip(unsigned options=MenuCodes) &
wxString Translation() const
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
void SetFocus(const WindowPlacement &focus)
Set the window that accepts keyboard input.
std::unique_ptr< WindowPlacement > FindFocus()
Find the window that is accepting keyboard input, if any.
wxString Display(bool usesSpecialChars=false) const