Code Sketch
yadnesh
Category: Programming
//scala
import java.awt.BasicStroke
import java.awt.BorderLayout
import java.awt.Color
import java.awt.Cursor
import java.awt.Dimension
import java.awt.FlowLayout
import java.awt.Font
import java.awt.GradientPaint
import java.awt.Graphics
import java.awt.Graphics2D
import java.awt.Image
import java.awt.RenderingHints
import java.awt.event._
import java.awt.geom.AffineTransform
import java.awt.geom.Path2D
import java.awt.image.BufferedImage
import java.io.File
import javax.imageio.ImageIO
import javax.swing._
import javax.swing.border.EmptyBorder
// ============================================================
// ULTRA LEGEND SMART DRAW STUDIO X - FUTURE EDITION
// ============================================================
// OFFLINE FUTURISTIC DRAWING / DESIGN STUDIO
//
// FEATURES
// ------------------------------------------------------------
// PENCIL / ERASER / SPRAY / LINE / RECT / ELLIPSE
// FREEHAND POLYGON / BRUSH / HIGHLIGHTER
// 100+ SHAPES
// 100+ OBJECT COMMANDS
// SMART COMMAND / AI-STYLE OFFLINE ASSISTANT
// IMAGE IMPORT
// IMAGE EXPORT
// TEXT
// GRADIENT BACKGROUNDS
// NEON / MAGIC / GOLD / CYBER EFFECTS
// GRID
// SNAP
// MIRROR
// ROTATE
// SCALE
// FLIP
// ZOOM
// PARTICLES
// STARFIELD
// ANIMATION PREVIEW
// UNDO / REDO HISTORY
// LAYERS
// COLOR PICKER
// CUSTOM BACKGROUND
// SECRET HOTKEY SYSTEM
// FULLSCREEN
// ============================================================
// ============================================================
// CONSTANTS
// ============================================================
val W = 1200
val H = 700
val CX = W / 2
val CY = H / 2
// ============================================================
// GLOBAL STATE
// ============================================================
var currentColor = new Color(20, 30, 40)
var currentTool = "PENCIL"
var brushSize = 6.0f
var zoom = 1.0
var rotation = 0.0
var gridOn = false
var snapOn = false
var shadowOn = false
var outlineOn = false
var neonOn = false
var particlesOn = false
var starfieldOn = false
var currentBackground = "SKY"
var currentStyle = "NORMAL"
var mouseDown = false
var startX = 0
var startY = 0
var lastX = 0
var lastY = 0
var selectedItem = ""
var frame: JFrame = null
var canvas: JPanel = null
var status: JLabel = null
var searchField: JTextField = null
var commandField: JTextField = null
var textField: JTextField = null
var itemModel = new DefaultListModel[String]()
var itemList: JList[String] = null
var undoStack =
scala.collection.mutable.Stack[BufferedImage]()
var redoStack =
scala.collection.mutable.Stack[BufferedImage]()
var animationRunning = false
var animationTick = 0
var importedImage: BufferedImage = null
// ============================================================
// IMAGE
// ============================================================
val image =
new BufferedImage(
W,
H,
BufferedImage.TYPE_INT_ARGB
)
val g =
image.createGraphics()
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
)
g.setRenderingHint(
RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY
)
g.setColor(Color.WHITE)
g.fillRect(0, 0, W, H)
// ============================================================
// BASIC HELPERS
// ============================================================
def statusText(s: String): Unit = {
if (status != null) status.setText(s)
}
def repaintCanvas(): Unit = {
if (canvas != null) canvas.repaint()
}
def copyImage(src: BufferedImage): BufferedImage = {
val dst =
new BufferedImage(
W,
H,
BufferedImage.TYPE_INT_ARGB
)
val cg = dst.createGraphics()
cg.setComposite(
java.awt.AlphaComposite.Src
)
cg.drawImage(
src,
0,
0,
null
)
cg.dispose()
dst
}
def remember(): Unit = {
undoStack.push(
copyImage(image)
)
redoStack.clear()
while (undoStack.size > 30) {
undoStack.remove(0)
}
}
def clearImage(): Unit = {
g.setTransform(
new AffineTransform()
)
g.setComposite(
java.awt.AlphaComposite.Src
)
g.setColor(
new Color(255,255,255,255)
)
g.fillRect(
0,
0,
W,
H
)
}
def restoreImage(src: BufferedImage): Unit = {
clearImage()
g.drawImage(
src,
0,
0,
null
)
repaintCanvas()
}
def makeButton(s: String): JButton = {
val b = new JButton(s)
b.setFocusable(false)
b.setFont(
new Font(
"Arial",
Font.BOLD,
11
)
)
b
}
// ============================================================
// UNDO / REDO
// ============================================================
def undo(): Unit = {
if (undoStack.nonEmpty) {
redoStack.push(
copyImage(image)
)
restoreImage(
undoStack.pop()
)
statusText(
"UNDO"
)
}
}
def redo(): Unit = {
if (redoStack.nonEmpty) {
undoStack.push(
copyImage(image)
)
restoreImage(
redoStack.pop()
)
statusText(
"REDO"
)
}
}
// ============================================================
// CANVAS MAPPING
// ============================================================
def drawW(): Int =
math.max(
1,
(W * zoom).toInt
)
def drawH(): Int =
math.max(
1,
(H * zoom).toInt
)
def canvasLeft(): Int =
(canvas.getWidth - drawW()) / 2
def canvasTop(): Int =
(canvas.getHeight - drawH()) / 2
def toImageX(x: Int): Int = {
val v =
((x - canvasLeft()) / zoom).toInt
math.max(
0,
math.min(W - 1, v)
)
}
def toImageY(y: Int): Int = {
val v =
((y - canvasTop()) / zoom).toInt
math.max(
0,
math.min(H - 1, v)
)
}
def insideCanvas(
x: Int,
y: Int
): Boolean = {
x >= canvasLeft() &&
x < canvasLeft() + drawW() &&
y >= canvasTop() &&
y < canvasTop() + drawH()
}
// ============================================================
// BACKGROUND
// ============================================================
def bgColors(name: String): Array[Color] = {
name.toUpperCase match {
case "SUNSET" =>
Array(
new Color(255,120,70),
new Color(90,30,150)
)
case "SUNRISE" =>
Array(
new Color(255,180,90),
new Color(255,240,180)
)
case "NIGHT" =>
Array(
new Color(8,15,55),
new Color(55,25,110)
)
case "SPACE" =>
Array(
new Color(2,4,20),
new Color(55,5,100)
)
case "OCEAN" =>
Array(
new Color(80,220,255),
new Color(5,70,170)
)
case "FOREST" =>
Array(
new Color(170,235,190),
new Color(30,115,55)
)
case "DESERT" =>
Array(
new Color(255,225,150),
new Color(190,125,60)
)
case "MAGIC" =>
Array(
new Color(220,185,255),
new Color(70,25,150)
)
case "NEON" =>
Array(
new Color(5,5,35),
new Color(80,0,110)
)
case "GOLD" =>
Array(
new Color(255,240,150),
new Color(170,110,20)
)
case "ICE" =>
Array(
new Color(235,255,255),
new Color(90,185,240)
)
case "VOLCANO" =>
Array(
new Color(255,130,40),
new Color(75,10,20)
)
case "CYBER" =>
Array(
new Color(3,15,30),
new Color(0,100,130)
)
case "GALAXY" =>
Array(
new Color(5,0,35),
new Color(100,0,150)
)
case _ =>
Array(
new Color(150,220,255),
new Color(100,190,120)
)
}
}
def drawBackground(name: String): Unit = {
val c = bgColors(name)
g.setTransform(
new AffineTransform()
)
g.setPaint(
new GradientPaint(
0,
0,
c(0),
0,
H,
c(1)
)
)
g.fillRect(
0,
0,
W,
H
)
val n = name.toUpperCase
if (
n == "NIGHT" ||
n == "SPACE" ||
n == "MAGIC" ||
n == "GALAXY" ||
n == "CYBER"
) {
g.setColor(
Color.WHITE
)
var i = 0
while (i < 180) {
val x =
math.abs(
(i * 97 + 31) % W
)
val y =
math.abs(
(i * 53 + 17) % H
)
val s =
1 + (i % 4)
g.fillOval(
x,
y,
s,
s
)
i += 1
}
}
if (
n == "SKY" ||
n == "SUNNY" ||
n == "SUNRISE" ||
n == "SUNSET"
) {
g.setColor(
new Color(255,220,80)
)
g.fillOval(
950,
45,
110,
110
)
}
if (n == "OCEAN") {
g.setColor(
new Color(10,100,190)
)
g.fillRect(
0,
510,
W,
190
)
g.setColor(
new Color(180,245,255)
)
var i = 0
while (i < 10) {
g.drawArc(
i * 140 - 70,
500,
180,
55,
0,
180
)
i += 1
}
}
if (n == "FOREST") {
g.setColor(
new Color(35,125,50)
)
g.fillRect(
0,
500,
W,
200
)
}
if (n == "DESERT") {
g.setColor(
new Color(225,175,90)
)
g.fillOval(
-100,
480,
650,
260
)
g.fillOval(
400,
450,
800,
280
)
}
if (n == "SPACE") {
g.setColor(
new Color(90,140,235)
)
g.fillOval(
450,
190,
240,
240
)
}
}
// ============================================================
// EFFECTS
// ============================================================
def applyEffects(): Unit = {
if (shadowOn) {
g.setColor(
new Color(0,0,0,70)
)
g.setStroke(
new BasicStroke(14)
)
g.drawRoundRect(
15,
15,
W - 30,
H - 30,
35,
35
)
}
if (
outlineOn ||
currentStyle == "COMIC"
) {
g.setColor(
new Color(15,15,15,210)
)
g.setStroke(
new BasicStroke(5)
)
g.drawRoundRect(
7,
7,
W - 14,
H - 14,
30,
30
)
}
if (
neonOn ||
currentStyle == "NEON"
) {
g.setColor(
new Color(0,255,255,160)
)
g.setStroke(
new BasicStroke(12)
)
g.drawRoundRect(
12,
12,
W - 24,
H - 24,
35,
35
)
g.setColor(
new Color(255,0,255,120)
)
g.setStroke(
new BasicStroke(4)
)
g.drawRoundRect(
25,
25,
W - 50,
H - 50,
30,
30
)
}
if (
particlesOn ||
currentStyle == "MAGIC"
) {
g.setColor(
Color.WHITE
)
var i = 0
while (i < 80) {
val x =
(i * 113) % W
val y =
(i * 71) % H
g.fillOval(
x,
y,
3 + i % 4,
3 + i % 4
)
i += 1
}
}
}
// ============================================================
// BASIC OBJECTS
// ============================================================
def drawCar(): Unit = {
g.setColor(
new Color(220,40,55)
)
g.fillRoundRect(
230,
360,
740,
150,
45,
45
)
val roof =
new java.awt.Polygon()
roof.addPoint(350,360)
roof.addPoint(490,210)
roof.addPoint(750,210)
roof.addPoint(880,360)
g.fillPolygon(roof)
g.setColor(
new Color(90,200,245)
)
g.fillRect(
470,
240,
115,
80
)
g.fillRect(
610,
240,
130,
80
)
g.setColor(Color.BLACK)
g.fillOval(
300,
450,
120,
120
)
g.fillOval(
780,
450,
120,
120
)
}
def drawHouse(): Unit = {
g.setColor(
new Color(245,210,135)
)
g.fillRect(
350,
280,
500,
300
)
val roof =
new java.awt.Polygon()
roof.addPoint(280,280)
roof.addPoint(600,70)
roof.addPoint(920,280)
g.setColor(
new Color(175,50,45)
)
g.fillPolygon(roof)
g.setColor(
new Color(110,70,45)
)
g.fillRect(
555,
400,
100,
180
)
g.setColor(
new Color(80,190,240)
)
g.fillRect(
390,
340,
90,
85
)
g.fillRect(
720,
340,
90,
85
)
}
def drawTree(): Unit = {
g.setColor(
new Color(130,80,40)
)
g.fillRoundRect(
555,
300,
90,
300,
25,
25
)
g.setColor(
new Color(35,170,70)
)
g.fillOval(
300,
120,
330,
250
)
g.fillOval(
550,
100,
330,
270
)
g.fillOval(
420,
45,
330,
270
)
}
def drawPerson(): Unit = {
g.setColor(
new Color(245,195,155)
)
g.fillOval(
500,
90,
170,
180
)
g.setColor(
new Color(50,30,25)
)
g.fillArc(
495,
65,
180,
105,
0,
180
)
g.setColor(Color.BLACK)
g.fillOval(
545,
165,
18,
18
)
g.fillOval(
610,
165,
18,
18
)
g.setColor(
new Color(50,120,220)
)
g.fillRoundRect(
450,
270,
270,
230,
35,
35
)
g.setColor(
new Color(245,195,155)
)
g.setStroke(
new BasicStroke(
28,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
g.drawLine(
470,
320,
330,
490
)
g.drawLine(
700,
320,
840,
490
)
g.setColor(
new Color(45,45,55)
)
g.setStroke(
new BasicStroke(
45,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
g.drawLine(
535,
500,
525,
640
)
g.drawLine(
635,
500,
645,
640
)
}
def drawCat(): Unit = {
g.setColor(
new Color(175,175,190)
)
g.fillOval(
400,
300,
400,
280
)
g.fillOval(
420,
110,
360,
300
)
val a =
new java.awt.Polygon()
a.addPoint(435,180)
a.addPoint(485,65)
a.addPoint(535,165)
g.fillPolygon(a)
val b =
new java.awt.Polygon()
b.addPoint(765,180)
b.addPoint(715,65)
b.addPoint(665,165)
g.fillPolygon(b)
g.setColor(
new Color(80,220,100)
)
g.fillOval(
500,
210,
45,
55
)
g.fillOval(
655,
210,
45,
55
)
g.setColor(Color.PINK)
g.fillOval(
585,
290,
35,
25
)
}
def drawDog(): Unit = {
g.setColor(
new Color(175,120,70)
)
g.fillOval(
390,
300,
420,
290
)
g.fillOval(
420,
120,
360,
300
)
g.setColor(
new Color(120,75,45)
)
g.fillOval(
380,
175,
100,
190
)
g.fillOval(
720,
175,
100,
190
)
g.setColor(Color.BLACK)
g.fillOval(
510,
220,
28,
30
)
g.fillOval(
665,
220,
28,
30
)
g.fillOval(
580,
305,
65,
45
)
}
def drawStar(): Unit = {
drawStarShape(
5,
280,
120,
CX,
CY
)
}
def drawStarShape(
points: Int,
outerRadius: Double,
innerRadius: Double,
cx: Int,
cy: Int
): Unit = {
val p =
new java.awt.Polygon()
var i = 0
while (
i < points * 2
) {
val a =
-math.Pi / 2 +
i * math.Pi / points
val r =
if (i % 2 == 0)
outerRadius
else
innerRadius
p.addPoint(
cx + (math.cos(a) * r).toInt,
cy + (math.sin(a) * r).toInt
)
i += 1
}
g.fillPolygon(p)
}
def drawHeart(): Unit = {
val p =
new Path2D.Double()
p.moveTo(
CX,
CY + 250
)
p.curveTo(
CX - 370,
CY + 20,
CX - 250,
CY - 220,
CX,
CY - 40
)
p.curveTo(
CX + 250,
CY - 220,
CX + 370,
CY + 20,
CX,
CY + 250
)
g.fill(p)
}
def drawFlower(): Unit = {
g.setStroke(
new BasicStroke(
22,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
g.setColor(
new Color(45,150,65)
)
g.drawLine(
CX,
350,
CX,
620
)
val petals =
Array(
Color.RED,
Color.PINK,
Color.MAGENTA,
Color.ORANGE,
new Color(130,80,220),
new Color(255,90,120)
)
var i = 0
while (i < 6) {
val a =
i * math.Pi / 3
val x =
CX + (math.cos(a) * 100).toInt - 70
val y =
230 + (math.sin(a) * 100).toInt - 70
g.setColor(
petals(i)
)
g.fillOval(
x,
y,
140,
140
)
i += 1
}
g.setColor(
Color.YELLOW
)
g.fillOval(
CX - 70,
160,
140,
140
)
}
def drawFish(): Unit = {
g.setColor(
new Color(50,150,230)
)
g.fillOval(
300,
260,
500,
280
)
val tail =
new java.awt.Polygon()
tail.addPoint(760,400)
tail.addPoint(930,270)
tail.addPoint(930,530)
g.fillPolygon(tail)
g.setColor(Color.BLACK)
g.fillOval(
410,
350,
30,
30
)
}
def drawRocket(): Unit = {
g.setColor(
new Color(220,225,235)
)
g.fillOval(
500,
100,
200,
400
)
g.setColor(
new Color(210,40,50)
)
val l =
new java.awt.Polygon()
l.addPoint(500,350)
l.addPoint(420,510)
l.addPoint(500,480)
g.fillPolygon(l)
val r =
new java.awt.Polygon()
r.addPoint(700,350)
r.addPoint(780,510)
r.addPoint(700,480)
g.fillPolygon(r)
g.setColor(
new Color(70,180,240)
)
g.fillOval(
555,
200,
90,
90
)
g.setColor(
Color.ORANGE
)
g.fillOval(
550,
455,
100,
180
)
}
def drawRobot(): Unit = {
g.setColor(
new Color(100,165,200)
)
g.fillRoundRect(
400,
300,
400,
280,
45,
45
)
g.setColor(
new Color(175,205,220)
)
g.fillRoundRect(
360,
90,
480,
230,
55,
55
)
g.setColor(Color.CYAN)
g.fillOval(
455,
165,
75,
75
)
g.fillOval(
670,
165,
75,
75
)
g.setColor(Color.DARK_GRAY)
g.fillRoundRect(
500,
250,
200,
40,
15,
15
)
g.setStroke(
new BasicStroke(10)
)
g.drawLine(
CX,
90,
CX,
30
)
g.setColor(Color.RED)
g.fillOval(
CX - 25,
5,
50,
50
)
}
// ============================================================
// GENERIC OBJECT ENGINE
// ============================================================
def drawGenericObject(name: String): Unit = {
val seed =
math.abs(
name.hashCode
)
val c =
new Color(
40 + seed % 180,
40 + (seed / 7) % 180,
40 + (seed / 13) % 180
)
g.setColor(c)
val kind =
seed % 10
if (kind == 0) {
g.fillRoundRect(
350,
180,
500,
360,
70,
70
)
} else if (kind == 1) {
g.fillOval(
350,
100,
500,
500
)
} else if (kind == 2) {
val p =
new java.awt.Polygon()
p.addPoint(CX,70)
p.addPoint(900,600)
p.addPoint(300,600)
g.fillPolygon(p)
} else if (kind == 3) {
g.fillRect(
330,
140,
540,
440
)
} else if (kind == 4) {
drawStarShape(
8,
260,
130,
CX,
CY
)
} else if (kind == 5) {
g.fillRoundRect(
300,
130,
600,
470,
120,
120
)
} else if (kind == 6) {
drawHeart()
} else if (kind == 7) {
drawFlower()
} else if (kind == 8) {
drawFish()
} else {
drawStar()
}
g.setColor(Color.BLACK)
g.setFont(
new Font(
"Arial",
Font.BOLD,
26
)
)
val label =
name.take(30)
val sw =
g.getFontMetrics.stringWidth(label)
g.drawString(
label,
CX - sw / 2,
665
)
}
// ============================================================
// HUGE OBJECT LIBRARY
// ============================================================
val things =
Array(
"CAR","SPORTS CAR","RACING CAR","TRUCK","BUS",
"TRAIN","AIRPLANE","HELICOPTER","ROCKET","BOAT",
"SHIP","SUBMARINE","BICYCLE","MOTORBIKE","SCOOTER",
"HOUSE","CASTLE","PALACE","LIGHTHOUSE","BRIDGE",
"SCHOOL","HOSPITAL","SHOP","TOWER","CITY",
"TREE","PALM TREE","FLOWER","MUSHROOM","CACTUS",
"MOUNTAIN","VOLCANO","ISLAND","CLOUD","RAINBOW",
"SUN","MOON","PLANET","EARTH","GALAXY",
"BOY","GIRL","MAN","WOMAN","PERSON","ROBOT",
"SUPERHERO","ASTRONAUT","SCIENTIST","KING","QUEEN",
"CAT","DOG","BIRD","FISH","SHARK","WHALE",
"DOLPHIN","LION","TIGER","ELEPHANT","HORSE",
"RABBIT","BEAR","PANDA","MONKEY","FOX","DEER",
"COW","GOAT","SHEEP","CHICKEN","DUCK","BUTTERFLY",
"BEE","SNAKE","CROCODILE","TURTLE",
"APPLE","BANANA","ORANGE","MANGO","WATERMELON",
"PIZZA","BURGER","CAKE","ICE CREAM","DONUT",
"GUITAR","PIANO","DRUM","MICROPHONE","SPEAKER",
"CAMERA","COMPUTER","PHONE","BOOK","PENCIL",
"CLOCK","KEY","LAMP","CHAIR","TABLE","BACKPACK",
"GLASSES","CUP","BOTTLE","CANDLE",
"STAR","HEART","DIAMOND","CROWN","TROPHY",
"GIFT","BALLOON","UMBRELLA","MAGIC WAND",
"FIRE","LIGHTNING","SNOWFLAKE",
"CRICKET BAT","CRICKET BALL","FOOTBALL","TENNIS BALL",
"BASKETBALL","TROPHY","MEDAL",
"CYBER CITY","AI ROBOT","FUTURE CAR","SPACE STATION",
"ALIEN PLANET","TIME MACHINE","HOLOGRAM","DRONE",
"FUTURE HOUSE","NEON TOWER"
)
// ============================================================
// SEARCH
// ============================================================
def searchItems(): Unit = {
val q =
searchField
.getText
.trim
.toLowerCase
itemModel.clear()
var i = 0
while (i < things.length) {
if (
q.length == 0 ||
things(i)
.toLowerCase
.contains(q)
) {
itemModel.addElement(
things(i)
)
}
i += 1
}
statusText(
"SEARCH: " + q
)
}
// ============================================================
// SMART OFFLINE COMMAND ENGINE
// ============================================================
def smartCommand(command: String): Unit = {
val c =
command
.trim
.toLowerCase
if (c.length == 0) return
if (
c.contains("clear")
) {
clearButtonAction()
} else if (
c.contains("undo")
) {
undo()
} else if (
c.contains("redo")
) {
redo()
} else if (
c.contains("random")
) {
val index =
scala.util.Random.nextInt(
things.length
)
drawItem(
things(index)
)
} else if (
c.contains("neon")
) {
neonOn = true
currentStyle = "NEON"
repaintCanvas()
} else if (
c.contains("magic")
) {
currentStyle = "MAGIC"
particlesOn = true
repaintCanvas()
} else if (
c.contains("gold")
) {
currentStyle = "GOLD"
currentBackground = "GOLD"
repaintCanvas()
} else if (
c.contains("space") ||
c.contains("galaxy")
) {
currentBackground = "GALAXY"
drawCurrentBackground()
} else if (
c.contains("night")
) {
currentBackground = "NIGHT"
drawCurrentBackground()
} else if (
c.contains("ocean")
) {
currentBackground = "OCEAN"
drawCurrentBackground()
} else if (
c.contains("grid")
) {
gridOn = !gridOn
repaintCanvas()
} else if (
c.contains("shadow")
) {
shadowOn = !shadowOn
repaintCanvas()
} else if (
c.contains("outline")
) {
outlineOn = !outlineOn
repaintCanvas()
} else if (
c.contains("animate")
) {
previewAnimation()
} else if (
c.contains("girl")
) {
drawItem("GIRL")
} else if (
c.contains("boy")
) {
drawItem("BOY")
} else if (
c.contains("cat")
) {
drawItem("CAT")
} else if (
c.contains("dog")
) {
drawItem("DOG")
} else if (
c.contains("car")
) {
drawItem("CAR")
} else if (
c.contains("house")
) {
drawItem("HOUSE")
} else if (
c.contains("tree")
) {
drawItem("TREE")
} else if (
c.contains("robot")
) {
drawItem("ROBOT")
} else if (
c.contains("rocket")
) {
drawItem("ROCKET")
} else if (
c.contains("flower")
) {
drawItem("FLOWER")
} else if (
c.contains("heart")
) {
drawItem("HEART")
} else if (
c.contains("star")
) {
drawItem("STAR")
} else {
var found = ""
var i = 0
while (
i < things.length &&
found == ""
) {
if (
things(i)
.toLowerCase
.contains(c)
) {
found = things(i)
}
i += 1
}
if (found != "") {
drawItem(found)
} else {
statusText(
"SMART COMMAND NOT FOUND"
)
}
}
}
// ============================================================
// DRAW ITEM
// ============================================================
def drawCurrentBackground(): Unit = {
clearImage()
drawBackground(
currentBackground
)
applyEffects()
repaintCanvas()
}
def drawItem(item: String): Unit = {
remember()
clearImage()
drawBackground(
currentBackground
)
val t =
item
.toLowerCase
g.setColor(
currentColor
)
if (t.contains("car")) {
drawCar()
} else if (
t.contains("house") ||
t.contains("castle") ||
t.contains("palace")
) {
drawHouse()
} else if (
t.contains("tree")
) {
drawTree()
} else if (
t.contains("boy") ||
t.contains("girl") ||
t.contains("man") ||
t.contains("woman") ||
t.contains("person")
) {
drawPerson()
} else if (
t.contains("cat")
) {
drawCat()
} else if (
t.contains("dog")
) {
drawDog()
} else if (
t.contains("fish") ||
t.contains("shark") ||
t.contains("whale") ||
t.contains("dolphin")
) {
drawFish()
} else if (
t.contains("flower")
) {
drawFlower()
} else if (
t.contains("star")
) {
drawStar()
} else if (
t.contains("heart")
) {
drawHeart()
} else if (
t.contains("rocket")
) {
drawRocket()
} else if (
t.contains("robot")
) {
drawRobot()
} else {
drawGenericObject(item)
}
applyEffects()
selectedItem =
item
repaintCanvas()
statusText(
"DRAWN: " + item
)
}
// ============================================================
// TEXT
// ============================================================
def drawText(): Unit = {
val text =
textField
.getText
.trim
if (text == "") {
statusText(
"TYPE TEXT FIRST"
)
return
}
remember()
g.setColor(
currentColor
)
g.setFont(
new Font(
"Arial",
Font.BOLD,
52
)
)
val width =
g.getFontMetrics
.stringWidth(text)
g.drawString(
text,
math.max(
20,
CX - width / 2
),
CY
)
repaintCanvas()
statusText(
"TEXT ADDED"
)
}
// ============================================================
// TRANSFORMS
// ============================================================
def transform(mode: String): Unit = {
remember()
val temp =
copyImage(image)
clearImage()
val tx =
g.create()
.asInstanceOf[Graphics2D]
tx.setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC
)
if (mode == "FLIP_H") {
tx.drawImage(
temp,
W,
0,
-W,
H,
null
)
} else if (mode == "FLIP_V") {
tx.drawImage(
temp,
0,
H,
W,
-H,
null
)
} else {
tx.translate(
CX,
CY
)
if (mode == "LEFT") {
tx.rotate(
-math.Pi / 2
)
} else {
tx.rotate(
math.Pi / 2
)
}
tx.translate(
-CX,
-CY
)
tx.drawImage(
temp,
0,
0,
null
)
}
tx.dispose()
repaintCanvas()
statusText(
"TRANSFORM: " + mode
)
}
// ============================================================
// IMPORT IMAGE
// ============================================================
def importImage(): Unit = {
val chooser =
new JFileChooser()
chooser.setDialogTitle(
"IMPORT IMAGE - JPG / PNG"
)
if (
chooser.showOpenDialog(frame) ==
JFileChooser.APPROVE_OPTION
) {
try {
val selected =
chooser.getSelectedFile
val loaded =
ImageIO.read(selected)
if (loaded != null) {
remember()
importedImage =
loaded
val iw =
loaded.getWidth
val ih =
loaded.getHeight
val scale =
math.min(
W.toDouble / iw,
H.toDouble / ih
)
val nw =
math.max(
1,
(iw * scale).toInt
)
val nh =
math.max(
1,
(ih * scale).toInt
)
val resized =
loaded.getScaledInstance(
nw,
nh,
Image.SCALE_SMOOTH
)
val x =
(W - nw) / 2
val y =
(H - nh) / 2
g.drawImage(
resized,
x,
y,
null
)
repaintCanvas()
statusText(
"IMAGE IMPORTED: " +
selected.getName
)
}
} catch {
case ex: Exception =>
JOptionPane.showMessageDialog(
frame,
"Could not import image.",
"IMAGE ERROR",
JOptionPane.ERROR_MESSAGE
)
}
}
}
// ============================================================
// SAVE
// ============================================================
def saveImage(): Unit = {
val chooser =
new JFileChooser()
chooser.setDialogTitle(
"SAVE PNG"
)
if (
chooser.showSaveDialog(frame) ==
JFileChooser.APPROVE_OPTION
) {
try {
var file =
chooser.getSelectedFile
if (
!file.getName
.toLowerCase
.endsWith(".png")
) {
file =
new File(
file.getAbsolutePath +
".png"
)
}
ImageIO.write(
image,
"png",
file
)
statusText(
"SAVED: " +
file.getName
)
} catch {
case _: Exception =>
statusText(
"SAVE ERROR"
)
}
}
}
// ============================================================
// CLEAR
// ============================================================
def clearButtonAction(): Unit = {
remember()
clearImage()
selectedItem = ""
repaintCanvas()
statusText(
"CANVAS CLEARED"
)
}
// ============================================================
// ANIMATION PREVIEW
// ============================================================
def previewAnimation(): Unit = {
val preview =
new JFrame(
"FUTURE ANIMATION PREVIEW"
)
preview.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE
)
preview.setSize(
1200,
800
)
preview.setLocationRelativeTo(
frame
)
var running = false
var tick = 0
val snapshot =
copyImage(image)
val panel =
new JPanel {
override def paintComponent(
graphics: Graphics
): Unit = {
super.paintComponent(
graphics
)
val pg =
graphics
.asInstanceOf[Graphics2D]
pg.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
)
val scale =
math.min(
(getWidth - 50).toDouble /
snapshot.getWidth,
(getHeight - 100).toDouble /
snapshot.getHeight
)
val iw =
(snapshot.getWidth * scale).toInt
val ih =
(snapshot.getHeight * scale).toInt
val x =
(getWidth - iw) / 2
val y =
(getHeight - ih) / 2
val angle =
if (running)
math.sin(tick * 0.08) * 0.035
else
0.0
val at =
new AffineTransform()
at.translate(
x + iw / 2,
y + ih / 2
)
at.rotate(angle)
at.translate(
-iw / 2,
-ih / 2
)
at.scale(
scale,
scale
)
pg.drawImage(
snapshot,
at,
null
)
}
}
val start =
makeButton(
"START / STOP"
)
val close =
makeButton(
"CLOSE"
)
val timer =
new Timer(
30,
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
if (running) {
tick += 1
panel.repaint()
}
}
}
)
start.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
running =
!running
if (running)
timer.start()
else
timer.stop()
}
}
)
close.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
timer.stop()
preview.dispose()
}
}
)
val controls =
new JPanel(
new FlowLayout()
)
controls.add(start)
controls.add(close)
preview.setLayout(
new BorderLayout()
)
preview.add(
panel,
BorderLayout.CENTER
)
preview.add(
controls,
BorderLayout.SOUTH
)
preview.setVisible(true)
}
// ============================================================
// BUTTONS
// ============================================================
val undoButton =
makeButton("UNDO")
val redoButton =
makeButton("REDO")
val clearButton =
makeButton("CLEAR")
val saveButton =
makeButton("SAVE PNG")
val importButton =
makeButton("IMPORT IMAGE")
val randomButton =
makeButton("RANDOM")
val drawButton =
makeButton("DRAW")
val colorButton =
makeButton("COLOR")
val textButton =
makeButton("TEXT")
val animateButton =
makeButton("ANIMATE")
val zoomInButton =
makeButton("ZOOM +")
val zoomOutButton =
makeButton("ZOOM -")
val flipHButton =
makeButton("FLIP H")
val flipVButton =
makeButton("FLIP V")
val rotateLButton =
makeButton("ROTATE L")
val rotateRButton =
makeButton("ROTATE R")
val gridButton =
makeButton("GRID")
val snapButton =
makeButton("SNAP")
val shadowButton =
makeButton("SHADOW")
val outlineButton =
makeButton("OUTLINE")
val neonButton =
makeButton("NEON")
val particleButton =
makeButton("PARTICLES")
// ============================================================
// TOOL COMBO
// ============================================================
val toolBox =
new JComboBox[String](
Array(
"PENCIL",
"ERASER",
"SPRAY",
"LINE",
"RECTANGLE",
"ELLIPSE",
"BRUSH",
"HIGHLIGHTER"
)
)
val sizeBox =
new JComboBox[String](
Array(
"2",
"4",
"6",
"8",
"12",
"16",
"20",
"30",
"40",
"60"
)
)
val backgroundBox =
new JComboBox[String](
Array(
"SKY",
"SUNNY",
"SUNRISE",
"SUNSET",
"NIGHT",
"SPACE",
"OCEAN",
"FOREST",
"DESERT",
"MAGIC",
"NEON",
"GOLD",
"ICE",
"VOLCANO",
"CYBER",
"GALAXY"
)
)
val styleBox =
new JComboBox[String](
Array(
"NORMAL",
"NEON",
"MAGIC",
"GOLD",
"COMIC",
"SOFT"
)
)
// ============================================================
// TEXT FIELDS
// ============================================================
commandField =
new JTextField(
"draw a futuristic car",
24
)
searchField =
new JTextField(
12
)
textField =
new JTextField(
"ULTRA LEGEND",
14
)
// ============================================================
// ITEM LIST
// ============================================================
itemList =
new JList[String](
itemModel
)
itemList.setFont(
new Font(
"Arial",
Font.BOLD,
13
)
)
itemList.setSelectionMode(
ListSelectionModel.SINGLE_SELECTION
)
var i = 0
while (i < things.length) {
itemModel.addElement(
things(i)
)
i += 1
}
// ============================================================
// STATUS
// ============================================================
status =
new JLabel(
"ULTRA LEGEND X READY"
)
status.setFont(
new Font(
"Arial",
Font.BOLD,
14
)
)
// ============================================================
// CANVAS
// ============================================================
canvas =
new JPanel {
override def paintComponent(
graphics: Graphics
): Unit = {
super.paintComponent(
graphics
)
val cg =
graphics
.asInstanceOf[Graphics2D]
cg.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
)
cg.setColor(
new Color(230,230,235)
)
cg.fillRect(
0,
0,
getWidth,
getHeight
)
val dw =
drawW()
val dh =
drawH()
val ox =
canvasLeft()
val oy =
canvasTop()
cg.drawImage(
image,
ox,
oy,
dw,
dh,
null
)
if (gridOn) {
cg.setColor(
new Color(0,0,0,35)
)
val step =
math.max(
20,
(50 * zoom).toInt
)
var x = ox
while (
x <= ox + dw
) {
cg.drawLine(
x,
oy,
x,
oy + dh
)
x += step
}
var y = oy
while (
y <= oy + dh
) {
cg.drawLine(
ox,
y,
ox + dw,
y
)
y += step
}
}
}
}
canvas.setFocusable(true)
canvas.setCursor(
Cursor.getPredefinedCursor(
Cursor.CROSSHAIR_CURSOR
)
)
// ============================================================
// LEFT PANEL
// ============================================================
val title =
new JLabel(
"OBJECT / AI LIBRARY"
)
title.setFont(
new Font(
"Arial",
Font.BOLD,
18
)
)
val searchPanel =
new JPanel(
new FlowLayout(
FlowLayout.LEFT,
3,
3
)
)
val searchButton =
makeButton(
"SEARCH"
)
searchPanel.add(
searchField
)
searchPanel.add(
searchButton
)
val leftPanel =
new JPanel(
new BorderLayout(
4,
4
)
)
leftPanel.setBorder(
new EmptyBorder(
5,
5,
5,
5
)
)
leftPanel.add(
title,
BorderLayout.NORTH
)
leftPanel.add(
searchPanel,
BorderLayout.CENTER
)
leftPanel.add(
new JScrollPane(itemList),
BorderLayout.SOUTH
)
// ============================================================
// TOOLBAR
// ============================================================
val toolbar =
new JPanel(
new FlowLayout(
FlowLayout.LEFT,
3,
3
)
)
toolbar.add(undoButton)
toolbar.add(redoButton)
toolbar.add(clearButton)
toolbar.add(saveButton)
toolbar.add(importButton)
toolbar.add(randomButton)
toolbar.add(
new JLabel("TOOL:")
)
toolbar.add(toolBox)
toolbar.add(
new JLabel("SIZE:")
)
toolbar.add(sizeBox)
toolbar.add(colorButton)
toolbar.add(gridButton)
toolbar.add(snapButton)
toolbar.add(shadowButton)
toolbar.add(outlineButton)
toolbar.add(neonButton)
toolbar.add(particleButton)
toolbar.add(
new JLabel("BG:")
)
toolbar.add(backgroundBox)
toolbar.add(
new JLabel("STYLE:")
)
toolbar.add(styleBox)
toolbar.add(zoomInButton)
toolbar.add(zoomOutButton)
toolbar.add(rotateLButton)
toolbar.add(rotateRButton)
toolbar.add(flipHButton)
toolbar.add(flipVButton)
// ============================================================
// AI COMMAND BAR
// ============================================================
val aiBar =
new JPanel(
new FlowLayout(
FlowLayout.LEFT,
5,
4
)
)
aiBar.add(
new JLabel(
"SMART COMMAND:"
)
)
val aiButton =
makeButton(
"RUN"
)
aiBar.add(
commandField
)
aiBar.add(
aiButton
)
// ============================================================
// TEXT BAR
// ============================================================
val textBar =
new JPanel(
new FlowLayout(
FlowLayout.LEFT,
5,
4
)
)
textBar.add(
new JLabel("TEXT:")
)
textBar.add(
textField
)
textBar.add(
textButton
)
textBar.add(
animateButton
)
// ============================================================
// FRAME
// ============================================================
frame =
new JFrame(
"ULTRA LEGEND SMART DRAW STUDIO X"
)
frame.setDefaultCloseOperation(
WindowConstants.EXIT_ON_CLOSE
)
frame.setSize(
1600,
950
)
frame.setLocationRelativeTo(
null
)
frame.setLayout(
new BorderLayout(
4,
4
)
)
frame.add(
toolbar,
BorderLayout.NORTH
)
frame.add(
leftPanel,
BorderLayout.WEST
)
frame.add(
canvas,
BorderLayout.CENTER
)
val south =
new JPanel(
new BorderLayout()
)
south.add(
aiBar,
BorderLayout.NORTH
)
south.add(
textBar,
BorderLayout.CENTER
)
south.add(
status,
BorderLayout.SOUTH
)
frame.add(
south,
BorderLayout.SOUTH
)
// ============================================================
// EVENTS
// ============================================================
toolBox.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
currentTool =
toolBox
.getSelectedItem
.toString
statusText(
"TOOL: " + currentTool
)
}
}
)
sizeBox.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
try {
brushSize =
sizeBox
.getSelectedItem
.toString
.toFloat
} catch {
case _: Exception =>
}
}
}
)
backgroundBox.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
currentBackground =
backgroundBox
.getSelectedItem
.toString
drawCurrentBackground()
}
}
)
styleBox.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
currentStyle =
styleBox
.getSelectedItem
.toString
if (
currentStyle == "NEON"
)
neonOn = true
if (
currentStyle == "MAGIC"
)
particlesOn = true
repaintCanvas()
statusText(
"STYLE: " +
currentStyle
)
}
}
)
colorButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val selected =
JColorChooser.showDialog(
frame,
"CHOOSE COLOR",
currentColor
)
if (selected != null) {
currentColor =
selected
statusText(
"COLOR CHANGED"
)
}
}
}
)
drawButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
smartCommand(
commandField.getText
)
}
}
)
aiButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
smartCommand(
commandField.getText
)
}
}
)
commandField.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
smartCommand(
commandField.getText
)
}
}
)
searchButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
searchItems()
}
}
)
searchField.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
searchItems()
}
}
)
itemList.addMouseListener(
new MouseAdapter {
override def mouseClicked(
e: MouseEvent
): Unit = {
val index =
itemList.locationToIndex(
e.getPoint
)
if (index >= 0) {
val value =
itemModel.getElementAt(
index
)
drawItem(value)
}
}
}
)
undoButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = undo()
}
)
redoButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = redo()
}
)
clearButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit =
clearButtonAction()
}
)
saveButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit =
saveImage()
}
)
importButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit =
importImage()
}
)
randomButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val index =
scala.util.Random.nextInt(
things.length
)
drawItem(
things(index)
)
}
}
)
textButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit =
drawText()
}
)
animateButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit =
previewAnimation()
}
)
zoomInButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
zoom =
math.min(
3.0,
zoom + 0.1
)
repaintCanvas()
statusText(
"ZOOM " +
(zoom * 100).toInt +
"%"
)
}
}
)
zoomOutButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
zoom =
math.max(
0.4,
zoom - 0.1
)
repaintCanvas()
statusText(
"ZOOM " +
(zoom * 100).toInt +
"%"
)
}
}
)
rotateLButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit =
transform("LEFT")
}
)
rotateRButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit =
transform("RIGHT")
}
)
flipHButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit =
transform("FLIP_H")
}
)
flipVButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit =
transform("FLIP_V")
}
)
gridButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
gridOn =
!gridOn
repaintCanvas()
statusText(
if (gridOn)
"GRID ON"
else
"GRID OFF"
)
}
}
)
snapButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
snapOn =
!snapOn
statusText(
if (snapOn)
"SNAP ON"
else
"SNAP OFF"
)
}
}
)
shadowButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
shadowOn =
!shadowOn
repaintCanvas()
}
}
)
outlineButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
outlineOn =
!outlineOn
repaintCanvas()
}
}
)
neonButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
neonOn =
!neonOn
repaintCanvas()
}
}
)
particleButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
particlesOn =
!particlesOn
repaintCanvas()
}
}
)
// ============================================================
// MOUSE DRAWING
// ============================================================
canvas.addMouseListener(
new MouseAdapter {
override def mousePressed(
e: MouseEvent
): Unit = {
if (
insideCanvas(
e.getX,
e.getY
)
) {
remember()
mouseDown = true
startX =
toImageX(
e.getX
)
startY =
toImageY(
e.getY
)
lastX = startX
lastY = startY
if (snapOn) {
startX =
(startX / 10) * 10
startY =
(startY / 10) * 10
}
if (
currentTool == "PENCIL" ||
currentTool == "ERASER" ||
currentTool == "BRUSH" ||
currentTool == "HIGHLIGHTER"
) {
g.setColor(
if (
currentTool == "ERASER"
)
Color.WHITE
else
currentColor
)
val alpha =
if (
currentTool ==
"HIGHLIGHTER"
)
80
else
255
g.setColor(
new Color(
currentColor.getRed,
currentColor.getGreen,
currentColor.getBlue,
alpha
)
)
if (
currentTool == "ERASER"
) {
g.setColor(
Color.WHITE
)
}
g.setStroke(
new BasicStroke(
if (
currentTool == "BRUSH"
)
brushSize * 2
else
brushSize,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
g.drawLine(
lastX,
lastY,
lastX,
lastY
)
}
if (
currentTool == "SPRAY"
) {
var s = 0
while (s < 50) {
val dx =
scala.util.Random.nextInt(
51
) - 25
val dy =
scala.util.Random.nextInt(
51
) - 25
g.setColor(
currentColor
)
g.fillOval(
startX + dx,
startY + dy,
3,
3
)
s += 1
}
}
repaintCanvas()
}
}
override def mouseReleased(
e: MouseEvent
): Unit = {
if (mouseDown) {
val x =
toImageX(
e.getX
)
val y =
toImageY(
e.getY
)
g.setColor(
currentColor
)
g.setStroke(
new BasicStroke(
brushSize,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
if (
currentTool == "LINE"
) {
g.drawLine(
startX,
startY,
x,
y
)
} else if (
currentTool == "RECTANGLE"
) {
val rx =
math.min(
startX,
x
)
val ry =
math.min(
startY,
y
)
val rw =
math.abs(
x - startX
)
val rh =
math.abs(
y - startY
)
g.drawRect(
rx,
ry,
rw,
rh
)
} else if (
currentTool == "ELLIPSE"
) {
val rx =
math.min(
startX,
x
)
val ry =
math.min(
startY,
y
)
val rw =
math.abs(
x - startX
)
val rh =
math.abs(
y - startY
)
g.drawOval(
rx,
ry,
rw,
rh
)
}
mouseDown = false
repaintCanvas()
}
}
}
)
canvas.addMouseMotionListener(
new MouseMotionAdapter {
override def mouseDragged(
e: MouseEvent
): Unit = {
if (
mouseDown &&
insideCanvas(
e.getX,
e.getY
)
) {
val x =
toImageX(
e.getX
)
val y =
toImageY(
e.getY
)
if (
currentTool == "PENCIL" ||
currentTool == "ERASER" ||
currentTool == "BRUSH" ||
currentTool == "HIGHLIGHTER"
) {
if (
currentTool == "ERASER"
) {
g.setColor(
Color.WHITE
)
} else if (
currentTool ==
"HIGHLIGHTER"
) {
g.setColor(
new Color(
currentColor.getRed,
currentColor.getGreen,
currentColor.getBlue,
80
)
)
} else {
g.setColor(
currentColor
)
}
g.setStroke(
new BasicStroke(
if (
currentTool == "BRUSH"
)
brushSize * 2
else
brushSize,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
g.drawLine(
lastX,
lastY,
x,
y
)
} else if (
currentTool == "SPRAY"
) {
var s = 0
while (s < 30) {
val dx =
scala.util.Random.nextInt(
41
) - 20
val dy =
scala.util.Random.nextInt(
41
) - 20
g.setColor(
currentColor
)
g.fillOval(
x + dx,
y + dy,
3,
3
)
s += 1
}
}
lastX = x
lastY = y
repaintCanvas()
}
}
}
)
// ============================================================
// FUTURISTIC SECRET KEY SYSTEM
// ============================================================
canvas.addKeyListener(
new KeyAdapter {
override def keyPressed(
e: KeyEvent
): Unit = {
val k =
e.getKeyCode
if (
e.isControlDown &&
k == KeyEvent.VK_Z
) undo()
else if (
e.isControlDown &&
k == KeyEvent.VK_Y
) redo()
else if (
e.isControlDown &&
k == KeyEvent.VK_S
) saveImage()
else if (
e.isControlDown &&
k == KeyEvent.VK_O
) importImage()
else if (
k == KeyEvent.VK_DELETE
) clearButtonAction()
else if (
k == KeyEvent.VK_F1
) {
JOptionPane.showMessageDialog(
frame,
"ULTRA LEGEND X SHORTCUTS\n\n" +
"CTRL+Z = UNDO\n" +
"CTRL+Y = REDO\n" +
"CTRL+S = SAVE\n" +
"CTRL+O = IMPORT IMAGE\n" +
"DELETE = CLEAR\n\n" +
"F1 = SHORTCUT GUIDE\n" +
"F2 = RANDOM OBJECT\n" +
"F3 = NEON MODE\n" +
"F4 = MAGIC MODE\n" +
"F5 = GRID\n" +
"F6 = SNAP\n" +
"F7 = SHADOW\n" +
"F8 = OUTLINE\n" +
"F9 = ZOOM IN\n" +
"F10 = ZOOM OUT\n" +
"F11 = ANIMATION\n" +
"F12 = SMART COMMAND\n\n" +
"ALT+LEFT = ROTATE LEFT\n" +
"ALT+RIGHT = ROTATE RIGHT\n" +
"ALT+H = FLIP HORIZONTAL\n" +
"ALT+V = FLIP VERTICAL",
"SECRET CONTROL CENTER",
JOptionPane.INFORMATION_MESSAGE
)
} else if (
k == KeyEvent.VK_F2
) {
randomButton.doClick()
} else if (
k == KeyEvent.VK_F3
) {
neonButton.doClick()
} else if (
k == KeyEvent.VK_F4
) {
currentStyle = "MAGIC"
particlesOn = true
repaintCanvas()
} else if (
k == KeyEvent.VK_F5
) {
gridButton.doClick()
} else if (
k == KeyEvent.VK_F6
) {
snapButton.doClick()
} else if (
k == KeyEvent.VK_F7
) {
shadowButton.doClick()
} else if (
k == KeyEvent.VK_F8
) {
outlineButton.doClick()
} else if (
k == KeyEvent.VK_F9
) {
zoomInButton.doClick()
} else if (
k == KeyEvent.VK_F10
) {
zoomOutButton.doClick()
} else if (
k == KeyEvent.VK_F11
) {
animateButton.doClick()
} else if (
k == KeyEvent.VK_F12
) {
commandField.requestFocusInWindow()
} else if (
e.isAltDown &&
k == KeyEvent.VK_LEFT
) {
rotateLButton.doClick()
} else if (
e.isAltDown &&
k == KeyEvent.VK_RIGHT
) {
rotateRButton.doClick()
} else if (
e.isAltDown &&
k == KeyEvent.VK_H
) {
flipHButton.doClick()
} else if (
e.isAltDown &&
k == KeyEvent.VK_V
) {
flipVButton.doClick()
}
}
}
)
// ============================================================
// START
// ============================================================
SwingUtilities.invokeLater(
new Runnable {
override def run(): Unit = {
frame.setVisible(
true
)
canvas.requestFocusInWindow()
statusText(
"ULTRA LEGEND X ONLINE - OFFLINE SMART ENGINE READY"
)
}
}
)
//