Creating A Toolbar & Canvas Sketch

Hi All,

I need help, my code is way off. What is the best way to format a sketch that uses the constrain() function to divide the window into two parts; one being a toolbar and the other being a canvas? I need to limit the mouse function based on its X Y locations, formatting the mouse to draw in the ‘canvas’ section only, and click and initiate the buttons in the toolbar section.

I want to use variables and conditional statements for buttons - located in the toolbar - that will change the drawing tool function; such as “clear background” “change color” “change size”.

Right now drawing tool is not limited to activate the only inside the canvas section (the ellipse follows over to the buttons), and the button functions are not constrained / or initiated to the rects. Bear with me, but here is my code! Any thoughts are appreciated on what I am missing!

Original code:

float mx;
float a = 0;
int y = 0;
int grow = 0;

void setup () {
size (620, 440); // size of window
background(120); // background set to gray
strokeWeight(0); // stroke set to 0
frameRate(20); // frameRate speed
rectMode(CORNER);
}

void draw() {

// line thickness
strokeWeight(4);
line

(100, y, 100, 440); // line divides window into two sections: toolbar and canvas

  // toolbar buttons
  rect(20, 50, 50, 30); // button 1
  rect(20, 100, 50, 30); // button 2
  rect(20, 150, 50, 30); // button 3

  // constrain drawing tool to rect - "canvas" 
  float mx = constrain(mouseX, 100, 440);
  rect(100, y, 520, 440);

  //Drawing tool activates if mouse is pressed inside canvas
  if (mousePressed) {
    ellipse(mouseX, mouseY, 50, 50);
  }
  
}

// Buttons Fuctions
void mousePressed() {

  // button 1 - Resets a blank 'canvas'
  if (mousePressed)
  {
    if (mouseX >= 20 && mouseX <= 50)
    {
      background(120);
    }
  }

  // button 2 - Color of drawing tool changes
  if (mousePressed)
  {
    if (mouseX >= 20 && mouseX <= 150)
    {
      fill( random(255), random(255), random(255), random(255));
    }
  }

  // Button three: Drawing tool grows
  if (mousePressed)
  {
    if (mouseX >= 20 && mouseX <= 50)
    {
      if (mousePressed) {
    float x1 = map(cos (a), 1, 200, 300, 500);
    float strokeweight = random(30); // stroke thickness varies 
    float diameter= strokeweight + grow;   // shape grows the long it is pressed
    strokeWeight(strokeweight);
    ellipse(mouseX, mouseY, x1, diameter);
    if (grow < 200) grow += 30;
  }
    }
  }
}


float mx;
float a = 0;
int y = 0;
int grow = 0;

void setup () {
  size (620, 440); // size of window
  background(120); // background set to gray
  strokeWeight(0); // Stroke set to 0
  frameRate(20); // FrameRate speed
  rectMode(CORNER);
}

void draw() {

  // line thickness
  strokeWeight(4); 
  line(100, y, 100, 440); // line divides window into two sections: toolbar and canvas

  // toolbar buttons
  rect(20, 50, 50, 30); // button 1
  rect(20, 100, 50, 30); // button 2
  rect(20, 150, 50, 30); // button 3

  // constrain drawing tool to rect - "canvas" 
  float mx = constrain(mouseX, 100, 440);
  rect(100, y, 520, 440);

  //Drawing tool activates if mouse is pressed inside canvas
  if (mousePressed) {
    ellipse(mouseX, mouseY, 50, 50);
  }

  //Drawing tool function
  float x1 = map(cos (a), 1, 200, 300, 500);

  // When mouse is pressed drawing tool is initiated 
  if (mousePressed) {
    float strokeweight = random(30); // stroke thickness varies 
    float diameter= strokeweight + grow;   // shape grows the long it is pressed
    strokeWeight(strokeweight);
    ellipse(mouseX, mouseY, x1, diameter);
    if (grow < 200) grow += 30;
  }
}

