as6: UndoLast revised: 11:57pm, 3-12-2020
- March 2nd
- Programming - Due March 11th
- Lock March 13th
- Heuristic Evaluation - Due March 14th (no leeway)
- Reflection - Due March 16th
- Be able to understand and modify an existing user interface
- Learn about floating action buttons
- Implement core data structure for Undo
- Modify and existing app in a consistent fashion
- Make your modifications accessible
- Make your modifications usable
- Use heuristic evaluation to assess an app
- Explanation of Codebase
- Codebase Structure
- Requirements for assignment
- Requirement 4: Improve the application
- Part 5: Reflection: Heuristic evaluation & Other Reflection Questions
Accept the Assignment / Turn-in the Assignment / Review your Submissions
- Handle undo/redo operations (required)
- Add a new thickness (0) to your app (required)
- Replace the color menu with a ColorPickerView (required)
- Make sure the button you add is accessible (required)
- Improve your app by adding a feature (not thickness, required)
- Make sure your change is accessible (required)
- Try to identify at least one usability problem and address it (optional)
Demo of our solution:
Explanation of Codebase
This is one of the more complex programs we are giving you in terms of code, it is a fairly functional application.
The initial interactor hierarchy at instantiation is shown below (shown at the side is a legend for the visibility status of different interactors). Hidden means on screen and drawn but hidden behind something else.
The Floating Action Button (FAB) subtrees are the
menus at the top of the screen (for undo and redo) and bottom (for
color and thickness), made up of one or more floating
action buttons. The
DrawingView is the place where drawing takes
place. Each new stroke is saved as a separate, new
The FABs in this assignment refer to Floating Action Buttons.
When the user draws on screen (by clicking and dragging inside the
DrawingView, this adds a new
StrokeView to the interface. Notice
Undo button is now visible instead of invisible because there
is an action to undo.
The sequence in the interface:
You can play around with the interface to change color and
thickness. Each new stroke you add adds another
StrokeView to the interface.
This is a complete codebase for a drawing program. It is designed to be as modular as possible and includes support for Command Objects which encapsulate changes to the application model.
Actions are Command Objects, which encapsulate changes to the
application model. An
AbstractAction has a single method,
when called, should apply the action to the view (our provided implementation is incomplete)
AbstractAction to add
when called, reverses the action.
As with events,
AbstractActions are part of an inheritance
AbstractReversibleAction has three subclasses –
All of them modify properties of the
class (specifically the stroke width and current color of its
object, and the its child views (painted strokes are encapsulated in a
StrokeView that is added to the
Application Code (
We’ve mentioned a
DrawingView (which is the main canvas for the
drawing application) and
StrokeView (which encapsulates a specific
stroke for the drawing application).
AbstractDrawingActivityis an abstract class for an app that supports drawing without support for Undo. If you changed the manifest to use it (you would need to make it not abstract first), you would see blank canvas that you can draw on with no thickness or color options. NOTE if you do this experiment, remember to make it abstract again when you’re done!
AbstractDrawingActivityand adds support for undo to it, including both the undo/redo buttons and the history. You can try changing the manifest to use this as well (not abstract). NOTE if you do this experiment, remember to make it abstract again when you’re done!
AbstractReversibleDrawingActivity. It adds support for thickness and color to the undo/redo support in
AbstractReversibleDrawingActivity. It also adds menus to show them. You can make a drawing application without support for history by changing
ReversibleDrawingActivityto inherit from
DrawingViewis the canvas on which drawing takes place. Drawings are made up of
StrokeViewclasses which are added to the
DrawingView. This class also implements a PPS (shown below) which responds to
StrokeViewis a single stroke. A stroke has a
paintobject which define it.
Requirements for assignment
There are five requirements for this assignment:
- Requirement 0: Implement
- Requirement 1: Implement history
- Requirement 2: Add a thickness 0 FAB to the thickness menu
- Requirement 3: Integrate colorpicker
- Requirement 4: Add a new feature to your app. Make sure it is accessible
You can also (optionally) work on improving the usability
Requirement 0: Implement
In order to familiarize yourself with Actions and reversible logic, implement
ChangeThicknessAction. This will be very similar to
ChangeColorAction, you should read and understand that code before implementing your
Requirement 1: History
Actions are the raw material that is used in the history. An
AbstractHistory simply allows an
AbstractReversibleAction to be added and supports
redo(). We subclass this with a stack-based history class called
StackHistory to support
redo(). You will implement the methods to support these features in this
StackHistory has a
capacity (a max number of actions that it can
undoStack (the history) and a
redoStack (actions that
have been undone and can be re-applied). It also supports specific capabilities you must implement (see comments in the code
for specifically what to do):
addAction()adds an action to the history stack
undo()undo the top action in the history stack
redo()redo the top action in the redo stack.
Here is a scenario where the user draws a stroke in the default color/thickness (1), changes the color (2), changes the thickness (3), and draws another stroke (4) in the original thickness and color, with various undos and redos mixed in.
|Action||Undo Stack||Redo Stack||Interface state|
|change color (2)||1,2||1,2|
|redo||1, 2||1, 2|
|change thickness (3)||1, 2, 3||1, 2, 3|
|undo||1, 2||3||1, 2|
|drawstroke (4)||1, 4||CLEARED||1, 4|
Requirement 2: Adding a thickness 0 FAB to the thickness menu
There are two main things you will need to do to add one.
First, you find the right place in
modify. For example, this is the XML in that file for the thickest FAB
<android.support.design.widget.FloatingActionButton android:id="@+id/fab_thickness_30" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|center" android:layout_marginBottom="@dimen/fab_label_margin" android:alpha="0" android:clickable="false" android:contentDescription="@string/thickness_desc" app:fabSize="mini" app:srcCompat="@drawable/ic_thickness_30" />
You should use the
@string notation for your
android:contentDescription, meaning you’ll need to add a string definition to
Next, you will need to update
onThicknessSelected to respond when
your FAB is pressed. It should change the stroke width to 0.
Finally, you will need to make sure that
ReversibleDrawingActivity is updated to account for your new menu item, since all mentions of thickness are currently hard coded to assume there is no 0 thickness.
Requirement 3: Integrating color picker
In addition to adding a thickness, we want to be able to draw strokes of any color instead of being limited to 3. You may recall that we have
already made a custom interactor that allows users to choose any color on the color spectrum in a previous assignment. It is time to wire up a
ColorPickerView into this application.
First, you need to copy over the
ColorPickerView.java file from your color picker assignment. Put this files in the same directory as your
ReversibleDrawingActivity.java file. Also be sure to change the package at the top from
cse340.undo.app in your
You also need to add it to your layout. One way to do this is to add xml for your
drawing_activity.xml. Be sure it is neither visible nor focusable until the user clicks on the color FAB. Also be sure to use the correct package name here too.
Next, you will need to change the behavior of the color FAB so that, when clicked, it opens up the color picking interface instead of opening the collapsible color menu. For reference on how to do this, take a look at
ReversibleDrawingActivity.java#onCreate (hint: make sure to take a look at what interfaces
When users have the color picker interactor open, they should not be able to access any other FABs (undo, redo, thickness change) so be sure to disable them when you show the color picker and visually indicate to the user that they are disabled. This behavior should be very similar to the what happens when you try to change the thickness using the collapsible menu. If a color change is undone or redone, the color picker should reflect the correct color. Once you set up all the listeners to respond correctly, your color picker interactor should allow users to pick any stroke color they want!
Finally, you will need to modify
ColorPickerView so that it only accepts input inside the color ring. If the user presses inside the ring, or outside it, you should not leave the start state. If the user releases inside the ring, or outside it, you should exit the state machine AND not consume the input. We have provided an AbstractColorPickerView class for you with an updated EssentialGeometry enum whose values are now
OFFWHEEL. Finally, you should modify
onDraw() to leave the center circle blank.
- A is updateModel();invalidate()
- B is invokeColorChangeListeners();invalidate()
- C is updateModel();invalidate()
- D is doNothing()
NOTE: You do not need to use bundler to change the starting color or to store your model for this assignment.
Related APIs: View#using-views
Requirement 4: Improve the application
Create an interesting way the user can interact with the application that can be undone and redone. This means that whatever interaction you
add must have a custom undo and redo function (it might help to take a look at
Whatever you choose to implement, make sure to describe your addition in the provided README.md.
In addition, make sure that the action you add is accessible.
Demo of a solution without colorpicker but with a new feature: Clear screen
You will describe this addition and its accessibility in your refletion (see below)
Optional addition: Improving usability
Try to identify at least one usability problem and address it (optional). As with adding a feature, there are several options here. Some examples of things I think are usability issues. You may not agree, if you choose to do this, you should focus on something you think is a usability issue.
Whatever problems you address, please briefly describe the problems and solutions in the provided README.
- As a color is selected and after the color is selected, the color FAB should update its background to that color.
- When a thickness is picked, the thickness FAB should update its icon to indicate the thickness selected.
- If the user begins drawing with the color or thickness FAB open (sub-icons present) the FAB immediately collapses
- Some might find the menu items small and hard to select
- No saving of state between invocations of the application. Could use bundle to do this.
Part 5: Reflection: Heuristic evaluation & Other Reflection Questions
This will take place in the last lab of the quarter, please watch for our announcement about any prep you need to do. Your analysis and be due over the next 24 hours, once we release results to you.
To facilitate the online-only nature of the last week of the quarter, you will need to make a video of your final solution. To create a video, click on the … at the bottom of the panel to the right of your emulator, then select “screen record” and “start recording” (see images below).
In addition, you should follow these instructions to make sure that clicks are visible:
Your video should have the following sequence. Please DO NOT try to create a perfect version with no mistakes! You will not lose points for any usability issues or mistakes (unless your code isn’t working, which will not be affected by this video). You will get much better feedback and learn more about Heuristic Evaluation if your video isn’t perfect!
- Step 1: draw something
- Step 2: undo
- Step 3: change color
- Step 4: try to redo
- Step 4: draw something
- Step 5: use new feature
- Step 6: draw something
- Step 7: undo it
- Step 8: undo new feature
- Step 9: draw something
- Step 10: use new feature
- Step 11: undo
- Step 12: redo
- Step 13: draw something
Finish as you will (e.g. demonstrate optional usability improvement)
5.2 Providing Heuristic Eval feedback
You will be assigned four videos. For each one you should:
- Watch the video
- While watching, take notes on paper about issues you see.
- Remember: Make two passes through video as discussed in class:
- Inspect flow
- Inspect each screen, one at a time against heuristics
- Fill out the following google form with the 3 most
severe issues. This will include questions about:
- Who are you/ who are you evaluating
- Which task step (above)
- Which heuristics are violated (primary and secondary)
- What severity rating would you give it
- Take a picture (a frame of the video) and circle the issue
- Describe what happened
You will submit 3 things for each assigned video. At least two should be bad issues, one can be good.
5.3 Reflecting on Heuristic Eval feedback and other aspects of assignment
You will turn in a report describing the feedback you got from the Heuristic Evaluation and answering other questions about the assignment. We have provided a template.
You will turn in the following files via GitGrade. It will accept:
- Any additional classes you create in
cse340.undofor your new action
You will turn in the following files via our google form:
- Your video
You will turn in your report on Gradescope
Implementation (20 pts)
- Part 0: Implement ChangeThicknessAction (2pts)
- Part 1: StackHistory (5pts)
- Part 2: Adding thickness to FAB thickness menu (4pts) -Part 3: Integrating ColorPickerView (8pts). Includes correct interactive behavior, and correct interaction with the stack.
- Code Organization, and Style: (1 pt)
Heuristic Evaluation & Reflection (30 pts)
- Part 4: Improvement (5 pts). Includes video of improvement, description of improvement, justification based on design principles and accessibility support.
- Part 5: Do Heuristic Evaluation (5pts) Includes video of tasks and completion of assigned heuristic evaluations
- Part 6: Reflection (20 pts). Includes the following reflection questions:
- How well do the heuristics fit mobile application design? (4 pts)
- Relate the heuristics to the gulf of evaluation and the gulf of execution (4 pts)
- How secure is the Undo app? (4 pts)
- How would you use context-aware computing in your drawing app? (4 pts)
- How have Properties of People I and II been used in your assignments? (4 pts)