Developing User Interfaces
CMSC 498B
Spring 2005
Prof. Ben Bederson
Project #4
Due April 21, 2005
Purpose
The purpose of this program is to develop an understanding of
building custom widgets and rendering with 2D graphics libraries.
The Problem
You must write a custom widget from scratch (meaning you extend UserControl)
that supports editing and selection of multi-line text. Essentially, you
are writing a slightly simplified version of TextBox. The goal is to
create a fully interactive working multi-line word-wrapping text box with
selection - but you do not have to worry about data binding, or any public APIs
for your control. The requirements for this project are:
- You must do all the rendering "manually", that is with calls to
Graphics.DrawString(), Graphics.FillRectangle(), etc. You must perform
all your own input event handling, and you may not use any other Controls.
Specifically, your control may not have any child controls.
- You should use a proportional space font such as Times Roman.
- Your control should support standard text editing with a text cursor,
including at least:
- Regular characters
- Arrow keys that move the text cursor. Note that when when the
up or down arrow keys are pressed, the cursor must move to the position
in the line above or below
- If you press the up or down arrow keys when
the line the cursor will move to is shorter than the current line, then
the cursor should go to the end of the new line (as opposed to sitting
out in space which would require inserting spaces).
- Enter key must start a new line
- Backspace key must delete the character before the text cursor
- Delete key must delete the character after the text cursor
- Home key must move the text cursor to the beginning of the current
line
- End key must move the text cursor to the end of the current line
- The text cursor should be rendered as a vertical bar that blinks, and
should be put just before the spot where the next character will be entered
when a key is pressed.
- Your control should support word wrap that automatically breaks words
delimited by spaces. That is, if you are typing a word and run out of
room on the current line, the entire word should be moved to the next line.
- Your control should support resizing. If the control is resized,
the text should be automatically re-word wrapped to fit the new width of the
control.
- You do not need to support scrolling, and you do not need to worry about
what happens if more text is entered then fits in the control. If the
words just disappear off the bottom, that is fine.
- You have to support keyboard based selection. Holding down the
shift key while pressing any of the 4 arrow keys should result in the
appropriate text being rendered as selected (white on black instead of white
on black). I am not going to define the complete semantics here, but
the behavior should be identical to the Microsoft TextBox control.
- You have to support mouse-based selection. Clicking and dragging
anywhere in your control should select the text between the click point and
the drag point. I am not going to define the complete semantics here, but
the behavior should be identical to the Microsoft TextBox control.
- You must define your control in its own Visual Studio project, and then
define a separate project with a simple application with one instance of
your control to test it.
Hints
- In order to determine how to lay out the text and to determine where to
draw selection marks, you need to know exactly how big a string of
characters is as rendered. You can determine this with
Graphics.MeasureString().
- Think early about what data structure you will use to store your lines
of text. There are many possible ways that will work, but some data
structures will make your life easier than others. As with all data
structure choices, you should consider what the operations you will need to
support. That means you need to read and understand this entire
project description.
- Supporting selection is hard. I strongly suggest that you think
about how you are going to implement it before you implement the
rest. If you implement the control without thinking about selection,
and then try to add selection later, you might find that you need to change
things.
- I suggest you spend some time using the Microsoft TextBox control so you
are very familiar with its behavior since you are essentially duplicating
it.
- I suggest creating a separate thread to make the cursor blink. You
can use System.Threading.Thread.Sleep() in that thread to sleep for some
time, and then when that thread wakes up, it can communicate with the event
thread with Control.Invoke() to cause the cursor to appear or disappear.
Submitting
Submit following the same rules as Project #3, but make the subject line of your
email contain "DUI: Proj #4 submission". As before, any submissions after the deadline will be ignored. If multiple
submissions are made, then only the last one before the deadline will be looked
at.
The zip file you submit must contain all files within a
directory named "proj4-<name>.zip" where you replace <name> with your last name.