// Buttons Fuctions
void mousePressed() {

  // button 1 - Resets a blank 'canvas'
  if (mousePressed)
  {
    if (mouseX >= 20 && mouseX <= 50)
    {
      background(120);
    }
  }

  // button 2 - Color of drawing tool changes
  if (mousePressed)
  {
    if (mouseX >= 20 && mouseX <= 150)
    {
      fill( random(255), random(255), random(255), random(255));
    }
  }

  // Button three: Drawing tool grows
  if (mousePressed)
  {
    if (mouseX >= 20 && mouseX <= 50)
    {
      grow = 0;
    }
  }
}
1 Like

please format your code using the
</> Preformatted text button from the forum edit menu


for all buttons and for a
STATE ( drawing Or Not )
use a boolean function " mouse over rectangle "

boolean drawing = false;
int drawwinx = width/2, drawwiny = 0, drawwinw = width/2, drawwinh = height;

//_check mouse over rect area 
boolean overRect(int x, int y, int w, int h) {
  if ( (mouseX > x) & (mouseX < (x+ w)) & (mouseY > y) & (mouseY < (y+ h)) ) return true;
  return false;
}

void setup() {
  noStroke();
  background(0);
}

void draw() {
  fill(200, 200, 0);                  // button area
  rect(0, 0, width/2, height);

  drawing = overRect(drawwinx, drawwiny, drawwinw, drawwinh);

  if ( drawing ) {
    fill(0, 200, 0);
    circle(mouseX, mouseY, 5);
  }
}

add one button:

//def: drawing area
boolean drawing = false;
int drawwinx = width/2, drawwiny = 0, drawwinw = width/2, drawwinh = height;
//def: toggle button 
int b1x=10, b1y=20, b1w=30, b1h=20;
boolean b1 = false;
//function: check mouse over rect area 
boolean overRect(int x, int y, int w, int h) {
  if ( ( mouseX > x ) & ( mouseX < (x+ w) ) & ( mouseY > y ) & ( mouseY < (y+ h) ) ) return true;
  return false;
}
//function: draw the buttonearea
void draw_buttonarea() {
  fill(200, 200, 0);                  // button area
  rect(0, 0, width/2, height);
  if ( b1 )  fill(0, 200, 0); 
  else       fill(0, 0, 200);
  rect( b1x, b1y, b1w, b1h);
}
//function: draw IN the drawingarea only
void draw_drawingarea() {
  if ( drawing ) {                    // mouse is over drawing area
    if ( b1 )  fill(0, 200, 0);       // button status
    else       fill(0, 0, 200);
    circle(mouseX, mouseY, 5);
  }
}
//_____________________________main
void setup() {
  noStroke();
  background(0);
}

void draw() {
  drawing = overRect(drawwinx, drawwiny, drawwinw, drawwinh);  // check mode
  draw_buttonarea();
  draw_drawingarea();
}

void mousePressed() {
  if ( overRect(b1x, b1y, b1w, b1h) )  println(" button 1 "+(b1 = ! b1));
}

OR draw only on mouse pressed LEFT draw with button color, on RIGHT erase

//def: drawing area
int dwinx = width/2, dwiny = 0, dwinw = width/2, dwinh = height;
//def: a toggle button 
int b1x=10, b1y=20, b1w=30, b1h=20;
boolean b1 = false;                           // toggle button status
//function: check mouse over rect area 
boolean overRect(int x, int y, int w, int h) {
  if (  ( mouseX > x ) && ( mouseX < ( x + w ) ) && 
    ( mouseY > y ) && ( mouseY < ( y + h ) )     ) 
    return true;
  return false;
}
//function: draw the buttonearea
void draw_buttonarea() {              // operation  area
  fill(200, 200, 0);
  rect(0, 0, width/2, height);
  if ( b1 )  fill(0, 200, 0);         // button 1
  else       fill(0, 0, 200);
  rect( b1x, b1y, b1w, b1h);
}
//function: draw with mouse pressed only
void  draw_in_drawingarea() {
  if ( mousePressed && overRect(dwinx, dwiny, dwinw, dwinh) ) {   // over drawing area only
      if ( mouseButton == LEFT ) {
        if ( b1 )  fill(0, 200, 0);                   // button status
        else       fill(0, 0, 200);
      } else       fill(0);                           // erase  on RIGHT   
      circle(mouseX, mouseY, 5);
    }
}
//_____________________________main
void setup() {
  noStroke();
  background(0);
}

