/** * Drawing sketch: Draws points, lines, triangles, and quadralaterals * with vertices clickecd by user. * Testing ButtonGroup, ListBox, ComboBox, Menu, and ScrollSketch. * * Copyright 2013-2014 James Brink * Revised 4/4/14 */ // vectors color[] backColors = {#ADEAEA, #EAADEA, #FFFACD}; String[] backColorNames = {"Turquoise", "Plum", "LemonChiffon"}; color[] foreColors // selected = {#FF00FF, #FF0000, #00DD00, #0000FF}; color[] foreColors0 // lineColor box normal = {#FF80FF, #FF7070, #80C080, #8080FF}; color[] foreColors1 // lineColor box over = {#CC30CC, #CC3030, #30A030, #3030C0}; color[] foreColors3 // linecolor box secected over = {#FF50FF, #FF5050, #30B030, #5050FF}; String[] foreColorNames = {"Cyan", "Red", "Green", "Blue"}; color[] fillColors = {#A0A0A0, #FF0000, #00C000, #0000FF, #000000}; String[] fillColorNames = {"Gray", "Red", "Green", "Blue", "Black"}; int[] shapes = {1, 2, 3, 4}; String[] shapeNames = {"Points", "Lines", "Triangles", "Quadrilaterals"}; // Declare Drawing features static final int NUM_SHAPES = 12; Shape[] shp = new Shape[NUM_SHAPES]; int currentShape = shapes[0]; color lineColor = foreColors[0]; color pointColor = foreColors[0]; color backColor = backColors[0]; color fillColor = fillColors[0]; boolean filled = false; // Declare clickable items ListBox shapeListBox = new ListBox(2, 45, 120, "ShapeListBox", shapeNames, #EEEEEE, #CCCCCC, #EEEEAA, #CCCC99); ComboBox pointColorListBox = new ComboBox(2, 145, 120, foreColorNames, #EEEEEE, #CCCCCC, #EEEEAA, #CCCC99); Button[] lineColorBtnArray = new Button[foreColors.length]; ButtonGroup lineColorBtnGrp; ListBox lineColorListBox; Button[] backgroundColorBtnArray = new Button[backColors.length]; ButtonGroup backgroundColorBtnGrp; ComboBox backgroundColorCombo; MyClickablePanel drawingPnl = new MyClickablePanel(140, 25, 200, 260, "Drawing Panel", backColor); Button clearBtn = new Button(358, 25, 120, 20, "Clear", #EEEEEE, #CCCCCC, #EEEEAA, #CCCC99); Checkbox fillBtn = new Checkbox(358, 60, "Fill shape"); RadioButtonListBox fillColorListBox = new RadioButtonListBox( 358, 100, 120, "Fill Colors ListBox", fillColorNames, true, #FFFFE0); MenuBar mBar = new MenuBar(#CCCCCC, #CCDDDD); Button clearMenuBtn = new Button(0, 0, 100, 20, "Clear", mBar.getColor(), mBar.getOverColor()); Checkbox fillMenuBtn = new Checkbox(0, 20, 100, 20, "Fill shape", mBar.getColor(), mBar.getOverColor()); Button[] optionsArray = {clearMenuBtn, fillMenuBtn}; ButtonGroup optionsBtnGrp = new ButtonGroup(optionsArray); Menu optionsMenu = new Menu(75, 40, "Options", optionsBtnGrp, mBar); Menu shapeMenu = new Menu(50, "Shape", 95, shapeNames, mBar, true); Menu pointMenu = new Menu(75, "Point Color", foreColorNames, mBar); Button[] lineMenuBtn = new Button[4]; ButtonGroup lineMenuGrp; Menu lineMenu; Menu fillMenu = new Menu(75, "Fill Color", fillColorNames, mBar); Menu backMenu = new Menu(120, "Background Color", backColorNames, mBar); ScrollSketch sketchWin = new ScrollSketch(#EEEEEE,#CCCCCC, #FF8080); // declare the clickArray. At this point, // backgroundColorCombo, lineColorListBox, sketch are // null and must be reset in the setup method. Then // the clickGrp can be created. Clickable[] clickArray = {drawingPnl, clearBtn, backgroundColorCombo, lineColorListBox, pointColorListBox, shapeListBox, fillBtn, fillColorListBox, mBar, shapeMenu, pointMenu, lineMenu, fillMenu, backMenu, optionsMenu, sketchWin}; ClickableGroup clickGrp; Clickable[] dragArray = {sketchWin}; Dragger drag; String msg; /** * Setup the sketch. */ void setup() { size(500, 320); smooth(); frameRate(20); int i; sketchWin.setupScrollSketch(true); drag = new Dragger(dragArray); clickArray[clickArray.length-1] = sketchWin; for (i = 1; i < shp.length; i++) shp[i] = null; shp[0] = new Shape(currentShape, pointColor, lineColor, fillColor, filled, 4); for (i = 0; i < foreColors.length; i++) { color fc = foreColors[i]; lineColorBtnArray[i] = new CircleButton(8 + (i%2) * 60, 20 * (int)(i/2) + 10, 6, foreColorNames[i], foreColors0[i], foreColors1[i], fc, foreColors3[i]); } lineColorBtnGrp = new ButtonGroup(lineColorBtnArray); lineColorListBox = new ListBox(2, 190, 120, 40, #FFFFCC, "Line colors", lineColorBtnGrp); for (i = 0; i < backColors.length; i++) { backgroundColorBtnArray[i] = new Button(121 + 100 * i, -20, 100, 20, backColorNames[i], backColors[i], #CCCCCC, backColors[i], #CCCC99); } backgroundColorBtnGrp = new ButtonGroup(backgroundColorBtnArray); backgroundColorCombo = new ComboBox(2, 255, 120, 0, backgroundColorBtnGrp, #EEEEEE, #CCCCCC, #EEEEAA, #CCCC99); for (i = 0; i < foreColors.length; i++) lineMenuBtn[i] = new Button(0, i * 20, 75, 20, foreColorNames[i], mBar.getColor(), mBar.getOverColor(), foreColors0[i], foreColors1[i]); lineMenuGrp = new ButtonGroup(lineMenuBtn); lineMenu = new Menu(75, 0, "Line Color", lineMenuGrp, mBar); // Now we can create the group clickArray[2] = backgroundColorCombo; clickArray[3] = lineColorListBox; clickArray[11] = lineMenu; clickGrp = new ClickableGroup(clickArray); if (clickGrp == null) { println("Error: clickGrp is null, noLoop set"); noLoop(); } // Set the introductory message msg = "Optionally change options on left and start clicking"; } // setup void draw() { if (clickGrp == null) return;// clickGrp.display(); int i; background(#FFFFAA); // background color fill(#000000); // font (and other) color updateClickableItems(); text("Shapes", sX_(2), sY_(40)); fill(pointColor); text("Point Color", sX_(2), sY_(140)); fill(lineColor); text("Line Color", sX_(2), sY_(185)); fill(#000000); text("Background Color", sX_(2), sY_(250)); fill(fillColor); text("Fill Color", sX_(358), sY_(95)); text(msg, sX_(140), sY_(395)); fill(#000000); text("Shape: " + shapeNames[currentShape -1], sX_(350), sY_(220)); fill(pointColor); text("Point color ", sX_(350), sY_(238)); fill(lineColor); text("Line color ", sX_(350), sY_(256)); fill(fillColor); text("Fill shapes: " + filled, sX_(350), sY_(274)); fill(fillColor); text("Fill color ", sX_(350), sY_(292)); if (clickGrp == null) { } else clickGrp.display(); } // draw void updateClickableItems() { // this method illustraties the two ways of checking // for the item that caused the click. int itemNum; int i; try { ClickablePanel pnl; Clickable item; String s; if (clickGrp == null) { return; } clickGrp.isOver(); if (clickGrp.hasBeenClicked()) { itemNum = clickGrp.getClickedItemNum(); item = clickGrp.getClickedItem(); if (item.getClickedItemNum() == Clickable.COMBO_BUTTON) return; msg = "Clicked " + itemNum + " selected " + clickGrp.getClickedItem().getSelectedItemLabel() + " " + clickGrp.getClickedItem().getSelectedItemNum(); switch (itemNum) { case 0: // drawing panel if (shp[0].isFull()) { for (i = shp.length - 1; i >= 1; i--) shp[i] = shp[i-1]; shp[0] = new Shape(currentShape, pointColor, lineColor, fillColor, filled, 4); } pnl = (ClickablePanel)clickGrp.getClickedItem(); shp[0].addPt(pnl.getClickX() + soX_, pnl.getClickY() + soY_); break; case 1: // clear button for (i = 1; i < NUM_SHAPES; i++) shp[i] = null; shp[0] = new Shape(currentShape, pointColor, lineColor, fillColor, filled, 4); break; case 2: // background Color comboBox if (clickGrp.getClickedItem().getSelectedItemNum() < Clickable.COMBO_BUTTON) { backColor = backColors[clickGrp.getClickedItem().getSelectedItemNum()]; drawingPnl.setColor(backColor); } break; case 3: // line color listBox lineColor = foreColors[lineColorListBox.getSelectedItemNum()]; shp[0].setColors(pointColor, lineColor, fillColor); // problem: setSelectedItemNum changes the label of lineMenu s = lineMenu.getLabel(); lineMenu.setSelectedItemNum(lineColorListBox.getSelectedItemNum()); lineMenu.setLabel(s); break; case 4: // points color combobox if (clickGrp.getClickedItem().getSelectedItemNum() < Clickable.COMBO_BUTTON) { pointColor = foreColors[clickGrp.getClickedItem().getSelectedItemNum()]; shp[0].setColors(pointColor, lineColor, fillColor); } break; case 5: // shape listbox currentShape = clickGrp.getClickedItem().getSelectedItemNum() + 1; if (shp[0].getCurrentNumberPoints() == 0) shp[0].setShape(currentShape); break; case 6: // fill shape check box filled = fillBtn.selected; shp[0].setFilled(filled); fillMenuBtn.setSelected(filled); break; case 7: // fill color list box. fillColor = fillColors[fillColorListBox.getSelectedItemNum()]; shp[0].setColors(pointColor, lineColor, fillColor); break; case 9: // shape menu item currentShape = clickGrp.getClickedItem().getClickedItemNum() + 1; if (shp[0].getCurrentNumberPoints() == 0) shp[0].setShape(currentShape); shapeListBox.setSelectedItemNum(currentShape - 1); break; } if (item.getClickedItemNum() != Clickable.COMBO_BUTTON) { if (item == pointMenu) { pointColor = foreColors[item.getClickedItemNum()]; shp[0].setColors(pointColor, lineColor, fillColor); pointColorListBox.setSelectedItemNum(item.getClickedItemNum()); } else if (item == lineMenu) { lineColor = foreColors[item.getClickedItemNum()]; shp[0].setColors(pointColor, lineColor, fillColor); lineColorListBox.setSelectedItemNum(item.getClickedItemNum()); } else if (item == fillMenu) { fillColor = fillColors[item.getClickedItemNum()]; shp[0].setColors(pointColor, lineColor, fillColor); fillColorListBox.setSelectedItemNum(item.getClickedItemNum()); } else if (item == backMenu) { backColor = backColors[item.getClickedItemNum()]; drawingPnl.setColor(backColor); backgroundColorCombo.setSelectedItemNum(item.getClickedItemNum()); } else if (item == optionsMenu) { if (item.getItem(item.getClickedItemNum()) == clearMenuBtn) { for (i = 1; i < NUM_SHAPES; i++) shp[i] = null; shp[0] = new Shape(currentShape, pointColor, lineColor, fillColor, filled, 4); } else if (item.getItem(item.getClickedItemNum()) == fillMenuBtn) { filled = fillMenuBtn.getSelected(); shp[0].setFilled(filled); fillBtn.setSelected(filled); } } } } } catch(Exception e) { println("Error: " + e); } } // updateClickableItems void drawShapes () { int i; for (i = shp.length - 1; i >= 0; i--) { if (shp[i] != null) { shp[i].display(); } } } // drawShapes void mousePressed() { Draggable item; if (drag.checkForDrag()) { item = (Draggable)drag.getItemTracked(); if (item == sketchWin) { sketchWin.readyForDrag(drag); } } } // mousePressed void mouseDragged() { Draggable item; if (mousePressed) { item = (Draggable)drag.getItemTracked(); if (item == sketchWin) { sketchWin.moved(drag); } } } // mouseDragged void mouseReleased() { if (drag.getWasDragging()) drag.endDrag(); else clickGrp.checkForClick(); } // mouseReleased // ************************************************************* class Shape { static final int MAX_POINTS = 4; int numPoints; // number of points in shape int num; // num of points available color cPts, cLines, cFill; boolean filled; int rad; int[] x = new int[MAX_POINTS]; int[] y = new int[MAX_POINTS]; Shape(int numberPoints, color colorPoints, color colorLines, int colorFill, boolean fillIt, int radius) { numPoints = min(numberPoints, MAX_POINTS); cPts = colorPoints; cLines = colorLines; cFill = colorFill; filled = fillIt; rad = radius; num = 0; } // constructor Shape void addPt(int xVal, int yVal) { if (num < numPoints) { x[num] = xVal; y[num] = yVal; num++; } } // addPt boolean isFull() { return num >= numPoints; } // is full void display() { int i; stroke(cPts); fill(pointColor); // note: sX_() and sY_() are needed in case the // sketch has been scrolled. for (i = 0; i < num; i++) { // plot points ellipse(sX_(x[i]), sY_(y[i]), rad, rad); } stroke(cLines); if (filled && num >= 3){ fill(cFill); if (num == 3) // filled triangle triangle(sX_(x[0]), sY_(y[0]), sX_(x[1]), sY_(y[1]), sX_(x[2]), sY_(y[2])); if (num == 4) // filled quadrilateral quad(sX_(x[0]), sY_(y[0]), sX_(x[1]), sY_(y[1]), sX_(x[2]), sY_(y[2]), sX_(x[3]), sY_(y[3])); } else { for (i = 1; i < num; i++) line(sX_(x[i-1]), sY_(y[i-1]), sX_(x[i]), sY_(y[i])); if (num == numPoints) line(sX_(x[0]), sY_(y[0]), sX_(x[num-1]), sY_(y[num-1])); } } // display void setColors(color ptColor, color lineColor, color fillColor) { cPts = ptColor; cLines = lineColor; cFill = fillColor; } // setColors void setShape(int numberPoints) { numPoints = numberPoints; } // setShape void setFilled(boolean fillIt) { filled = fillIt; } // setFilled int getCurrentNumberPoints() { return num; } // getCurrentNumberPoints } // class Shape // ************************************************************* /** * Extend ClickablePanel in order to include the drawing method */ class MyClickablePanel extends ClickablePanel { MyClickablePanel (int leftX, int topY, int theWidth, int theHeight, String theLabel, color stdColor) { super(leftX, topY, theWidth, theHeight, theLabel, stdColor); } // constructor MyClickablePanel void drawOnPanel() { drawShapes(); } // drawOnPanel } // class MyClickablePanel