A3-Vanilla
Started doing the mockup on Sat March 2.
Video demo: https://vault.cs.uwaterloo.ca/s/HB8b9MqGiE7Rj2D
- You must create your interface using “vanilla” HTML, CSS, and DOM manipulation. This means using things like
<div>
and<input>
tags, standard DOM events, CSS layout techniques like Flexbox, etc. See the corresponding lectures for approaches. - You may install the npm package “html-template-tag” to use html tagged templates for constructing your UI.
March 3:
- Start a3
- Need to figure out how to put the drawing of the cat, bullseye etc. all together in html and css.
- Have the layout done
March 4:
- Start implementing functionalities, mostly done left view
March 5:
- Complete rightView functionalities (form and editor views) attach with MVC model
March 8:
- Undo bonus
- Fix randomized bullseye and stars
- Fix drawing bullseye
March 9:
- Undo fix bug for Add
- Fix Bullseye rings and scale on the right side view
TODO:
- CSS red border when it goes out of range for the form
- Star randomly generat outer radius??
- Undo?
- README.md file
- 24. Toolbar buttons are disabled under certain conditions. A disabled button is drawn in lighter grays, there are no hover or down effects, and it won’t send any bound events. “Add” is disabled when there are 25 shapes in the list. “Delete” is disabled when no shapes are selected. “Clear” is disabled when there are no shapes in the list.
- [ ]
- 16. The hue textfield accepts only numeric input. There are “up/down” buttons that only permit a range of 0 to 360, but the user can enter any number. If the number is out of range or the textfield is empty, the textfield has a 2px red outline.
Things I didn’t quite understand
- This is a getter method named
root
that returns the value of thecontainer
property. By using a getter, you can accesscontainer
as if it were a property of the class (view.root
), but internally, it’s actually invoking theroot()
method to retrieve the value. - To provide external access to the
container
property without allowing direct modification of the property itself. This is a common pattern in TypeScript and other object-oriented programming languages to encapsulate the internal state of an object while providing controlled access to it.
A2 Example Solution Video
Video Link password: ksk6p5cyxc
This video is only for students enrolled in W24 CS349.
Do not share or download this video
Note that the Model is almost exactly the same as A2, the general structure of views is the same as A2, and the way views work internally is very similar.
- General Structure in
main.ts
- 4 views: toolbar, list, status, and edit
- layout is all flexbox
- Model in
model.ts
Shape
type andcreateRandomShape
extended for Bullseye and Cat- select and deselect now also set the editing id (in A2 the edit id was set in the list controller, better to doo this in model since shape to be edited is always related to overall list selection state)
ToolbarView
- layout is flexbox row
- I use nesting for CSS rules that apply to children, but this is the same as using a selector like div#toolbar>button (you’ll see this nesting in all CSS)
- Add button gets ref to select in controller
- used html tagged template to create
<select>
, but rest is imperative - update sets button enabled/disabled state like A2
StatusView
- layout is flexbox row
- span for shape number and span for selected messages
- update sets text for spans depending on model state
- (“FULL” and “SHIFT” added for debugging and demo, not requirements)
ListView
- layout is flexbox with wrap
- update clears all children, then adds in canvas elements for each shape
drawShape
using canvas graphics context- sets class on canvas if selected
- CSS sizes the 100x100 canvas to 50x50
- select and hover states created with CSS
- each shape widget gets a “click” controller:
- model call to select or deselect the shape (multiselect and edit shape state handled in model )
- stops propagation
- ”click” controller on listView div container deselects all shapes and clears editor state (by calling methods on model)
EditView
- layout is flexbox
- swaps EditMessageView or EditShapeView depending on edit state
- removes old view from Model observer list
- re-uses the child view if they don’t change (re-using EditShapeView maintains input focus too)
EditMessageView
- layout is flexbox with centred paragraph element
EditShapeView
This view is quite different than A2- constructor creates canvas and form for shape type (can re-use them if edit shape stays the same)
- the canvas is 100x100
- in
update
thedrawShape
function is called with shape props from Model - the form is an HTML form
- a switch adds fields required by a shape type to a field object, each time calling
makeRow
creates and adds the HTML label (with prop name) and adds the HTML input element- in
update
, the fields object is used to set current shape props form the model makeInput
creates the HTML number input element for the prop- sets up validation using min, max, and build-in HTML methods
- creates a controlled with the props object to update the model
makeSelect
creates the HTML select for the Cat- layout is flexbox
- canvas is inside a div, sized using the object-fit CSS property
- form also uses flexbox for rows and even in each row
- invalid red outline set with pseudo selector