void OnKeyEnd(ref Position cur, ref Position next) { next.First = dataView.Buffer.Size; next.Second = dataView.Buffer.Size; next.Digit = 0; okp_showType = DataViewDisplay.ShowType.End; }
void OnKeyHome(ref Position cur, ref Position next) { next.First = 0; next.Second = 0; next.Digit = 0; okp_showType = DataViewDisplay.ShowType.Start; }
void OnKeyPageDown(ref Position cur, ref Position next) { long offset = cur.Second; int digit = cur.Digit; offset += okp_bpr * (int)dvDisplay.VScroll.Adjustment.PageIncrement; if (offset > dataView.Buffer.Size) { offset = dataView.Buffer.Size; //digit = 0; } okp_showType = DataViewDisplay.ShowType.Cursor; next.First = offset; next.Second = offset; next.Digit = digit; }
///<summary>Handle key presses</summary> internal void OnKeyPress(object o, KeyPressEventArgs args) { Gdk.EventKey e = args.Event; okp_focusArea = null; bool shiftPressed = false; // find focused area okp_focusArea = dvDisplay.Layout.AreaGroup.FocusedArea; // if no area has the focus, give it to the first one applicable if (okp_focusArea == null) { dvDisplay.Layout.AreaGroup.CycleFocus(); okp_focusArea = dvDisplay.Layout.AreaGroup.FocusedArea; } // if still no area got the focus give up if (okp_focusArea == null) { return; } okp_bpr = okp_focusArea.BytesPerRow; okp_dpb = okp_focusArea.DigitsPerByte; okp_showType = DataViewDisplay.ShowType.Closest; if ((e.State & Gdk.ModifierType.ShiftMask) == Gdk.ModifierType.ShiftMask) { shiftPressed = true; } UpdateSelection(true); Position cur = new Position(); if (shiftPressed || !dvDisplay.Layout.AreaGroup.Selection.IsEmpty()) { cur = selEndPos; cur.Digit = 0; } else { cur = selStartPos; } Position next = new Position(); // set next to cur in case it is not set by a keypress handler next = cur; // handle keys bool specialKey = false; switch (e.Key) { case Gdk.Key.Up: OnKeyUp(ref cur, ref next); break; case Gdk.Key.Down: OnKeyDown(ref cur, ref next); break; case Gdk.Key.Left: OnKeyLeft(ref cur, ref next); break; case Gdk.Key.Right: if (shiftPressed) { cur.Digit = okp_dpb - 1; } OnKeyRight(ref cur, ref next); break; case Gdk.Key.Page_Up: OnKeyPageUp(ref cur, ref next); break; case Gdk.Key.Page_Down: OnKeyPageDown(ref cur, ref next); break; case Gdk.Key.Home: OnKeyHome(ref cur, ref next); break; case Gdk.Key.End: OnKeyEnd(ref cur, ref next); break; case Gdk.Key.Insert: OnKeyInsert(); break; case Gdk.Key.Tab: OnKeyTab(); // cycling through the areas may change the current cursor digit // (note however that we don't want to call EvaluateSelection()->SetCursor() // because that will reset the digit of all areas. So we just update // selStartPos.Digit here and set specialKey = true to avoid calling SetCursor()...) selStartPos.Digit = dvDisplay.Layout.AreaGroup.CursorDigit; specialKey = true; break; case Gdk.Key.BackSpace: OnKeyBackspace(); return; // OnKeyBackspace() handles drawing default: OnKeyDefault(e, ref cur, ref next, out specialKey); break; } // end switch() //System.Console.WriteLine("Current: {0},{1},{2} Next: {3},{4},{5}", cur.First, cur.Second, cur.Digit, next.First, next.Second, next.Digit); // if just a special key was pressed (eg shift, ctrl, tab or a digit the area doesn't understand don't do anything) if (specialKey) { return; } if (shiftPressed) { next.Digit = 0; if (selStartPos.First == selStartPos.Second) { selStartPos.First--; } selEndPos = next; } else { selEndPos = next; selStartPos = next; } //System.Console.WriteLine("Start: {0},{1},{2} End: {3},{4},{5}", selStartPos.First, selStartPos.Second, selStartPos.Digit, selEndPos.First, selEndPos.Second, selEndPos.Digit); EvaluateSelection(okp_showType); }
///<summary> /// Sets the selection and the cursor position according to the values of selStartPos, selEndPos ///</summary> private void EvaluateSelection(DataViewDisplay.ShowType showType) { //System.Console.WriteLine("Evaluate (1) Start: {0},{1},{2} End: {3},{4},{5}", selStartPos.First, selStartPos.Second, selStartPos.Digit, selEndPos.First, selEndPos.Second, selEndPos.Digit); long cursorOffset; // no selection if (selStartPos.First == selEndPos.First && selStartPos.Second == selEndPos.Second) { cursorOffset = selStartPos.Second; // make sure cursor (or end of selection) is visible dvDisplay.MakeOffsetVisible(cursorOffset, showType); dataView.SetSelection(-1, -1); dataView.MoveCursor(selStartPos.Second, selEndPos.Digit); } // selection with start pos <= end pos else if (selStartPos.Second <= selEndPos.First) { // set end position between bytes // this is done so that selections performed with // the mouse can be continued with the keyboard // (keyboard selections always set positions between bytes) selEndPos.Second = selEndPos.First + 1; // if selEndPos.Second is at or beyond the EOF long off = ValidateOffset(selEndPos.Second); if (selEndPos.First >= off) { off++; } cursorOffset = off; dvDisplay.MakeOffsetVisible(cursorOffset, showType); // set the selection only if the start position (which is the start of the selection) // is within the file's limits if (selStartPos.Second < dataView.Buffer.Size) { dataView.SetSelection(ValidateOffset(selStartPos.Second), ValidateOffset(selEndPos.First)); } else { dataView.SetSelection(-1, -1); } dataView.MoveCursor(off, 0); } // selection with start pos > end pos else { // set start position between bytes // this is done so that selections performed with // the mouse can be continued with the keyboard // (keyboard selections always set positions between bytes) // TODO: This is currently disabled because it breaks mouse // selection // //selStartPos.Second = selStartPos.First + 1; long off = selEndPos.Second; cursorOffset = off; dvDisplay.MakeOffsetVisible(cursorOffset, showType); // set the selection only if the end position (which is the start of the selection) // is within the file's limits if (selEndPos.Second < dataView.Buffer.Size) { dataView.SetSelection(ValidateOffset(selEndPos.Second), ValidateOffset(selStartPos.First)); } else { dataView.SetSelection(-1, -1); } dataView.MoveCursor(off, 0); } //System.Console.WriteLine("Evaluate (2) Start: {0},{1},{2} End: {3},{4},{5}", selStartPos.First, selStartPos.Second, selStartPos.Digit, selEndPos.First, selEndPos.Second, selEndPos.Digit); }