CIS 1200

Paint FAQ

Task 1

I’m getting type errors when I use space (0, 0) in my functions?

You probably need to add parentheses around this to clarify the order of operations - i.e., (space (0, 0)).

When I modify vlist, my toolbars are so far off the screen that I can’t see them!

Make sure that you understand what each component of hlist does. Examine each element that should change because of the x and y direction switch.

How do I call fold or another higher order function?

You can use the List module for this assignment.

Task 2

How important is it that undo works?

Very important because the functionality of undo is checked for every mode.

Conceptually, what is the preview?

It is a shape that needs to be redrawn just like all the saved shapes, except that it is not saved yet.

I implemented drag and drop for lines and I can’t click two points to form a line between them anymore!

This is expected and totally fine! You might want to think about why this is the case based on how you wrote your code.

My program exhibits odd behavior when I start a line and then drag the mouse off the canvas.

That’s OK - it happens in our solution too. In general, we won’t test the cases that are outside the canvas.

Make sure that zero is never used as a line width – when we say “only positive values are valid for line width,” we mean values > 0!

Task 4

Sometimes when I try to draw an ellipse my program freezes / everything on the screen disappears!

This is probably because you are passing invalid (i.e. negative) arguments into your ellipse drawing function.

Task 5

I’m getting Fatal error: exception Graphics.Graphic_failure("graphic screen not opened") or Graphics.Graphic_failure(“cannot open display”)?

You’re trying to do something with the Graphics module before the paint program has fully launched. Don’t set the thickness in Graphics until you’re actually in some function in paint.ml.

Other potential reasons for this error include:

  • Calling .size () or .text_size () outside of your widget’s repaint, handle, or size functions. The open_graphics function hasn’t been called yet, so .size () or .text_size () are not valid function calls.
  • Calling hpair in your overall implementation. Since hpair calls .size (), you’ll run into a similar issue as the point above.

Potential fixes:

  • Move any hpair or .size () into your repaint, handle, or size functions. We know that once the repaint, handle, or size functions are called, the graphics window will already be opened, so we won’t run into this error.

Why am I getting weird errors in my records?

Note that when you create records of first-class functions, you should always put those functions in parentheses.

{ get_value = fun () -> blah;
  change_value = fun x -> blah;
  add_change_listener = (fun (newl: 'a -> unit) -> blergh) }

will be interpreted as

{ get_value = (fun () -> blah;
  change_value = (fun x -> blah;
  add_change_listener = (fun (newl: 'a -> unit) -> blergh))) }

and give you a compilation error.

Instead use:

{ get_value = (fun () -> blah);
  change_value = (fun x -> blah);
  add_change_listener = (fun (newl: 'a -> unit) -> blergh) }

What is the difference between a change_listener and an event_listener?

These are not the same thing. An event_listener is called whenever a mouse, movement, or other event occurs, and they can be for any widget.

change_listeners are specific to the widgets they are listening for, one example being a change of the check/not-checked state for checkboxes. Code with a change_listener doesn’t care about the mouse clicks or movements on the widget, it only wants to know when the widget state changes, even though that probably happens as the result of an event. We maintain a list of change listeners because there might be multiple things that we want to do when the state changes, for example, if we want to turn the canvas yellow, print “LIGHT IS ON” to the console, and increment a counter somewhere, each of those things would be elements in the list of change_listeners.

Type bool is not compatible with type Gctx error in widget.ml?

If you see an error like the following, you are constraining the type of your change_listener in the handle part of your widget.

===== Build №159 =====
Building: GUI/widget.ml
File "GUI/widget.ml", line 268, characters 41-45:
Error: This expression has type bool change_listener = bool -> unit
but an expression was expected of type Gctx.gctx -> Gctx.event -> unit
      Type bool is not compatible with type Gctx.gctx

What is the difference between a change_listener and an event_listener?

These are not the same thing. An event_listener is called whenever a mouse, movement, or other event occurs, and they can be for any widget.

change_listeners are specific to the widgets they are listening for, one example being a change of the check/not-checked state for checkboxes. Code with a change_listener doesn’t care about the mouse clicks or movements on the widget, it only wants to know when the widget state changes, even though that probably happens as the result of an event. We maintain a list of change listeners because there might be multiple things that we want to do when the state changes, for example, if we want to turn the canvas yellow, print “LIGHT IS ON” to the console, and increment a counter somewhere, each of those things would be elements in the list of change_listeners.

Why aren’t my colors changing?

This probably has to do with something in your repaint function! You should also make sure that you are setting the graphics context properly.

General

unbound module error in Codio?

Sometimes Codio will not render the error highlighting properly if you have not compiled yet. Try building the project (Build Project)– if you see no errors or warnings in the terminal, you are fine. If the errors persist but you have no compilation errors, you can also try clearing your browser cache and logging in and out.

If a syntax or compilation error pops up, you must fix that before the error highlighting can be updated.

I ran my paint application, but none of the buttons (e.g. undo, color switching) work!

You may have an error with how you wrote vpair - it should not be identical to hpair. You should be testing out functionality of your code, including clicking the buttons, after each step/task. Do not wait until task 5 or 6 to run your paint application and see if it works.

Can I edit the MLI files?

Yes! You need to for this assignment. But make sure the given files/demos (e.g. lightbulb) still compile fine (you should not need to change these files).

Why can’t I call the function I just wrote from another file?

Make sure you update the corresponding .mli file so that the signature is exposed.

Linking error with widget.cmo or gctx.cmo?

Try cleaning the project to make sure there are no old files left over. If this problem persists, it is because the corresponding mli file is not compiling.