PROJECT: ɯeme


Overview

ɯeme is a meme manager app for those who prefer to use a desktop app for managing memes. More importantly, ɯeme is optimized for those who prefer to work with a Command Line Interface (CLI) while still having the benefits of a Graphical User Interface (GUI). Users can view, tag, search, import and export a collection of meme. They can also create their own memes from meme templates.

Summary of contributions

  • Major enhancement: added the ability to create memes from templates

    • What it does: allows the user to add meme templates and create memes by adding text to templates.
      The user can:

      • add, list, edit, search, and delete templates

      • place text anywhere on the template image and see the effect immediately

      • customize the font size, color, and style of the text they add to the template

      • move the text conveniently using arrow keys

    • Justification: This feature forms an integral part of the product because generating memes is something that meme lovers do on a regular basis.

    • Highlights: This enhancement required extending all levels of the architecture: model and storage components were extended to support storing templates; UI was extended to display meme creation session and listen to arrow key presses. It required an in-depth analysis of how the user should interact with the product, given our target user group are those who prefer Command Line Interfaces. The implementation was challenging as it involved graphics processing.

  • Minor enhancement:

    • Implemented the GUI for tabs [#50]

    • Optimized the GUI performance. Reduced lag and memory usage, expanding the capacity of the GUI from lagging with 10 memes to being able to hold 1000 memes without significant lag. [#231]

  • Code contributed: [RepoSense data]

  • Other contributions:

    • Project management:

      • Reviewed a large number of pull requests [Reviews]

    • Enhancements to existing features:

      • Changed the display from a list to a grid, which is more suitable for images [#44]

    • Documentation:

      • Reworded, formatted, and organized the User Guide: [#159]

    • Community:

      • Reported bugs and suggestions for other teams in the class [PED]

Contributions to the User Guide

Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users.

Besides the section below, I have also written the Templates tab section, which is not included here due to page limit. Please refer to here if you would like to see more detail.

Create Tab

The create tab allows you to create a new meme from a template. To start a meme creation session, select a template from the templates tab and execute the use command.

Meme creation sessions will not be saved after exiting the app.
Please finish the meme creation session before exiting the app if you would like to create a meme from it.

Adding text: add

Adds a piece of text to the template.
Format: add TEXT x/X_COORDINATE y/Y_COORDINATE [c/COLOR] [s/SIZE] [S/STYLE]…​

  • X_COORDINATE and Y_COORDINATE denote the position at which the supplied text will be placed and are represented as ratios of the image dimensions. x/0.5 y/0.3 means the center of the supplied text will be 50% right of the left border and 30% down from the top border.

  • COLOR can be a name, e.g. cyan, or a hex RGB value, e.g. #FF34E2.

  • Weme supports 6 levels of font size. SIZE must be an integer from 1 to 6, where 1 denotes the smallest font size and 6 denotes the largest font size. Some text of each font size can be found at the right hand side of the image as a reference. Note that the sample sizes only apply to templates whose width/height ratio do not deviate too much from 1.

  • STYLE must be plain, bold, or italic. In the case you specify multiple font styles, Weme will combine them. For example, S/bold S/italic will give you bold and italic text.

  • If you do not specify COLOR, SIZE, or STYLE, the default values will be used. The default values are black, 5, and plain, respectively.

  • Weme will not add text that would exceed the image boundary. If it detects such a scenario, it will print an error message.

The x and y coordinates given in the command specify the position for the center of the text. This means if you want to add text to the center of the image, the command will always be add TEXT x/0.5 y/0.5 no matter how long your text is.

Examples:

  • add CS students be like x/0.5 y/0.3
    Adds text CS students be like to the template, placing its center 50% right of the left border and 30% down from the top border.

  • add sToNKs x/0.5 y/0.75 c/red s/5 S/bold
    Adds red and bold text sToNKs with size 5 to the template, placing its center 50% right of the left border and 75% down from the top border.

Editing text: edit

Whenever you add text, the list at the right hand side will be updated.
The edit command allows you to choose and edit a piece of text from that list.
Format: edit INDEX [t/TEXT] [x/X_COORDINATE] [y/Y_COORDINATE] [c/COLOR] [s/SIZE] [S/STYLE]…​

  • At least one of the optional fields must be provided.

  • Existing values will be updated to the input values.

  • When editing text styles, the existing styles of the text will be removed i.e adding of styles is not cumulative.

Examples:

  • edit 1 t/CODE
    Changes the text at index 1 to CODE.

  • edit 2 x/0.5
    Changes the x-coordinate of the text at index 2 to 0.5.

  • edit 3 c/#FC1423 s/5 S/bold
    Edits the text at index 3, changing its color to #FC1423, size to 5 and style to bold.

Moving text: move

Moves the specified text.
Format: move INDEX [x/X_CHANGE] [y/Y_CHANGE]

  • The move is relative to the current position of the specified text.

  • At least one of X_CHANGE and Y_CHANGE must be specified.

Examples:

  • move 1 x/-0.1
    Moves the text at index 1 to the left by 10% of the image width.

  • move 2 y/0.3
    Moves the text at index 2 down by 30% of the image height.

  • move 3 x/0.2 y/-0.3
    Moves the text at index 3 to the right by 20% of the image width and up by 30% of the image height.

You can type move INDEX and use arrow keys to move the specified text.
Hold Shift while pressing arrow keys to make the text move faster.
Hold Alt (Option on MacOS) while pressing arrow keys to make the text move slower.

Deleting text: delete

Deletes the text at the specified index.
Format: delete INDEX

Aborting meme creation: abort

Aborts this meme creation session and go back to the templates tab.
Format: abort

Completing the creation session: create

Creates a new meme with all the added text applied. The new meme will be saved into Weme’s meme collection, with the specified description and tags.
Format: create [d/DESCRIPTION] [t/TAG]…​

  • This command does not modify the template you used to start the creation session. You can use the same template to make more memes.

  • You will be directly to view the meme you have created. To continue making new memes, use tab templates to go to the templates tab.

Examples:

  • create d/sleep or code t/soc t/cs2103
    Creates a new meme from the current meme creation session, giving it a description sleep or code and tags soc and cs2103.

Contributions to the Developer Guide

Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project.

Besides the section below, I have also written the Tabs feature section, which is not included here due to page limit. Please refer to here if you would like to see more detail.

Templates feature

Many memes are created from templates. Meme lovers often store a list of templates and process them to generate new memes when needed. A template typically reserves whitespace for the user to fill in text to give the template meanings. Weme provides this feature and allows the users to store their favourite templates and generate memes with the templates.

Current Implementation

Like a Meme, a Template also has an associated image that is stored on the hard disk. Each Template object has 2 fields, Name and ImagePath, where Name serves as the identifier and ImagePath holds the path to the image of this template. A user can add, edit, delete, or find a template.

TemplateClassDiagram
Figure 1. Partial class diagram showing only classes in Model related to Template

Templates are stored together with Memes in Weme. Refer to the model class diagram above for details.

When the user requests to generate a meme using a template, Weme enters the "Create" tab. The user can then use commands to add text to the template image. Meme creation is supported internally by the MemeCreation class. A MemeCreation object represents a meme creation session (which can be empty when the user is not creating a meme). Once a session is activated, the MemeCreation object stores a BufferedImage of the template and a list of MemeText objects, which represent text that the user wants to add to the template. Every time the user adds text, the list of MemeText gets updated. When the UI requests for the updated image, MemeCreation generates it on the fly with all the MemeText applied. When the user is done, MemeCreation creates a new Meme with all the added text included and saves it in the meme collection.

MemeCreationClassDiagram
Figure 2. Partial class diagram showing only classes in Model related to MemeCreation

Given below is an example usage scenario of meme creation using a template.

Step 1. The user launches the application and enters the Templates tab.

Step 2. The user executes find doge command to find the doge template. The FilteredList<Template> in ModelManager is updated with a predicate that matches only templates whose names match doge.

Step 3. Assuming the template that the user wants to use is displayed as the first template, the user executes use 1 to start creating a meme using that template. Weme starts a new MemeCreation session and enters the "Create" tab.

Step 4. The user executes add cs students be like x/0.5 y/0.3 command to add the text "cs students be like". A new MemeText is created and added to the list in the current MemeCreation session. The UI requests MemeCreation to render the resultant image, and MemeCreation returns an image with the text "cs students be like" whose center is placed 50% horizontally from the left border and 30% vertically from the top border.

Step 5. The user decides that there is a typo in the text because "cs" is not capitalized. The user executes the command edit 1 t/CS students be like to edit the text labelled 1, which is the text that was just added. MemeCreation changes the text of this MemeText from "cs students be like" to "CS students be like". Upon request by the UI, MemeCreation generates the updated image for the UI for display.

Step 6. The user wants to move the text. The user types move 1 into the command box and uses arrow keys to adjust the text position. The user holds Shift to make large adjustments at first, then holds Alt to make small adjustments until the text is at the desired position. CommandBox listens to key presses and dispatches a TextMoveCommand on each key press. It also throttles the key press rate to prevent firing commands too frequently. MemeCreation generates a new image on each command received and the UI keeps the displayed image up-to date.

Step 7. The user executes create d/A meme about CS students t/funny t/CS to complete the creation session. Weme will create a new image with the text added and save it to the data directory. Weme will also create a new Meme entry with that image, with description "A meme about CS students" and tags "funny" and "CS". The description and tag arguments are similar to those for Meme add command. Weme displays the newly created meme, as if from a view command.

The user can abort any meme creation session by typing abort. This will put Weme back to displaying the content of the Templates tab.

The following activity diagram summarizes the meme creation process:

MemeCreationActivityDiagram

The following sequence diagram shows how the user adds a piece of text.

TextAddCommandSequenceDiagram

Design Considerations

Aspect: How to store and update the image
  • Alternative 1 (current choice): Only store the initial image and a list of text. Re-generate an image when it is requested by the UI.

    • Pros: Can edit/delete text after they are added.

    • Cons: Waste resources by repeatedly rendering largely similar images.

  • Alternative 2: Always store the updated image. Update the image whenever a piece of text is added.

    • Pros: Less performance overhead, only render what is needed.

    • Cons: Cannot edit/delete text.

Aspect: How the user adds/deletes text
  • Alternative 1 (current choice): The user enters commands to add/edit/move/delete text.

    • Pros: Easier to implement. Integrates well with the rest of the product.

    • Cons: It is troublesome to type in the coordinates and difficult to position the text accurately.

    • Mitigation measure: Provide rulers beside the image as visual aid for the user, support using arrow keys to move text.

  • Alternative 2: The user manipulates the UI through individual key strokes (Vim-like modal key-bindings) For example, a to add a piece of text, arrow keys to adjust the position of the currently selected text, 1 to select text labelled 1 and d to delete the currently selected text.

    • Pros: The user can accurately adjust the position of the text.

    • Cons: Very hard to implement. Requires major work on the UI. Must use extra care to make sure the state transitions are correct.

  • Alternative 3: The user moves the text using the mouse

    • Pros: Might be more intuitive for new users. New users do not need to learn the commands.

    • Cons: Breaks the keyboard-driven workflow. Using the mouse might actually be less accurate when positioning text.

Aspect: How to specify the position of text coordinates
  • Alternative 1: The user specifies where the top-left corner of the text should be.

    • Pros: Might be more useful if the user wants to place the text right after another piece of text.

    • Cons: User will be unsure where the text will end. Might need to use the move command afterwards to adjust the text position after seeing its length.

  • Alternative 2(current choice): The user specifies where the center of the text should be.

    • Pros: Easier to specify where the text will eventually be. For example, when the text should be at the center, the user simply specifies x/0.5 y/0.5, instead of doing a visual estimate of how the long text would be and specifying its top-left corner’s coordinates.

    • Cons: New users might be more used to specifying the top-left corner’s coordinates and think there is a bug in the product.