void draw() {
  draw_buttonarea();                               // need refresh button color
  draw_in_drawingarea();                           // on mouse pressed only
}

void mousePressed() {
  if ( overRect(b1x, b1y, b1w, b1h) )  println(" button 1 "+(b1 = ! b1));
}

2 Likes

Suggestion to get rid of some brackets:

if ( mouseX > x &
mouseX < x+ w &
mouseY > y &
mouseY < y+ h )
return true;

3 Likes

thanks, the inner ( ) are all not needed,
but hm…
for readability i not like both ways
AND is & (bitwise) bad? need && logical?
and make more lines?

  if (  ( mouseX > x ) && ( mouseX < ( x + w ) ) && 
        ( mouseY > y ) && ( mouseY < ( y + h ) ) ) return true;

better?

2 Likes

Thanks for your response. How can I specifically divide the window into two distinct parts using the constrain() function and if statements though? Where the drawing tool is constrained to canvas section, and the use of a button function

if you would constrain the mouse position, buttons would not work?
you not like my drawing state idea? did you test both codes?


a total different way? try
http://kll.engineering-news.org/kllfusion01/downloads/painter_basic_mousewheelplusplus_pde.txt


you still not repair your code posting??
and also test copy / paste back to PDE ( and run ) works

1 Like

Hello,

kll, you added a 2nd example showing the use of a button, right?

yes, i try a minimalistic toggle button,
the idea is just to show the use of the

