int LineEdit::PlaceCaretNoG(int newcursor, bool sel) { if(newcursor > total) newcursor = total; Point p = GetColumnLine(newcursor); if(sel) { if(anchor < 0) { anchor = cursor; } if(rectsel || rectsel != dorectsel) Refresh(); else RefreshLines(p.y, GetLine(cursor)); rectsel = dorectsel; } else { if(anchor >= 0) { if(rectsel || dorectsel) Refresh(); else RefreshLines(GetLine(cursor), GetLine(anchor)); anchor = -1; } rectsel = false; } RefreshLine(GetColumnLine(cursor).y); RefreshLine(p.y); cursor = newcursor; ScrollIntoCursor(); PlaceCaret0(p); SelectionChanged(); WhenSel(); if(IsAnySelection()) SetSelectionSource(ClipFmtsText()); return p.x; }
void DocEdit::PlaceCaret(int newpos, bool select) { if(newpos > GetLength()) newpos = GetLength(); int z = GetLine(newpos); if(select) { if(anchor < 0) { anchor = cursor; } RefreshLines(z, GetLine(cursor)); } else if(anchor >= 0) { RefreshLines(GetLine(cursor), GetLine(anchor)); anchor = -1; } cursor = newpos; PlaceCaret(true); SelectionChanged(); if(IsSelection()) SetSelectionSource(ClipFmtsText()); }
int LineEdit::PlaceCaretNoG(int newcursor, bool sel) { if(newcursor > total) newcursor = total; Point p = GetColumnLine(newcursor); if(sel) { if(anchor < 0) { anchor = cursor; } RefreshLines(p.y, GetLine(cursor)); } else if(anchor >= 0) { RefreshLines(GetLine(cursor), GetLine(anchor)); anchor = -1; } cursor = newcursor; ScrollIntoCursor(); PlaceCaret0(p); SelectionChanged(); WhenSel(); if(IsSelection()) SetSelectionSource(ClipFmtsText()); return p.x; }
// // Sets the view type // void KeyView::SetView(ViewByType type) { int index = LineToIndex(GetSelection()); // Handle an existing selection if (index != wxNOT_FOUND) { // Cache the currently selected node KeyNode & node = mNodes[index]; // Expand branches if switching to Tree view and a line // is currently selected if (type == ViewByTree) { // Cache the node's depth int depth = node.depth; // Search for its parents, setting each one as open for (int i = node.index - 1; i >= 0 && depth > 1; i--) { if (mNodes[i].depth < depth) { mNodes[i].isopen = true; depth = mNodes[i].depth; } } } } // Unselect any currently selected line...do even if none selected SelectNode(-1); // Save new type mViewType = type; // Refresh the view lines RefreshLines(); // Reselect old node (if possible) if (index != wxNOT_FOUND) { SelectNode(index); } return; }
// // Handle the wxEVT_LEFT_DOWN event // void KeyView::OnLeftDown(wxMouseEvent & event) { // Only check if for tree view if (mViewType != ViewByTree) { // Allow further processing (important for focus handling) event.Skip(); return; } // Get the mouse position when the button was pressed wxPoint pos = event.GetPosition(); // And see if it was on a line within the view int line = HitTest(pos); // It was on a line if (line != wxNOT_FOUND) { KeyNode *node = mLines[line]; // Toggle the open state if this is a parent node if (node->isparent) { // Toggle state node->isopen = !node->isopen; // Don't want the view to scroll vertically, so remember the current // top line. size_t topline = GetVisibleBegin(); // Refresh the view now that the number of lines have changed RefreshLines(); // Reset the original top line ScrollToLine(topline); // And make sure current line is still selected SelectNode(LineToIndex(line)); } } // Allow further processing (important for focus handling) event.Skip(); }
// // Collapse all branches // void KeyView::CollapseAll() { int cnt = (int) mNodes.GetCount(); // Set all parent nodes to closed for (int i = 0; i < cnt; i++) { KeyNode & node = mNodes[i]; if (node.isparent) { node.isopen = false; } } RefreshLines(); }
// // Expand all branches // void KeyView::ExpandAll() { int cnt = (int) mNodes.GetCount(); // Set all parent nodes to open for (int i = 0; i < cnt; i++) { KeyNode & node = mNodes[i]; if (node.isparent) { node.isopen = true; } } RefreshLines(); }
bool wxVListBox::SelectRange(size_t from, size_t to) { wxCHECK_MSG( m_selStore, false, _T("SelectRange() may only be used with multiselection listbox") ); // make sure items are in correct order if ( from > to ) { size_t tmp = from; from = to; to = tmp; } wxCHECK_MSG( to < GetItemCount(), false, _T("SelectRange(): invalid item index") ); wxArrayInt changed; if ( !m_selStore->SelectRange(from, to, true, &changed) ) { // too many items have changed, we didn't record them in changed array // so we have no choice but to refresh everything between from and to RefreshLines(from, to); } else // we've got the indices of the changed items { const size_t count = changed.GetCount(); if ( !count ) { // nothing changed return false; } // refresh just the lines which have really changed for ( size_t n = 0; n < count; n++ ) { RefreshLine(changed[n]); } } // something changed return true; }
// // Sets the filter // void KeyView::SetFilter(const wxString & filter) { int index = LineToIndex(GetSelection()); // Unselect any currently selected line...do even if none selected SelectNode(-1); // Save the filter mFilter = filter.Lower(); // Refresh the view lines RefreshLines(); // Reselect old node (if possible) if (index != wxNOT_FOUND) { SelectNode(index); } }
// // Process a new set of bindings // void KeyView::RefreshBindings(const wxArrayString & names, const wxArrayString & categories, const wxArrayString & prefixes, const wxArrayString & labels, const wxArrayString & keys) { // Start clean mNodes.Clear(); // Same as in RecalcExtents() but do it inline mLineHeight = 0; mKeyWidth = 0; mCommandWidth = 0; wxString lastcat; wxString lastpfx; int nodecnt = 0; int depth = 1; bool incat = false; bool inpfx = false; // Examine all names...all arrays passed have the same indexes int cnt = (int) names.GetCount(); for (int i = 0; i < cnt; i++) { wxString name = names[i]; int x, y; // Remove any menu code from the category and prefix wxString cat = wxMenuItem::GetLabelFromText(categories[i]); wxString pfx = wxMenuItem::GetLabelFromText(prefixes[i]); // Append "Menu" this node is for a menu title if (cat != wxT("Command")) { cat.Append(wxT(" ")); cat += _("Menu"); } // Process a new category if (cat != lastcat) { // A new category always finishes any current subtree if (inpfx) { // Back to category level depth--; inpfx = false; } // Only time this is not true is during the first iteration if (incat) { // Back to root level depth--; incat = false; } // Remember for next iteration lastcat = cat; // Add a new category node if (cat != wxEmptyString) { KeyNode node; // Fill in the node info node.name = wxEmptyString; // don't associate branches with a command node.category = cat; node.prefix = pfx; node.label = cat; node.index = nodecnt++; node.iscat = true; node.isparent = true; node.depth = depth++; // Add it to the tree mNodes.Add(node); incat = true; // Measure category GetTextExtent(cat, &x, &y); mLineHeight = wxMax(mLineHeight, y); mCommandWidth = wxMax(mCommandWidth, x); } } // Process a new prefix if (pfx != lastpfx) { // Done with prefix branch if (inpfx) { depth--; inpfx = false; } // Remember for next iteration lastpfx = pfx; // Add a new prefix node if (pfx != wxEmptyString) { KeyNode node; // Fill in the node info node.name = wxEmptyString; // don't associate branches with a command node.category = cat; node.prefix = pfx; node.label = pfx; node.index = nodecnt++; node.ispfx = true; node.isparent = true; node.depth = depth++; // Add it to the tree mNodes.Add(node); inpfx = true; } } // Add the key entry KeyNode node; node.category = cat; node.prefix = pfx; // Labels for undo and redo change according to the last command // which can be undone/redone, so give them a special check in order // not to confuse users if (name == wxT("Undo")) { node.label = _("Undo"); } else if (name == wxT("Redo")) { node.label = _("Redo"); } else { // Strip any menu codes from label node.label = wxMenuItem::GetLabelFromText(labels[i].BeforeFirst(wxT('\t'))); } // Fill in remaining info node.name = name; node.key = KeyStringDisplay(keys[i]); node.index = nodecnt++; node.depth = depth; // Add it to the tree mNodes.Add(node); // Measure key GetTextExtent(node.key, &x, &y); mLineHeight = wxMax(mLineHeight, y); mKeyWidth = wxMax(mKeyWidth, x); // Prepend prefix for all view types to determine maximum // column widths wxString label = node.label; if (!node.prefix.IsEmpty()) { label = node.prefix + wxT(" - ") + label; } // Measure label GetTextExtent(label, &x, &y); mLineHeight = wxMax(mLineHeight, y); mCommandWidth = wxMax(mCommandWidth, x); } #if 0 // For debugging for (int j = 0; j < mNodes.GetCount(); j++) { KeyNode & node = mNodes[j]; wxLogDebug(wxT("NODE line %4d index %4d depth %1d open %1d parent %1d cat %1d pfx %1d name %s STR %s | %s | %s"), node.line, node.index, node.depth, node.isopen, node.isparent, node.iscat, node.ispfx, node.name.c_str(), node.category.c_str(), node.prefix.c_str(), node.label.c_str()); } #endif // Update horizontal scrollbar UpdateHScroll(); // Refresh the view lines RefreshLines(); }
// // Handle the wxEVT_KEY_DOWN event // void KeyView::OnKeyDown(wxKeyEvent & event) { int line = GetSelection(); int keycode = event.GetKeyCode(); switch (keycode) { // The LEFT key moves selection to parent or collapses selected // node if it is expanded. case WXK_LEFT: { // Nothing selected...nothing to do if (line == wxNOT_FOUND) { // Allow further processing event.Skip(); break; } KeyNode *node = mLines[line]; // Collapse the node if it is open if (node->isopen) { // No longer open node->isopen = false; // Don't want the view to scroll vertically, so remember the current // top line. size_t topline = GetVisibleBegin(); // Refresh the view now that the number of lines have changed RefreshLines(); // Reset the original top line ScrollToLine(topline); // And make sure current line is still selected SelectNode(LineToIndex(line)); } else { // Move selection to the parent of this node for (int i = line - 1; i >= 0; i--) { // Found the parent if (mLines[i]->depth < node->depth) { // So select it SelectNode(LineToIndex(i)); break; } } } // Further processing of the event is not wanted // (we didn't call event.Skip() } break; // The RIGHT key moves the selection to the first child or expands // the node if it is a parent. case WXK_RIGHT: { // Nothing selected...nothing to do if (line == wxNOT_FOUND) { // Allow further processing event.Skip(); break; } KeyNode *node = mLines[line]; // Only want parent nodes if (node->isparent) { // It is open so move select to first child if (node->isopen) { // But only if there is one if (line < (int) mLines.GetCount() - 1) { SelectNode(LineToIndex(line + 1)); } } else { // Node is now open node->isopen = true; // Don't want the view to scroll vertically, so remember the current // top line. size_t topline = GetVisibleBegin(); // Refresh the view now that the number of lines have changed RefreshLines(); // Reset the original top line ScrollToLine(topline); // And make sure current line is still selected SelectNode(LineToIndex(line)); } } // Further processing of the event is not wanted // (we didn't call event.Skip() } break; // Move selection to next node whose 1st character matches // the keycode default: { int cnt = (int) mLines.GetCount(); bool found = false; // Search the entire list if not is currently selected if (line == wxNOT_FOUND) { line = cnt; } else { // Search from the node following the current one for (int i = line + 1; i < cnt; i++) { wxString label; // Get the string to search based on view type if (mViewType == ViewByTree) { label = GetLabel(LineToIndex(i)); } else if (mViewType == ViewByName) { label = GetFullLabel(LineToIndex(i)); } else if (mViewType == ViewByKey) { label = GetKey(LineToIndex(i)); } // Move selection if they match if (label.Left(1).IsSameAs(keycode, false)) { SelectNode(LineToIndex(i)); found = true; break; } } } // A match wasn't found if (!found) { // So scan from the start of the list to the current node for (int i = 0; i < line; i++) { wxString label; // Get the string to search based on view type if (mViewType == ViewByTree) { label = GetLabel(LineToIndex(i)); } else if (mViewType == ViewByName) { label = GetFullLabel(LineToIndex(i)); } else if (mViewType == ViewByKey) { label = GetKey(LineToIndex(i)); } // Move selection if they match if (label.Left(1).IsSameAs(keycode, false)) { SelectNode(LineToIndex(i)); found = true; break; } } } // A node wasn't found so allow further processing if (!found) { event.Skip(); } // Otherwise, further processing of the event is not wanted // (we didn't call event.Skip() } } }