#4 Adds Rounded rectangles and Borders

Open
ingles98 wants to merge 3 commits from ingles98/master into pgimeno/master
1 changed files with 89 additions and 4 deletions
  1. 89 4
      Gspot.lua

+ 89 - 4
Gspot.lua

@@ -131,9 +131,25 @@ local lgprintf = version < 001000 and love.graphics.printf or function(text, x,
 
 local Gspot = {}
 
+-- Default unit
+local DEFAULT_UNIT = 16
+local DEFAULT_BORDER_OFFSET = 0.5
+local DEFAULT_BORDER_STYLE = "smooth" -- 'smooth' or 'rough'
+local DEFAULT_BORDER_WIDTH = DEFAULT_UNIT/4
 
 Gspot.style = { -- see Gspot.setComponentMax for colour values
-	unit = 16,
+	unit = DEFAULT_UNIT,
+	rectradius = DEFAULT_UNIT / 4,
+	rectsegments = DEFAULT_UNIT*10,
+	border = {
+		color = {},
+		style = DEFAULT_BORDER_STYLE,
+		width = DEFAULT_BORDER_WIDTH,
+		left = DEFAULT_BORDER_OFFSET,
+		right = DEFAULT_BORDER_OFFSET,
+		top = DEFAULT_BORDER_OFFSET,
+		bottom = DEFAULT_BORDER_OFFSET
+	},
 	font = love.graphics.newFont(10),
 	fg = {},
 	bg = {},
@@ -153,6 +169,7 @@ Gspot.setComponentMax = function(this, value)
 		st.default[1],st.default[2],st.default[3],st.default[4] = 96,96,96,255
 		st.hilite[1],st.hilite[2],st.hilite[3],st.hilite[4] = 128,128,128,255
 		st.focus[1],st.focus[2],st.focus[3],st.focus[4] = 160,160,160,255
+		st.border.color[1],st.border.color[2],st.border.color[3],st.border.color[4] = 0,0,0,0
 		if value == "native" then
 			Gspot.nativeColorMax = true
 			for i = 1, 4 do
@@ -175,6 +192,22 @@ Gspot.load = function(this)
 	local def = {
 		style = {
 			unit = this.style.unit,
+			rectradius = this.style.rectradius,
+			rectsegments = this.style.rectsegments,
+			border = {
+				color = {
+					this.style.border.color[1],
+					this.style.border.color[2],
+					this.style.border.color[3],
+					this.style.border.color[4]
+				},
+				style = this.style.border.style,
+				width = this.style.border.width,
+				left = this.style.border.left,
+				right = this.style.border.right,
+				top = this.style.border.top,
+				bottom = this.style.border.bottom
+			},
 			font = this.style.font,
 			fg = this.style.fg,
 			bg = this.style.bg,
@@ -501,7 +534,7 @@ Gspot.pos = setmetatable(pos, {__call = pos.load})
 
 Gspot.util = {
 	setshape = function(this, shape)
-		assert(shape == 'circle' or shape == 'rect' or not shape, 'shape must be "rect" or "circle" or nil')
+		assert(shape == 'circle' or shape == 'rect' or shape == 'roundrect'or not shape, 'shape must be "rect", "circle", "roundrect" or nil')
 		this.shape = shape
 		if this.shape == 'circle' and not this.pos.r then this.pos.r = this.pos.w / 2 end
 	end,
@@ -511,6 +544,21 @@ Gspot.util = {
 		if this.shape == 'circle' then
 			local segments = this.segments or math.max(pos.r, 8)
 			love.graphics.circle('fill', pos.x + pos.r, pos.y + pos.r, pos.r, segments)
+			if this:hasBorder() then
+				local border = this.style.border
+				-- Backup line style
+				local tmp_linewidth = love.graphics.getLineWidth()
+				local tmp_linestyle = love.graphics.getLineStyle()
+				-- Set new line style (if applicable)
+				love.graphics.setLineWidth(border.width or tmp_linewidth)
+				love.graphics.setLineStyle(border.style or tmp_linestyle)
+				-- Actually draw the border
+				local r = pos.r + border.top
+				love.graphics.circle('line', pos.x + r, pos.y + r, r, segments)
+				-- Reverting to backup line style
+				love.graphics.setLineWidth(tmp_linewidth)
+				love.graphics.setLineStyle(tmp_linestyle)
+			end
 		else
 			this:rect(pos)
 		end
@@ -520,7 +568,39 @@ Gspot.util = {
 		pos = this.Gspot:pos(pos.pos or pos or this.pos)
 		assert(pos:type() == 'Gspot.pos')
 		mode = mode or 'fill'
-		love.graphics.rectangle(mode, pos.x, pos.y, pos.w, pos.h)
+	
+		if this.shape == 'roundrect' then
+			love.graphics.rectangle(mode, pos.x, pos.y, pos.w, pos.h, this.style.rectradius, this.style.rectradius, this.style.rectsegments)
+		else
+			love.graphics.rectangle(mode, pos.x, pos.y, pos.w, pos.h)
+		end
+
+		if this:hasBorder() then
+			local border = this.style.border
+			local tmp_linewidth = love.graphics.getLineWidth()
+			local tmp_linestyle = love.graphics.getLineStyle()
+			local tmp_color = {love.graphics.getColor()}
+
+			love.graphics.setLineWidth(border.width or tmp_linewidth)
+			love.graphics.setLineStyle(border.style or tmp_linestyle)
+			setColor(border.color or tmp_color)
+
+			local x, y, w, h
+			x = pos.x -border.left
+			y = pos.y -border.top
+			w = pos.w +border.right +border.left
+			h = pos.h +border.bottom +border.top
+
+			if this.shape == 'roundrect' then
+				love.graphics.rectangle("line", x, y, w, h, this.style.rectradius, this.style.rectradius, this.style.rectsegments)
+			else
+				love.graphics.rectangle("line", x, y, w, h)
+			end
+
+			love.graphics.setLineWidth(tmp_linewidth)
+			love.graphics.setLineStyle(tmp_linestyle)
+			setColor(tmp_color)
+		end
 	end,
 
 	setimage = function(this, img)
@@ -712,6 +792,10 @@ Gspot.util = {
 	type = function(this)
 		return 'Gspot.element.'..this.elementtype
 	end,
+
+	hasBorder = function(this)
+		return this.style.border.color[4] > 0
+	end,
 }
 
 Gspot.element = {
@@ -725,6 +809,7 @@ Gspot.element = {
 		if circ then element.shape = 'circle' else element.shape = 'rect' end
 		if parent then element.style = setmetatable({}, {__index = parent.style})
 		else element.style = setmetatable({}, {__index = Gspot.style}) end
+		element.style.border = setmetatable({}, {__index = Gspot.style.border})
 		return setmetatable(element, {__index = Gspot[elementtype], __tostring = function(this) return this:type() .. ' (' .. this:getlevel() .. ')' end})
 	end,
 }
@@ -1221,4 +1306,4 @@ Gspot.progress = {
 setmetatable(Gspot.progress, {__index = Gspot.util, __call = Gspot.progress.load})
 
 
-return Gspot:setComponentMax("native")
+return Gspot:setComponentMax("native")