boolean overRect(int x, int y, int w, int h) {
  • -a- for the detection mouse over drawing area ( program flow inside draw() )
  • -b- for the use inside mousePressed() as button click

i not want to rewrite OP’s program, just show how easy it gets when he use that little boolean function.

but also a major point is to show the use of global vars
what define the x,y,w,h of the drawing and button areas
( to be used in the drawing function and the mouse “overRect” )
much better as hardcoded positions inside the code

2 Likes

not sure if this would help, as it doesn’t use the constrain() function.

Ive created the start of a cnc program, which uses classes to separate each section. You have menus, menu controls, and buttons, the menu function tracks the mouse and click, so that it activates only if the mouse is clicked in its location. After that the cnc area could be amended to take mouse input and draw instead of left, right, down, up.

alternatively heres an old paint program i started on khan academy

https://www.khanacademy.org/computer-programming/paint/5326237854695424

Soz just porting it to p5.js now.

please note this is old work and the logical functions aren’t great.

and finally paint ported to p5.js.

2 Likes

Here is an example that uses the constrain() function:

You can easily split the canvas in 1/2 and constrain the drawing area with constrain() and if statements.
It gets more complicated using constrain() with more canvases!

I will not help any further until you have edited (format and delete duplicate code) your original code.
You have a few very obvious errors that I can help with.

Please edit your posts:

  • You posted your code twice. You posted your code twice.
  • It is difficult to read unless formatted properly.

:slight_smile:

4 Likes

Thanks for your patience, as I am a total beginner. I NEED to use the constrain() function, even though I would like to use an easier way, that is what is required and what I am trying to apply for this exercise. I have referenced the reference library, but I obviously am not applying its function correctly.

I have been trying to trouble shoot, but my drawing tool draws in the wrong area, and the buttons to not initiate correctly. Any help on CONSTRAIN() and buttons would be greatly appreciated, per my original question.

Updated code - used auto format on Processing



float a = 0;
int y = 0;
int grow = 0;

void setup () {
  size (620, 440); // size of window
  background(120); // background set to gray
  strokeWeight(0); // Stroke set to 0
  frameRate(20); // FrameRate speed
  rectMode(CORNER);
}

void draw() {

  // line thickness
  strokeWeight(4); 
  line(100, y, 100, 440); // line divides window into two sections: toolbar and canvas

  // toolbar buttons
  rect(20, 50, 50, 30); // button 1
  rect(20, 100, 50, 30); // button 2
  rect(20, 150, 50, 30); // button 3

  // constrain drawing tool to rect - "canvas" 
  float mx = constrain(mouseX, 100, 440);

  //Drawing tool activates if mouse is pressed inside canvas
  if (mousePressed) {
    ellipse(mouseX, mouseY, 50, 50);
  }
  
}

// Buttons Fuctions
void mousePressed() {

  // button 1 - Resets a blank 'canvas'
  if (mousePressed)
  {
    if (mouseX >= 20 && mouseX <= 50)
    {
      background(120);
    }
  }

  // button 2 - Color of drawing tool changes
  if (mousePressed)
  {
    if (mouseX >= 20 && mouseX <= 150)
    {
      fill( random(255), random(255), random(255), random(255));
    }
  }

  // Button three: Drawing tool grows
  if (mousePressed)
  {
    if (mouseX >= 20 && mouseX <= 50)
    {
      if (mousePressed) {
    float x1 = map(cos (a), 1, 200, 300, 500);
    float strokeweight = random(30); // stroke thickness varies 
    float diameter= strokeweight + grow;   // shape grows the long it is pressed
    strokeWeight(strokeweight);
    ellipse(mouseX, mouseY, x1, diameter);
    if (grow < 200) grow += 30;
  }
    }
  }
}
1 Like

Hello,

You can go back and edit your code!

Look for the pencil and click on it:
image

Use the editor tools to format your code:
image

Highlight your code and click on </>.

You can move the mouse over the above editor tools when editing and a pop up will tell you what they do.

:slight_smile:

You seemed to have done this while I was typing! Yay!

2 Likes

Hint 1:
Use noFill() before rectangle.

Hint 2:
mx is declared twice! Only declare it globally once or locally in draw() for immediate use.
You do not use mx in code.
Use mx to constrain location of ellipse.

Hint 3:
Look at range of your constrain() for mouseX; you have a Y location in there as a limit.

Hint 4:

void mousePressed() has multiple mousePressed inside it; this function executes if mouse is pressed so you do not have to keep checking it.

Work on above first and look at example I posted before.

Going for a long hike in woods and not back for a while.

:slight_smile:

Yes! Thanks. I appreciate your time, I edited my code but when I comment out the constrain() function on my second code I posted, I realize it is not being applied at all. I am at a total loss of how to format these functions correctly.

Thanks for your help! I am online working on it now if you are available- but you are not taking personal messages at this time.

are you referencing the first or second code I posted? I am working off of the second.

Work one one thing at a time and save a working version; I add 00, 01, 02 to my code.

:slight_smile:

https://processing.org/examples/constrain.html

I will not be posting any code since this appears to be an academic assignment.

You can do this.

Hint:
The rect() may be better off in the setup() since it will keep drawing over your sketch canvas if it is in draw().

:slight_smile:

Though I have referenced the library, as I stated before, I am not applying it correctly, therefore I do not understand how to format it. To clarify, I am not asking for my code to be written, but rather guidance on how to use the constrain function properly. I will try with rect()

Enjoy your hike. thanks anyways.

thanks

  // constrain drawing tool to rect - "canvas" 
  float mx = constrain(mouseX, 100, 440);
// and later do
    ellipse(mouseX, mouseY, x1, diameter);

so you use constrain but not use the result,
instead mx you use again mouseX,
so it is actually NOT USED!


but more, as you have
ellipseMode(CENTER)
your drawing will still be over the button area


and as you not check if you are over button area or over drawing area
you would still draw something at the moment when you press the button.


that is why we try long time to show you better ways.

2 Likes