예제 #1
0
 /// <summary>
 /// Constructor called to initialize the event args with the key pressed by the user.
 /// </summary>
 /// <param name="c"></param>
 public KeyPressEventArgs(Textbox field, char c) {
     _field = field;
     _char = c;
 }
예제 #2
0
        /// <summary>
        /// A method that loops and processes keystrokes until the form is complete, 
        /// either by <see cref="FormComplete">FormComplete</see> or 
        /// <see cref="FormCancelled">FormCancelled</see> events.
        /// </summary>
        private void LoopForKeypress() {
            // Loop for keypresses.  Since we're doing all the work of processing, we have
            // to trap special keypresses and respond appropriately
            while (true) {
                // Blocks on the next function call.
                ConsoleKeyInfo cki = Console.ReadKey(true);

                ConsoleKey nKey = cki.Key;

                // A key's been pressed.  Figure out what to do.
                // All actions will be against the current field, stored in _field.
                char	cChar	= cki.KeyChar;

                if (cChar != 0) {        // Guard against unprintable chars.
                    KeyPressEventArgs kpea = new KeyPressEventArgs(_field, cChar);

                    if (_keyPressEvent != null)
                        _keyPressEvent(this, kpea);

                    if (!kpea.Cancel) {     // Process the keystroke.  It wasn't cancelled.
                        switch (nKey) {
                            case ConsoleKey.Backspace:		// Backspace pressed
                                // Is there a character to backspace over?
                                if (_field.Text.Length > 0) {
                                    _field.Text = _field.Text.Substring(0, _field.Text.Length - 1);
                                    Refresh(_field);
                                }

                                break;

                            case ConsoleKey.Tab:		// Tab -> Move to the next field.
                                if (cki.Modifiers == ConsoleModifiers.Shift) { 
                                    // Go backwards.
                                    _currentField--;

                                    // If we're at the first field, move to the last.
                                    if (_currentField == -1)
                                        _currentField = _textboxes.Count - 1;
                                } else {
                                    // Go forwards
                                    _currentField++;

                                    // If we're in the last field already, move back to the first.
                                    if (_currentField == _textboxes.Count)
                                        _currentField = 0;
                                }

                                // Set the current field to the next one in the collection.
                                _field = _textboxes[_currentField];
                                _textboxes.FocusField = _field;

                                // Move the cursor to the location of the next field, accomodating
                                // any text that may already be there..
                                Console.SetCursorPosition(_field.Location.X + _field.Text.Length, _field.Location.Y);
                                break;

                            case ConsoleKey.Enter:		// Enter -> Fire the complete event if it's wired.
                                if (_formCompleteEvent != null) {
                                    FormCompleteEventArgs fcea = new FormCompleteEventArgs();

                                    _formCompleteEvent(this, fcea);

                                    // The listener of this event will set the Cancel field if they
                                    // want to re-use the form.  If not cancelled, the form will
                                    // be destroyed.
                                    if (!fcea.Cancel) {
                                        // Get rid of this form.  A new one will be displayed.

                                        // Unusual to call Dispose() on oneself, but it saves a lot of
                                        // code in the clients if this is the default behaviour, rather
                                        // than forcing every single event to call Dispose() on the
                                        // passed-in sender parameter.
                                        ((IDisposable)this).Dispose();
                                        return;
                                    }   // else the current form will be reused.  Go back for more keys.
                                }

                                break;

                            case ConsoleKey.Escape:     // Esc -> Fire the cancelled event if it's wired.
                                if (this.FormCancelled != null) {
                                    this.FormCancelled(this, System.EventArgs.Empty);

                                    ((IDisposable)this).Dispose();
                                    return;
                                }

                                break;

                            default:		// Any other keystroke
                                if (_field != null) {   // May not be an active textbox.
                                    if (_field.Text.Length < _field.Length) {
                                        // The field is not yet full.  It can be appended to.
                                        _field.NonEventingText += cChar;
                                        Console.ForegroundColor = _field.Foreground;
                                        Console.BackgroundColor = _field.Background;

                                        if (_field.PasswordChar != char.MinValue)
                                            // It's a password field.  Display the password character.
                                            Console.Write(_field.PasswordChar);
                                        else
                                            // Not a password type field.  Show the actual character.
                                            Console.Write(cChar);
                                    }  // Field already full => no keystrokes accepted.
                                }
                                break;
                        } // Keystroke was not cancelled
                    } // Character was printable
                }  // End of switch statement
            }  // End loop for keypresses
        }
예제 #3
0
        /// <summary>
        /// Draws the current form onto the console.
        /// </summary>
        /// <param name="clear">A <see cref="bool">bool</see> indicating whether or
        /// not the screen should be cleared before it is redrawn.</param>
        public      void        Render(bool clear) {
            Console.ResetColor();
            
            if (clear)
                Console.Clear();

            Console.Title = _name;

            // Resize the window and the buffer to the form's size.
            if (Console.BufferHeight != _height || Console.BufferWidth != _width) {
                Console.SetWindowSize(_width, _height);
                Console.SetBufferSize(_width, _height);
            }

            if (Console.WindowHeight != _height || Console.WindowWidth != _width) {
                Console.SetBufferSize(_width, _height);
                Console.SetWindowSize(_width, _height);
            }

            // Draw the lines first.
            foreach (Line line in _lines) {
                Console.BackgroundColor = line.Colour;

                if (line.Orientation == Line.LineOrientation.Horizontal) {
                    // Instructions for drawing a horizontal line.
                    Console.SetCursorPosition(line.Location.X, line.Location.Y);
                    Console.Write(new string(' ', line.Length));
                } else {
                    // Instructions for drawing a vertical line.
                    Int32 x = line.Location.X;

                    for (Int32 i = line.Location.Y; i < line.Location.Y + line.Length; i++) {
                        Console.SetCursorPosition(x, i);
                        Console.Write(" ");
                    }
                }
            }

            // Draw the labels next.
            foreach (Label label in _labels)
                Refresh(label);

            // Now draw the textboxes.
            foreach (Textbox text in _textboxes)
                Refresh(text);

            // If any textboxes are defined for the form, pick the first one and position
            // the cursor accordingly.
            if (_textboxes.Count > 0) {
                _field = _textboxes[0];
                _textboxes.FocusField = _field;
                Console.SetCursorPosition(_field.Location.X + _field.Text.Length, _field.Location.Y);
                Console.CursorVisible = true;
            } else
                // Otherwise, hide the cursor.
                Console.CursorVisible = false;

            _labels.Rendered();
            _textboxes.Rendered();

            if (_keyThread.Name == null) {
                // Start the thread that listens for keypresses.
                _keyThread.Name = "Keypress loop for " + _name;
                _keyThread.Start();
            }
        }
예제 #4
0
        public      void        SetFocus(Textbox field) {
            for (Int32 i = 0; i < _textboxes.Count; i++)
                if (_textboxes[i] == field) {
                    _field = Textboxes[i];
                    _currentField = i;

                    Console.ForegroundColor = _field.Foreground;
                    Console.BackgroundColor = _field.Background;
                    Console.SetCursorPosition(_field.Location.X + _field.Text.Length, _field.Location.Y);

                    return;
                }

            throw new InvalidOperationException(field.Name + " not found.");
        }
예제 #5
0
 /// <summary>
 /// Appends a <see cref="Textbox">Textbox</see> to the list.
 /// </summary>
 /// <param name="t">The <see cref="Textbox">Textbox</see> to add.</param>
 public   void     Add(Textbox t) {
     _textboxes.Add(t);
 }
예제 #6
0
        /// <summary>
        /// Reads Xml when the <see cref="Textboxes">Textboxes</see> is to be deserialized 
        /// from a stream.</summary>
        /// <param name="reader">The stream from which the object will be deserialized.</param>
        void System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader reader) {
            if (!reader.IsEmptyElement) {
                while (reader.Read()) {
                    if (reader.NodeType == System.Xml.XmlNodeType.EndElement) {
                        reader.Read();
                        break;
                    }

                    Textbox textbox = new Textbox();

                    ((IXmlSerializable)textbox).ReadXml(reader);
                    _textboxes.Add(textbox);

                    reader.Read();
                }
            } else
                reader.Read();
        }