Added time controls and nice clock face

This commit is contained in:
Brandon Dyck 2024-04-11 21:42:11 -06:00
parent a8df373f93
commit f3da84db34
107 changed files with 25454 additions and 49 deletions

View File

@ -1,41 +1,6 @@
local MAX_MINUTES = 60 * 12 local Time = require"time"
local Time = {}
Time.__index = Time
local function newTimeRaw(rawMinutes)
local t = {
rawminutes = rawMinutes % MAX_MINUTES
}
return setmetatable(t, Time)
end
function Time:new(hour, minute)
return newTimeRaw((hour or 12) % 12 * 60 + (minute or 0))
end
function Time:get()
local h = math.floor(self.rawminutes / 60 % 12)
if h == 0 then h = 12 end
local m = self.rawminutes % 60
return h, m
end
function Time:getHoursSinceTwelve()
local h = self.rawminutes / 60
if h < 1 then h = h + 12 end
return h
end
function Time:addMinutes(minutes)
return newTimeRaw(self.rawminutes + minutes)
end
function Time:fmt()
local h, m = self:get()
return string.format("%2d:%02d", h, m)
end
local numberFont = love.graphics.newFont(100)
local function pointToTurns(x, y) local function pointToTurns(x, y)
local rawTurns = math.atan2(y, x) / 2 / math.pi local rawTurns = math.atan2(y, x) / 2 / math.pi
@ -68,17 +33,58 @@ function Hand:draw(turns)
end end
local function drawFaceCanvas(r)
local oldCanvas = love.graphics.getCanvas()
local canvas = love.graphics.newCanvas(2*r,2*r)
love.graphics.setCanvas(canvas)
love.graphics.push("all")
love.graphics.translate(r, r)
love.graphics.setColor(0.93, 0.8, 0)
love.graphics.circle("fill", 0, 0, r)
love.graphics.setColor(1, 1, 1)
love.graphics.circle("fill", 0, 0, 0.84*r)
love.graphics.setColor(0,0,0)
for i=1,60 do
love.graphics.rotate(math.pi/30)
love.graphics.circle("fill", 0.6*r, 0, 0.01*r)
end
love.graphics.setColor(0.87,0,0)
for i=1,12 do
love.graphics.rotate(math.pi/6)
love.graphics.circle("fill", 0.6*r, 0, 0.015*r)
end
local font = love.graphics.newFont("font/JosefinSans-Regular.ttf", r/6)
love.graphics.setColor(0,0,0)
for i=1,12 do
local s = tostring(i)
local h = font:getHeight()
local w = font:getWidth(s)
local tr = love.math.newTransform(0,0,-math.pi/6*i+math.pi)
tr = tr:apply(love.math.newTransform(w*0.5, h*0.4))
local x, y = tr:inverseTransformPoint(0, 0.72*r)
love.graphics.printf(s, font, x, y, r)
end
love.graphics.pop()
love.graphics.setCanvas(oldCanvas)
return canvas
end
local Clock = {} local Clock = {}
Clock.__index = Clock Clock.__index = Clock
function Clock:new(time, diameter, transform) function Clock:new(time, diameter)
local radius = diameter and diameter/2 or 300
local transform = love.math.newTransform(radius, radius)
local c = { local c = {
time = (time or Time:new()), time = (time or Time:new()),
minuteHand = Hand:new(240, {1,0,0}), minuteHand = Hand:new(240, {1,0,0}),
hourHand = Hand:new(180, {0,0.5,0.5}), hourHand = Hand:new(180, {0,0.5,0.5}),
dragging = false, dragging = false,
transform = transform or love.math.newTransform(), radius = radius,
radius = diameter and diameter/2 or 300 onSetHands = nil,
transform = transform,
faceCanvas = drawFaceCanvas(radius)
} }
return setmetatable(c, self) return setmetatable(c, self)
end end
@ -94,11 +100,9 @@ end
function Clock:draw() function Clock:draw()
local _, m = self.time:get() local _, m = self.time:get()
local h = self.time:getHoursSinceTwelve() local h = self.time:getHoursSinceTwelve()
love.graphics.push("all") love.graphics.push("all")
love.graphics.draw(self.faceCanvas)
love.graphics.applyTransform(self.transform) love.graphics.applyTransform(self.transform)
love.graphics.setColor(0.5, 0.5, 0.5)
love.graphics.circle("fill", 0, 0, self.radius)
self.minuteHand:draw(m / 60) self.minuteHand:draw(m / 60)
self.hourHand:draw(h / 12) self.hourHand:draw(h / 12)
love.graphics.pop() love.graphics.pop()
@ -122,13 +126,13 @@ local function clockPointAt(clock, x, y)
dMinutes = dMinutes - 60 dMinutes = dMinutes - 60
end end
clock.time = clock.time:addMinutes(dMinutes) clock.time = clock.time:addMinutes(dMinutes)
if clock.onSetHands then clock.onSetHands(clock.time) end
end end
function Clock:movemouse(x, y) function Clock:movemouse(x, y)
if self.dragging then if self.dragging then
local localX, localY = self.transform:inverseTransformPoint(x, y) local localX, localY = self.transform:inverseTransformPoint(x, y)
clockPointAt(self, x, y) clockPointAt(self, x, y)
-- TODO update clock hands
end end
end end
@ -136,7 +140,6 @@ function Clock:pressmouse(x, y, button)
if not self.dragging and button == 1 and clockContainsPoint(self, x,y) then if not self.dragging and button == 1 and clockContainsPoint(self, x,y) then
self.dragging = true self.dragging = true
clockPointAt(self, x, y) clockPointAt(self, x, y)
-- TODO update clock hands
end end
end end

View File

@ -1,3 +1,4 @@
function love.conf(t) function love.conf(t)
t.window.msaa = 3 t.window.msaa = 3
t.window.fullscreen = true
end end

Binary file not shown.

93
font/OFL.txt Normal file
View File

@ -0,0 +1,93 @@
Copyright 2010 The Josefin Sans Project Authors (https://github.com/ThomasJockin/JosefinSansFont-master), with Reserved Font Name "Josefin Sans".
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://openfontlicense.org
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

954
loveframes/changelog.txt Normal file
View File

@ -0,0 +1,954 @@
================================================
Version 11.3 - Alpha (Apr 28 - 2020)
================================================
[CHANGED] String functions len, sub, gsub, find replaced with utf8 versions
[ADDED] New properties: skin.controls.smallfont and skin.controls.imagebuttonfont
================================================
Version 11.2 - Alpha (Mar 6 - 2019)
================================================
[ADDED] New functions button.SetImage and button.GetImage
[ADDED] LoveFrames Demo
[ADDED] New Default skin with subskins
[FIXED] Colors as numbers
[CHANGED] Massive internal update and cleaning by ingsoc451 (https://love2d.org/forums/memberlist.php?mode=viewprofile&u=137519)
[CHANGED] Require system
[CHANGED] loveframes.util and loveframes.templates functions moved to loveframes
[CHANGED] utf8 moved to third-party
================================================
Version 11.0 - Alpha (Apr 15 - 2018)
================================================
[FIXED] updated to LÖVE 11.0
================================================
Version 0.10.1 - Alpha (Nov 13 - 2016)
================================================
[ADDED] a new property: image.stretch (boolean)
[ADDED] a new property: button.image (image) -- left aligned image
[ADDED] new properties: button.groupIndex (int) and button.checked (boolean)
[ADDED] new properties: imagebutton.groupIndex (int) and imagebutton.checked (boolean)
[ADDED] a new property: checkbox.groupIndex
[ADDED] a new function: wheelmoved
[FIXED] textinput - Unicode support
[FIXED] Update for LÖVE 0.10.1
[FIXED] Update stencil calls
================================================
Version 0.10 - Alpha (Release Date TBD)
================================================
[ADDED] a new object: tree
[ADDED] a new object: radiobutton
[ADDED] a new button method: GetDown()
[ADDED] support for relative object sizing
[ADDED] a new columnlist method: GetCellText(rowid, columnid)
[ADDED] a new button method: SetToggleable(bool)
[ADDED] a new button method: GetToggleable()
[ADDED] toggle functionality to the button object
[ADDED] resizing functinality to the columnlistheader object
[ADDED] horizontal scrolling to the columnlist object
[ADDED] a new columnlistarea method: GetVerticalScrollBody()
[ADDED] a new columnlistarea method: GetHorizontalScrollBody()
[ADDED] a new columnlist method: GetTotalColumnWidth()
[ADDED] a new columnlist method: SetColumnWidth(id, width)
[ADDED] a new columnlist method: GetColumnWidth(id)
[ADDED] a new columnlist method: ResizeColumns()
[ADDED] a new columnlist method: SetDefaultColumnWidth(width)
[ADDED] a new columnlist method: GetDefaultColumnWidth()
[ADDED] a new columnlist method: SetColumnResizeEnabled(bool)
[ADDED] a new columnlist method: GetColumnResizeEnabled()
[ADDED] a new columnlist method: SizeColumnToData()
[ADDED] a new columnlist method: SetColumnOrder(curid, newid)
[ADDED] a new columnlistheader method: SetName(name)
[ADDED] a new scrollbody method: GetScrollBar()
[ADDED] a new scrollbar method: ScrollTo(percent)
[ADDED] a new frame method: SetMaxSize(width, height)
[ADDED] a new frame method: GetMaxSize()
[ADDED] a new frame method: SetMinSize(width, height)
[ADDED] a new frame method: GetMinSize()
[ADDED] a new textinput method: ClearLine(line)
[ADDED] a new textinput method: SetTrackingEnabled(bool)
[ADDED] a new textinput method: GetTrackingEnabled()
[ADDED] a new list method: GetAutoScroll()
[FIXED] bug that would cause tabbuttons to be positioned incorrectly when scrolling with the mouse wheel
[FIXED] collision detection issue caused by list child objects not being updated when outside of their parent's bounding box
[FIXED] checkbox text becoming invisible when calling checkbox:SetText after switching to a custom state
[FIXED] an error caused by calling base:MoveToTop on an object parented to a panel object
[FIXED] nested list positioning issues
[FIXED] textinput.alltextselected being set to true when calling the SelectAll method on an empty single-line textinput
[FIXED] a bug that allowed frames to be resized when they where not being hovered
[FIXED] text:GetLines always returning nil
[FIXED] creating a newline in a multiline textinput with the return key would not reset the object's xoffset
[FIXED] the last character of a long line in a multiline textinput not being shown due to a text offset calculation issue
[FIXED] scrollbody now resizes to parent
[FIXED] textinput indicator now always visible
[FIXED] columnlist rows can have non-drawable extra info ("Blue" skin doesn't crash on it)
[CHANGED] columnlist row colors are now adjusted when a row is removed from the list
[CHANGED] columnlistarea.rowcolorindex now resets to 1 when the list is cleared
[CHANGED] columnlist:SetRowColumnText to columnlist:SetCellText
[CHANGED] columnlist:AdjustColumns to columnlist:PositionColumns
[CHANGED] license to zlib/libpng
[CHANGED] the loveframes table is now returned by init.lua
[CHANGED] template files are now expected to return a template table instead of calling loveframes.templates.Register
[CHANGED] textinput tries to scroll horizontally only if alt is pressed
[CHANGED] project-wide utf8 support
[CHANGED] the textinput's indicator is now always visible when being moved
================================================
Version 0.9.8.1 - Alpha (May 17 - 2014)
================================================
[ADDED] ability to specify a custom skin directory in a skin's lua file
[FIXED] frame:MakeTop not returning self in certain situations
[FIXED] ability to insert tabs into a textinput when all of the object's text was selected
[FIXED] ability to cause a single-line textinput to enter all text selected mode when no text had been entered
[CHANGED] returning false in a frame.OnClose event callback will prevent the frame from being removed
[CHANGED] tabs:AddTab now returns the tabbutton object associated with the new tab
================================================
Version 0.9.8 - Alpha (April 3 - 2014)
================================================
[ADDED] support for method chaining
[ADDED] a new tooltip method: GetPadding()
[ADDED] a new frame method: SetAlwaysOnTop(bool)
[ADDED] a new frame method: GetAlwaysOnTop()
[FIXED] text object link detection issues
[FIXED] loveframes.util.GetDirectoryContents returning incorrect require paths
[CHANGED] the text object will now detect newlines that are not separated by spaces
[REMOVED] support for LOVE 0.8.0
================================================
Version 0.9.7.2 - Alpha (January 29 - 2014)
================================================
[ADDED] a new closebutton method: SetAutoPosition(bool)
[ADDED] a new closebutton method: GetAutoPosition()
[ADDED] checkbox skin directives
[FIXED] ability to use the tab button in numberbox textinputs
[FIXED] text width being calculated incorrectly when max width was set to 0
[FIXED] base menus can no longer extend beyond the boundaries of the application window
[CHANGED] minor performance improvements for the following objects: list, columnlistarea, tabs
[CHANGED] closebuttons are now automatically positioned by default
[CHANGED] optimized loveframes.util.TableHasKey (thanks CyaNox)
================================================
Version 0.9.7.1 - Alpha (January 15 - 2014)
================================================
[ADDED] a new tooltip method: GetOffsetX()
[ADDED] a new tooltip method: GetOffsetY()
[ADDED] a new tooltip method: GetOffsets()
[ADDED] a new tooltip method: GetFollowCursor()
[ADDED] a new tooltip method: GetObject()
[ADDED] a new tooltip method: GetFont()
[ADDED] a new tooltip method: GetFollowObject()
[CHANGED] Moved library files to /libraries
[CHANGED] Upgraded to middleclass 3.0.1
================================================
Version 0.9.7 - Alpha (January 12 - 2014)
================================================
[ADDED] a new base method: textinput(text)
[ADDED] a new frame method: SetResizable(bool)
[ADDED] a new frame method: GetResizable()
[ADDED] a new frame method: SetMinWidth(width)
[ADDED] a new frame method: GetMinWidth()
[ADDED] a new frame method: SetMaxWidth(width)
[ADDED] a new frame method: GetMaxWidth()
[ADDED] a new frame method: SetMinHeight(height)
[ADDED] a new frame method: GetMinHeight()
[ADDED] a new frame method: SetMaxHeight(height)
[ADDED] a new frame method: GetMaxHeight()
[ADDED] a new progressbar method: SetText(text)
[ADDED] a new progressbar method: GetText()
[ADDED] a new tabs method: SetButtonAreaX(x)
[ADDED] a new tabs method: GetButtonAreaX()
[ADDED] a new tabs method: SetButtonAreaWidth(width)
[ADDED] a new tabs method: GetButtonAreaWidth()
[ADDED] a new tabs method: SetAutoButtonAreaWidth(bool)
[ADDED] a new tabs method: GetAutoButtonAreaWidth()
[ADDED] a new text method: SetLinksEnabled(enabled)
[ADDED] a new text method: GetLinksEnabled()
[ADDED] a new text method: SetDetectLinks(detect)
[ADDED] a new text method: GetDetectLinks()
[ADDED] a new textinput method: Copy()
[ADDED] a new textinput method: Paste()
[ADDED] a new textinput method: SelectAll()
[ADDED] a new textinput method: DeselectAll()
[ADDED] a new textinput method: SetMasked(masked)
[ADDED] a new textinput method: GetMasked()
[ADDED] a new textinput method: SetMaskChar(char)
[ADDED] a new textinput method: GetMaskChar()
[ADDED] a new textinput method: SetPlaceholderText(text)
[ADDED] a new textinput method: GetPlaceholderText()
[ADDED] a new tooltip method: SetOffsetX(xoffset)
[ADDED] a new tooltip method: SetOffsetY(yoffset)
[ADDED] a new tooltip method: GetText()
[ADDED] a new text event callback: OnClickLink(object, text)
[ADDED] a new frame event callback: OnResize(object, width, height)
[ADDED] a new util library function: TableHasValue(table, value)
[ADDED] a new util library function: GetHoverObject()
[ADDED] a new callback: textinput(text)
[ADDED] a new object: form
[ADDED] a new object: menu
[ADDED] a new skin drawing function: DrawOverTabPanel(object)
[ADDED] basic clipboard support for the textinput object (0.9.0 only)
[ADDED] custom cursor support for the textinput object
[ADDED] support for love.filesystem changes to loveframes.util.GetDirectoryContents (0.9.0 only)
[ADDED] support for text object link processing
[ADDED] loveframes.downobject
[ADDED] skin directives for the text object
[ADDED] functionality for resizing frames
[FIXED] error when pressing a function key while a textinput was focused
[FIXED] the tooltip object not setting the state of its text object
[FIXED] the text object not being set to the correct width in certain situations
[FIXED] textinput:GetText appending an extra newline to then end of the text string
[FIXED] text processing issues with the textinput object (0.9.0 only)
[FIXED] text positioning issues when moving the textinput's indicator with the left and right arrow keys
[FIXED] textinput character limit blocking user input when all text was selected
[CHANGED] cleaned up the tooltip object
[CHANGED] upgraded to middleclass 3.0
[CHANGED] loveframes.hoverobject is now used to store the currently hovered object
[CHANGED] textinput:SetText now repositions the object's indicator
[CHANGED] reworked the collision detection system for MAJOR performance improvements
[CHANGED] text object formatting options are now specified in a single table rathar than as individual arguments
[CHANGED] text can now be specified as a link via text formatting options
[CHANGED] text formatting options now support link colors
[REMOVED] base:IsTopCollision
================================================
Version 0.9.6.3 - Alpha (August 15 - 2013)
================================================
[CHANGED] the collapsible category icons used in the stock skins
[REMOVED] loveframes.info
================================================
Version 0.9.6.2 - Alpha (August 14 - 2013)
================================================
[FIXED] collapsiblecategory:GetOpen() returning a nil value
[CHANGED] loveframes.util.RemoveAll() now resets loveframes.hoverobject, loveframes.modalobject, loveframes.inputobject and loveframes.hover
[CHANGED] the frame topbar image of both stock skins back to the gradients used before the 0.9.6 update
[CHANGED] the stock skins now draw a gradient for the body of the frame object instead of a solid color
[CHANGED] slight color/drawing adjustments to the blue stock skin
[CHANGED] the collapsiblecategory object now checks its child object's visibility while closed to make sure it hasn't been marked as visible (mainly to prevent collision issues)
[REMOVED] examples menu from the debug library
[REMOVED] skin selector menu from the debug library
[REMOVED] many skin controls from the orange stock skin that are no longer needed
================================================
Version 0.9.6.1 - Alpha (August 12 - 2013)
================================================
[FIXED] blue stock skin setting an invalid image directory in its skin file
================================================
Version 0.9.6 - Alpha (August 12 - 2013)
================================================
[ADDED] a new base method: GetSkinName()
[ADDED] a new frame method: SetDockable(dockable)
[ADDED] a new frame method: GetDockable()
[ADDED] a new frame method: SetDockZoneSize(size)
[ADDED] a new frame method: GetDockZoneSize()
[ADDED] a new columnlist method: RemoveColumn(id)
[ADDED] a new columnlist method: SetColumnName(id, name)
[ADDED] a new columnlist method: RemoveRow(id)
[ADDED] a new columnlist method: SetRowColumnText(text, rowid, columnid)
[ADDED] a new columnlist method: SetRowColumnData(rowid, columndata)
[ADDED] a new columnlist method: SizeToChildren(max)
[ADDED] a new frame event callback: OnDock(object, dockobject)
[ADDED] a new tabs method: SetTabObject(id, object)
[ADDED] a new util library function: RectangleCollisionCheck(rect1, rect2)
[ADDED] a new util library function: DeepCopy(orig)
[ADDED] a new skins library function: Get(name)
[ADDED] a new skins library function: SetControl(name, control, value)
[ADDED] a new skins library function: SetImage(name, image, value)
[ADDED] a new skins library function: SetImageDirectory(name, dir)
[ADDED] a new skins library function: ReloadImages(name)
[ADDED] docking functionality for frame objects
[ADDED] skins can now define a separate skin to use as a base via skin.base
[ADDED] skins can now load images from external directories via the skin.imagedir setting (defaults to loveframes/skins/skin_name/images)
[ADDED] compatibility for LOVE 0.9.0
[CHANGED] scroll buttons for the tabs object are no longer removed and re-created everytime a new tab is added
[CHANGED] base:GetSkin() now returns the skin's table instead of the skin's name
[CHANGED] the frame topbar image of both stock skins to a different gradient
[FIXED] columnlist:GetSelectedRows() returning a nil value
[FIXED] syntax typo in textinput:RemoveFromText() (was textinput:RemoveFromeText())
[FIXED] object creation via datatables
[FIXED] multichoice:SelectChoice(choice) causing an error if called when a multichoice list was not open
[FIXED] multichoice object value not being reset when calling multichoice:Clear()
[FIXED] an error that would occurred when attempting to scroll a tabs object with the scroll wheel when the object had no tabs
[FIXED] colunlist:AddRow not working correctly with LuaJIT versions of LOVE
[REMOVED] drawing code from the orange stock skin (now inherits from the blue stock skin)
================================================
Version 0.9.5.14 - Alpha (June 25 - 2013)
================================================
[FIXED] columnlistheaders and columnlistrows not being clickable when the columnlist object was using a custom state
================================================
Version 0.9.5.13 - Alpha (June 24 - 2013)
================================================
[FIXED] tabbuttons not being clickable when the tabs object was using a custom state
================================================
Version 0.9.5.12 - Alpha (June 10 - 2013)
================================================
[ADDED] a new columnlist method: SelectRow(row, ctrl)
[ADDED] a new columnlist method: DeselectRow(row)
[ADDED] a new columnlist method: GetSelectedRows()
[ADDED] a new columnlist method: SetSelectionEnabled(bool)
[ADDED] a new columnlist method: GetSelectionEnabled()
[ADDED] a new columnlist method: SetMultiselectEnabled(bool)
[ADDED] a new columnlist method: GetMultiselectEnabled()
[ADDED] a new columnlistrow method: SetSelected(bool)
[ADDED] a new columnlistrow method: GetSelected()
[ADDED] a new columnlistrow method: SetColumnData(data)
[ADDED] a new columnlist event callback: OnRowRightClicked(parent, row, data)
[ADDED] a new columnlist event callback: OnRowSelected(parent, row, data)
[ADDED] a new util library function: GetCollisionCount()
[ADDED] a new util library function: GetHover()
[CHANGED] the default mousewheel scroll-amount value for the list object
[CHANGED] the list object no longer uses delta time for scrolling by default
[CHANGED] some of the columnlistrow object's colors in the default skins
================================================
Version 0.9.5.11 - Alpha (May 15 - 2013)
================================================
[ADDED] ability to use multiple fonts with the text object
[ADDED] a new checkbox method: SetEnabled(bool)
[ADDED] a new checkbox method: GetEnabled()
[ADDED] a new multichoice method: SetEnabled(bool)
[ADDED] a new multichoice method: GetEnabled()
[FIXED] being able to check a checkbox object while it was not down
[FIXED] collisions being detected on objects outside of the active state
[CHANGED] the checkbox event callback "OnChanged" now returns both the object and a boolean value representing whether or not the object is checked
================================================
Version 0.9.5.10 - Alpha (May 12 - 2013)
================================================
[ADDED] a new slider method: GetDecimals()
[ADDED] a new numberbox method: SetDecimals(decimals)
[ADDED] a new numberbox method: GetDecimals()
[ADDED] a new textinput method: SetVisible(bool) (override of the base SetVisible method)
[FIXED] the textinput object's "keydown" property not reseting when the object was not visible
================================================
Version 0.9.5.9 - Alpha (May 8 - 2013)
================================================
[FIXED] the slider event callback "OnRelease" not being called when the sliderbutton was released while being dragged in a non-hover state
================================================
Version 0.9.5.8 - Alpha (May 5 - 2013)
================================================
[ADDED] a new textinput method: SetValue(value) (alias of SetText(text))
[ADDED] a new textinput method: GetValue() (alias of GetText())
[ADDED] a new object: grid
[ADDED] a new frame method: SetIcon(icon)
[ADDED] a new frame method: GetIcon()
[ADDED] a new callback for the slider object: OnRelease(object)
[ADDED] a new text method: SetDefaultColor(r, g, b, a)
[ADDED] a new text method: GetDefaultColor()
[FIXED] OnOpened and OnClosed callbacks for tabbuttons not being asigned properly
[FIXED] the image object not checking its hover state
[FIXED] tabbutton rendering issues with the default skins
[FIXED] some padding issues with multiline textinputs
[CHANGED] loveframes.config["DIRECTORY"] no longer needs to be set when installing Love Frames
================================================
Version 0.9.5.7 - Alpha (April 9 - 2013)
================================================
[FIXED] some issues with positioning the textinput object's text
================================================
Version 0.9.5.6 - Alpha (March 29 - 2013)
================================================
[FIXED] numberbox:SetValue not functioning correctly
================================================
Version 0.9.5.5 - Alpha (March 23 - 2013)
================================================
[ADDED] a new textinput method: SetRepeatDelay(delay)
[ADDED] a new textinput method: GetRepeatDelay()
[ADDED] a new textinput method: SetRepeatRate(rate)
[ADDED] a new textinput method: GetRepeatRate()
[FIXED] several typos in the numberbox object's code
[CHANGED] love frames now resets the active font to the font used before calling loveframes.draw()
[REMOVED] loveframes.util.CheckForUpdates()
================================================
Version 0.9.5.4 - Alpha (March 5 - 2013)
================================================
[ADDED] a new multichoice method: RemoveChoice(choice)
[ADDED] a new multichoice method: Clear()
[FIXED] a bug with list:RemoveItem that would cause an error when providing an argument that wasn't a number
[FIXED] the list object not resizing correctly when using list:RemoveItem and providing a number as an argument
================================================
Version 0.9.5.3 - Alpha (February 25 - 2013)
================================================
[FIXED] mousereleased never getting called on the collapsiblecategory's object
================================================
Version 0.9.5.2 - Alpha (February 24 - 2013)
================================================
[ADDED] a new slider method: SetEnabled(bool)
[ADDED] a new slider method: GetEnabled()
[FIXED] a resizing/layout issue with the columnlist object
[FIXED] base:GetChildren being declared twice and base:GetInternals never being declared
[CHANGED] major performance improvements for the default skins Blue and Orange
[REMOVED] the "Blue (basic)" skin
[REMOVED] the "Orange (basic)" skin
================================================
Version 0.9.5.1 - Alpha (February 17 - 2013)
================================================
[ADDED] a new slider method: SetScrollable(bool)
[ADDED] a new slider method: GetScrollable()
[ADDED] a new slider method: SetScrollIncrease(increase)
[ADDED] a new slider method: GetScrollIncrease()
[ADDED] a new slider method: SetScrollDecrease(decrease)
[ADDED] a new slider method: GetScrollDecrease()
[ADDED] a new multichoice method: Sort(func)
[ADDED] a new multichoice method: SetSortFunction(func)
[ADDED] a new multichoice method: GetSortFunction()
[ADDED] support for scrolling the slider object with the mouse wheel
[FIXED] the slider event callback "OnValueChanged" not passing the slider's new value in certain situations
[FIXED] some typos in the changelog
[CHANGED] the default mouse wheel scroll amounts of the scrollable objects (list, columnlist, tabs, multichoice)
[CHANGED] minor modifications to the default skins
[CHANGED] objects can now be centered when using the base methods SetPos, SetX, and SetY (ex: object:SetPos(x, y, true) would center the object at the position specified by x and y)
================================================
Version 0.9.5 - Alpha (February 11 - 2013)
================================================
[ADDED] state system
[ADDED] a new base method: SetState(name)
[ADDED] a new base method: GetState()
[ADDED] a new list method: EnableHorizontalStacking(bool)
[ADDED] a new list method: GetHorizontalStacking()
[ADDED] a new list method: SetDTScrolling(bool)
[ADDED] a new list method: GetDTScrolling()
[ADDED] a new image method: GetImageSize()
[ADDED] a new image method: GetImageWidth()
[ADDED] a new image method: GetImageHeight()
[ADDED] a new imagebutton method: GetImageSize()
[ADDED] a new imagebutton method: GetImageWidth()
[ADDED] a new imagebutton method: GetImageHeight()
[ADDED] a new tabs method: RemoveTab(id)
[ADDED] a new tabs method: SetButtonScrollAmount(amount)
[ADDED] a new tabs method: GetButtonScrollAmount()
[ADDED] a new tabs method: SetMouseWheelScrollAmount(amount)
[ADDED] a new tabs method: GetMouseWheelScrollAmount()
[ADDED] a new tabs method: SetDTScrolling(bool)
[ADDED] a new tabs method: GetDTScrolling()
[ADDED] a new columlist method: SetDTScrolling(bool)
[ADDED] a new columlist method: GetDTScrolling()
[ADDED] a new multichoice method: SetDTScrolling(bool)
[ADDED] a new multichoice method: GetDTScrolling()
[ADDED] a new base library function: loveframes.SetState(name)
[ADDED] a new base library function: loveframes.GetState()
[ADDED] a new object: numberbox
[ADDED] support for horizontal stacking of list object items when the list object's display mode is set to vertical
[FIXED] an error that would occur when providing a number as the text argument for textinput:SetText(text)
[FIXED] default skin images becoming distorted at certain positions on the screen
[FIXED] being able to clear a textinput's text by pressing an unusable key while all of the object's text was selected
[FIXED] several typos in the changelog
[CHANGED] the SetColor method for the image object now checks for four arguments (r, g, b, a) instead of one (table)
[CHANGED] major code cleanup for the default skins
[CHANGED] list:RemoveItem now accepts either an object or a number as an argument
[CHANGED] miscellaneous changes/improvements to various sections of code
[CHANGED] the images of the default skins
================================================
Version 0.9.4.15 - Alpha (January 5 - 2013)
================================================
[ADDED] a new base method: GetInternals()
[ADDED] a new tooltip method: SetFollowObject(bool)
================================================
Version 0.9.4.14 - Alpha (January 4 - 2013)
================================================
[ADDED] a new util library function: loveframes.util.CheckForUpdates() (note: this function is meant to be used by the developer and is never called internally by Love Frames)
[ADDED] a new callback for the tabbutton object: OnOpened(object)
[ADDED] a new callback for the tabbutton object: OnClosed(object)
[CHANGED] tabs:AddTab(name, object, tip, image) now accepts two new optional arguments for tabbutton callbacks (ex: tabs:AddTab(name, object, tip, image, onopened, onclosed))
================================================
Version 0.9.4.13 - Alpha (January 4 - 2013)
================================================
[ADDED] a new base method: IsInList()
[FIXED] not being able to add the boolean "false" to a template as a property with loveframes.templates.AddProperty(templatename, object, property, value)
[CHANGED] small code cleanup
[CHANGED] improved performance of the text object while parented within a list object
================================================
Version 0.9.4.12 - Alpha (December 30 - 2012)
================================================
[CHANGED] newlines created on the text object with \n now display properly
[CHANGED] Love Frames now resets the current drawing color to the last color used before calling loveframes.draw() after it has finished all drawing operations
================================================
Version 0.9.4.11 - Alpha (December 28 - 2012)
================================================
[ADDED] a new textinput method: SetAutoScroll(bool)
[ADDED] a new textinput method: GetAutoScroll()
[FIXED] a couple of typos in the changelog
[FIXED] a sliderbutton calculation error that caused the sliderbutton object to flash while moving the cursor out of it's bounding box while it was down
[CHANGED] cleaned up a lot of code
[CHANGED] the text object's shadow color now defaults to black
================================================
Version 0.9.4.10 - Alpha (December 26 - 2012)
================================================
[FIXED] registration errors for the new default skins
================================================
Version 0.9.4.9 - Alpha (December 26 - 2012)
================================================
[ADDED] a new default skin: Blue (basic)
[ADDED] a new default skin: Orange (basic)
[ADDED] a new skins library function: loveframes.skins.GetAvailable()
[CHANGED] the license from CC BY-SA 3.0 to CC BY 3.0
[CHANGED] made minor improvements to the default skins
================================================
Version 0.9.4.8 - Alpha (December 24 - 2012)
================================================
[ADDED] a new text method: SetShadow(bool)
[ADDED] a new text method: GetShadow()
[ADDED] a new text method: SetShadowOffsets(offsetx, offsety)
[ADDED] a new text method: GetShadowOffsets()
[ADDED] a new text method: SetShadowColor(r, g, b, a)
[ADDED] a new text method: GetShadowColor()
[ADDED] a new columnlist method: SetColumnHeight(height)
[FIXED] templates not being applied to objects
[CHANGED] the columnlistarea object now has better sorting
[CHANGED] the frame object no longer sets the size of it's close button
================================================
Version 0.9.4.7 - Alpha (December 19 - 2012)
================================================
[FIXED] textinput:SetFocus(focus) not working properly
[CHANGED] the tooltip object is now positionable via the standard positioning methods when not set to follow the cursor
================================================
Version 0.9.4.6 - Alpha (December 10 - 2012)
================================================
[ADDED] a new textinput event callback: OnFocusGained(object)
[ADDED] a new textinput event callback: OnFocusLost(object)
[FIXED] the textinput object accepting input from the tab and delete keys when object.editable was set to false
[CHANGED] all "." are now replaced with "/" in loveframes.config["DIRECTORY"] after all inernal Love Frames libraries have been loaded (this is to prevent filesystem errors)
[REMOVED] loveframes.util.TrimString(string)
================================================
Version 0.9.4.5 - Alpha (November 28 - 2012)
================================================
[FIXED] text inputs not losing focus in certain situations
================================================
Version 0.9.4.4 - Alpha (November 24 - 2012)
================================================
[ADDED] a new text input method: SetButtonScrollAmount(amount)
[ADDED] a new text input method: GetButtonScrollAmount()
[ADDED] a new text input method: SetMouseWheelScrollAmount(amount)
[ADDED] a new text input method: GetMouseWheelScrollAmount()
[ADDED] a new multichoice method: SetButtonScrollAmount(amount)
[ADDED] a new multichoice method: GetButtonScrollAmount()
[ADDED] a new multichoice method: SetMouseWheelScrollAmount(amount)
[ADDED] a new multichoice method: GetMouseWheelScrollAmount()
[ADDED] a new column list method: SetButtonScrollAmount(amount)
[ADDED] a new column list method: GetButtonScrollAmount()
[ADDED] a new column list method: SetMouseWheelScrollAmount(amount)
[ADDED] a new column list method: GetMouseWheelScrollAmount()
[ADDED] a new frame method: SetParentLocked(bool)
[ADDED] a new frame method: GetParentLocked()
[ADDED] a new base method: CenterWithinArea(x, y, width, height)
[ADDED] a new library function: loveframes.NewObject(id, name, inherit_from_base)
[FIXED] an error that would occur when clicking a scroll button on a multiline text input or a multichoice list
[FIXED] a button calculation error that caused the button object to flash while moving the cursor out of it's bounding box while it was down
[FIXED] several errors that could occur when a collapsible category did not have an object
[FIXED] the value of the slider object becoming -0 in certain situations
[CHANGED] the close button object is no longer positioned internally by the frame object and should now be positioned by it's skin drawing function
[CHANGED] all Love Frames objects are now stored within loveframes.objects
[CHANGED] frames are now draggable when parented to any object
[CHANGED] the look of the debug overlay
================================================
Version 0.9.4.3 - Alpha (November 20 - 2012)
================================================
[ADDED] a new base method: SetProperty(name, value)
[ADDED] a new base method: GetProperty(name)
[ADDED] a new list method: SetButtonScrollAmount(amount)
[ADDED] a new list method: GetButtonScrollAmount()
[ADDED] a new list method: SetMouseWheelScrollAmount(amount)
[ADDED] a new list method: GetMouseWheelScrollAmount()
[FIXED] a typo in the changelog
[FIXED] image:SetScale(scalex, scaley) not working correctly
[CHANGED] loveframes.util.GetDirContents(dir, t) to loveframes.util.GetDirectoryContents(dir, t)
[CHANGED] arguments passed to require() to use "." instead of "/" which should fix file loading issues on certain systems
================================================
Version 0.9.4.2 - Alpha (November 5 - 2012)
================================================
[ADDED] a new text object method: SetIgnoreNewlines(bool)
[ADDED] a new text object method: GetIgnoreNewlines()
[ADDED] a new image method: SetOrientation(orientation)
[ADDED] a new image method: GetOrientation()
[ADDED] a new image method: SetScaleX(scalex)
[ADDED] a new image method: GetScaleX()
[ADDED] a new image method: SetScaleY(scaley)
[ADDED] a new image method: GetScaleY()
[ADDED] a new image method: SetScale(scalex, scaley)
[ADDED] a new image method: GetScale()
[ADDED] a new image method: SetOffsetX(x)
[ADDED] a new image method: GetOffsetX()
[ADDED] a new image method: SetOffsetY(y)
[ADDED] a new image method: GetOffsetY()
[ADDED] a new image method: SetOffset(x, y)
[ADDED] a new image method: GetOffset()
[ADDED] a new image method: SetShearX(x)
[ADDED] a new image method: GetShearX()
[ADDED] a new image method: SetShearY(y)
[ADDED] a new image method: GetShearY()
[ADDED] a new image method: SetShear(x, y)
[ADDED] a new image method: GetShear()
[FIXED] an error that occurred after pressing enter on a multiline text input while all of it's text was selected
[FIXED] text in a single line text input always being cleared when the enter key was pressed
[FIXED] a syntax error in both default skin files that caused imaged to draw incorrect when they had a custom color
[FIXED] an error that would occur when a tab button was being drawn while no font had been set
[FIXED] textinput.OnTextChanged being called too early when using the backspace key or the delete key
[CHANGED] tab buttons no longer calculate their width from within their internal drawing function and should be sized externally from now on
[CHANGED] the text object now calculates what characters should be drawn while in a list object to improve performance with list objects that contain large amounts of text
================================================
Version 0.9.4.1 - Alpha (October 25 - 2012)
================================================
[ADDED] support for using the delete key in text input objects
[FIXED] textinupt:GetText() only returning the first line of a multiline text input
[FIXED] an error that occurred when clicking a multiline text input object after setting the object's text to an empty string with textinput:SetText("")
[FIXED] incorrect positioning of the text input object's indicator when using the left or right arrow keys to move the object's indicator to a different line
[FIXED] the text input object not creating a new line correctly in certain situations
[CHANGED] textinput:GetText() now returns the object's text with line breaks
================================================
Version 0.9.4 - Alpha (October 22 - 2012)
================================================
[ADDED] a new base method: SetDrawOrder()
[ADDED] a new base method: GetDrawOrder()
[ADDED] a new text method: GetFormattedText()
[ADDED] a new text input method: SetEditable(bool)
[ADDED] a new text input method: GetEditable()
[ADDED] a new text input method: GetUsable()
[ADDED] a new text input method: GetUnusable()
[ADDED] a new system for creating and applying templates to objects
[FIXED] a few incorrect entries in the changelog and added a few entries that were meant to be in the last upadte's changelog
[FIXED] an error that occurred when clicking on a frame that was parented to another frame
[FIXED] frames not being positioned properly if they were parented to another object
[FIXED] modal background object not drawing over umodaled objects in certain situations
[FIXED] an error that would occur when a multichoice list object would become scrollable
[FIXED] an error that would occur when a the column list object had no columns
[FIXED] multichoice object not positioning itself properly if it's parent was the base object
[CHANGED] text:GetText() now returns a string of the object's text
[CHANGED] parented frames can no longer be modaled
================================================
Version 0.9.3.2 - Alpha (Spetember 29 - 2012)
================================================
[ADDED] a new base method: SetDrawOrder()
[ADDED] a new text input method: SetMultiline(bool)
[ADDED] a new text input method: GetVerticalScrollBody()
[ADDED] a new text input method: GetHorizontalScrollBody()
[ADDED] a new text input method: SetText(text)
[ADDED] a new text input method: HasVerticalScrollBar()
[ADDED] a new text input method: HasHorizontalScrollBar()
[ADDED] a new text input method: GetFont()
[ADDED] a new text input method: GetLineNumbersPanel()
[ADDED] a new text input method: GetMultiline()
[ADDED] a new text input method: GetTextX()
[ADDED] a new text input method: GetTextY()
[ADDED] a new text input method: IsAllTextSelected()
[ADDED] a new text input method: GetLines()
[ADDED] a new text input method: GetOffsetX()
[ADDED] a new text input method: GetOffsetY()
[ADDED] a new text input method: GetIndicatorX()
[ADDED] a new text input method: GetIndicatorY()
[ADDED] a new text input method: SetLineNumbersEnabled(enabled)
[ADDED] a new text input method: GetLineNumbersEnabled()
[ADDED] a new text input method: GetItemWidth()
[ADDED] a new text input method: GetItemHeight()
[ADDED] a new text input method: SetTabReplacement(tabreplacement)
[ADDED] a new text input method: GetTabReplacement()
[ADDED] a new scroll area method: GetBarType()
[ADDED] a new scroll bar method: IsDragging()
[ADDED] a new scroll bar method: GetBarType()
[ADDED] a new scroll button method: GetScrollType()
[ADDED] a new tab button method: GetText()
[ADDED] a new tab button method: GetImage()
[ADDED] a new tab button method: GetTabNumber()
[ADDED] a new column list header method: GetName()
[ADDED] a new column list row method: GetColumnData()
[ADDED] a new multichoice method: SetText(text)
[ADDED] a new multichoice method: GetText()
[ADDED] a new multichoice row method: GetText()
[ADDED] a new progressbar method: GetBarWidth()
[ADDED] a new internal object: linenumberspanel
[ADDED] multiline support for the text input object
[ADDED] ability to select all text within a text input
[FIXED] progressbar object not positioning itself properly if it's parent was the base object
[FIXED] a typo in the syntax of loveframes.util.SplitString (was "SplitSring", changed to "SplitString")
[FIXED] the tooltip object not disappearing if it was visible when it's object's visibility was changed to false
[FIXED] the text input object's x offset not being adjusted initially when the width of it's text would would become wider than it's drawing area
[CHANGED] massive code cleanup for optimization and
[CHANGED] frames can now be parent to other objects
[CHANGED] textinput:RunBlink() to textinput:UpdateIndicator()
[CHANGED] textinput:GetBlinkerVisisbility() to textinput:GetIndicatorVisisbility()
[CHANGED] textinput:MoveBlinker(num, exact) to textinput:MoveIndicator(num, exact)
[CHANGED] scrollbars now only autoscroll when their list's item width/height is greater than their previous list's previous item width/height
[CHANGED] cleaned up the code for the default skins
[CHANGED] the text input object's text is no longer drawn internally by the object and should now be draw within the object's skin drawing function
[CHANGED] the column list row object's text is no longer drawn internally by the object and should now be draw within the object's skin drawing function
[REMOVED] textinput:SetTextColor(color)
[REMOVED] columnlistrow:SetTextColor()
================================================
Version 0.9.3.1 - Alpha (Spetember 2 - 2012)
================================================
[ADDED] numpad enter key support for textinput.OnEnter
[FIXED] duplicate progressbar:GetCompleted() in progressbar.lua
[CHANGED] textinput.OnTextEnterd to textinput.OnTextChanged
[CHANGED] textinput.OnTextChanged is now also called when the backspace key is pressed
================================================
Version 0.9.3 - Alpha (Spetember 1 - 2012)
================================================
[ADDED] a new base method: GetParents()
[ADDED] a new base method: IsTopInternal()
[ADDED] a new base method: IsInternal()
[ADDED] a new base method: GetType()
[ADDED] a new checkbox method: GetFont()
[ADDED] a new checkbox method: GetBoxSize()
[ADDED] a new checkbox method: GetBoxWidth()
[ADDED] a new checkbox method: GetBoxHeight()
[ADDED] a new image method: GetImage()
[ADDED] a new image method: GetColor()
[ADDED] a new progressbar method: GetCompleted()
[ADDED] a new tabs method: GetTabNumber()
[ADDED] a new text method: GetLines()
[ADDED] a new text input method: SetLimit(limit)
[ADDED] a new text input method: SetUsable(usable)
[ADDED] a new text input method: SetUnusable(unusable)
[ADDED] a new text input method: Clear()
[ADDED] a new text input method: GetText()
[ADDED] support for line breaks in the text object (please refer to the wiki on how to format your text with line breaks)
[ADDED] more information to the debug overlay
[FIXED] tooltips and multichoice lists not functioning properly when a frame was modaled
[FIXED] the text object not moving it's base parent to the top when clicked if it's base parent was a frame
[FIXED] the list object not scrolling via the mouse wheel due to certain collision detection issues
[FIXED] tooltips flickering when in a hover state
[FIXED] slider calculation errors
[FIXED] skin.DrawRepeatingImage creating a new image every frame
[FIXED] checkbox text not scrolling properly when in a list
[FIXED] the collapsible category's object not scrolling properly when in a list
[FIXED] skins not assuming the drawing functions of the default skins if drawing functions in the active skin were missing
[FIXED] some objects not being removed
[FIXED] sliders not scrolling properly when in a list
[CHANGED] various code for a small cleanup
[CHANGED] tooltips from being children of the base object to internals of the base object
[CHANGED] tooltips from never being removed to being removed when their assigned object is removed
[CHANGED] tooltips are now not able to be assigned to the base object (this would cause an error due to the way the tooltip currently functions)
[CHANGED] the text object now positions it's text when SetText is called instead of positioning it's text every frame
[CHANGED] slider:SetMax(max), slider:SetMin(min) and slider:SetMinMax(min, max) now adjust the slider's value if the slider's value is out of the range specified
[CHANGED] loveframes.Create(data, parent) now activates an error screen if the object specified is invalid
================================================
Version 0.9.2.5 - Alpha (June 1 - 2012)
================================================
[FIXED] the text object not drawing numbers in certain situations
[FIXED] a typo in the changelog
================================================
Version 0.9.2.4 - Alpha (May 29 - 2012)
================================================
[FIXED] the SetSkin(skin) method causing a stack overflow
================================================
Version 0.9.2.3 - Alpha (May 27 - 2012)
================================================
[FIXED] imagebutton.OnClick not working
[FIXED] text being added into the text input object at incorrect positions when the value of textinput.blinknum was 0
[FIXED] a bug that would cause an error when running SetVisible on a frame object when the value of frame.showclose was true
================================================
Version 0.9.2.2 - Alpha (May 23 - 2012)
================================================
[FIXED] vertical slider value direction (top is now max value and bottom is 0)
[FIXED] text flashing in the text input object when moving the text blinker to the right
[FIXED] text blinker in the text input object not appearing in certain situations
================================================
Version 0.9.2 - Alpha (May 22 - 2012)
================================================
[ADDED] a new slider method: SetButtonSize(width, height)
[ADDED] a new slider method: GetButtonSize()
[ADDED] a new slider method: SetSlideType(slidetype)
[ADDED] a new slider button method: MoveToY(y)
[REMOVED] slider method: SetButtonYCenter(y)
[REMOVED] slider method: GetButtonYCenter()
[FIXED] the column list row object not setting it's text's font to it's font
[FIXED] a small gradient error in the default skins
[FIXED] an error that caused tab buttons to be over-scrolled with the middle mouse button
[FIXED] the scroll area object not moving it's base parent to the top when clicked (only in situations where it's base parent was a frame)
[CHANGED] sliders no longer use ycenter for button positioning
[CHANGED] slider functionality, sliders can now be horizontal or vertical (use slider:SetSlideType("horizontal" or "vertical"))
[CHANGED] lots of code for optimization and general cleanliness
[CHANGED] a few minor things in the default skins
[CHANGED] scrollbar hover behavior when being moved via it's scroll area being clicked (will no longer auto hover when it reaches the mouse position)
================================================
Version 0.9.1.6 - Alpha (May 17 - 2012)
================================================
[ADDED] a new column list method: Clear()
[ADDED] a new column list method: SetAutoScroll(bool)
[ADDED] "autoscroll" property for the column list object
[ADDED] a new column list area method: Clear()
[ADDED] a new skin function: DrawOverTextInput()
[FIXED] not being able to move the column list object's scrollbar by clicking on it's scroll area
[FIXED] column list rows color indexes becoming disordered when the list was sorted via a column list header
[CHANGED] a few minor things in the default skins
================================================
Version 0.9.1.5 - Alpha (May 16 - 2012)
================================================
[FIXED] a bug that caused scrollbars to always autoscroll
================================================
Version 0.9.1.4 - Alpha (May 16 - 2012)
================================================
[FIXED] list:SetAutoScroll() not working
================================================
Version 0.9.1.3 - Alpha (May 14 - 2012)
================================================
[ADDED] modal system for frames
[ADDED] a new frame method: SetModal(bool)
[ADDED] a new frame method: GetModal()
[ADDED] a new frame method: SetVisible(bool) - this override is part of a frame bug fix
[ADDED] "showclose" property for the frame object
[ADDED] a new internal object: modal background
[ADDED] a new base method: IsActive()
[ADDED] a new base method: CenterX()
[ADDED] a new base method: CenterY()
[ADDED] a new skin function: DrawOverColumList()
[FIXED] a bug that made the frame's close button become visible when the frame was made visible and show close button was set to false
================================================
Version 0.9.1.2 - Alpha (May 12 - 2012)
================================================
[ADDED] a system for preventing objects from being hovered over when another object is being pressed or is "down"
[ADDED] "down" property for the checkbox object
[ADDED] "down" property for the collapsible category object
[ADDED] a new method for the tabs object: SetToolTipFont(font)
[FIXED] list:GetScrollBar() crashing when the list had no scroll bar
[FIXED] not being able to move the text input blinker to the front or end of the it's text by clicking on it's whitespace
[FIXED] the multichoice row object being "down" when mouse buttons other than the left mouse button were pressed
[CHANGED] collapsible category opening and closing system (will now only open or close when "down")
================================================
Version 0.9.1 - Alpha (May 8 - 2012)
================================================
[ADDED] a new object: image button
[ADDED] a new skin: Orange
[ADDED] a new column list row method: SetTextPos(x, y)
[ADDED] a new column list row method: SetFont(font)
[ADDED] a new column list row method: GetFont()
[ADDED] a new column list row method: GetColorIndex()
[ADDED] a new column list row method: SetTextColor(color)
[ADDED] a new debug function: SkinSelector()
[ADDED] license.txt
[ADDED] changelog.txt
[CHANGED] the name of the default skin to Blue
[CHANGED] the drawing system of the image object, the image object will now draw it's image from it's skin function instead of it's internal drawing function
[CHANGED] argument type for adding an image to a tab in tabs:AddTab(), the image argument can now be either an image object or a string containg the path to an image
[CHANGED] the look of the debug overlay
[CHANGED] some of the code within the default skins to improve performance (as suggested by kikito)
[REMOVED] license.html
[REMOVED] loveframes.graphics and graphics.lua
================================================
Version 0.9 - Alpha (May 5 - 2012)
================================================
Initial commit

308
loveframes/init.lua Normal file
View File

@ -0,0 +1,308 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
local path = ...
local loveframes = {}
-- special require for loveframes specific modules
loveframes.require = function(name)
local ret = require(name)
if type(ret) == 'function' then return ret(loveframes) end
return ret
end
-- loveframes specific modules
loveframes.require(path .. ".libraries.utils")
loveframes.require(path .. ".libraries.templates")
loveframes.require(path .. ".libraries.objects")
loveframes.require(path .. ".libraries.skins")
-- generic libraries
loveframes.class = require(path .. ".third-party.middleclass")
loveframes.utf8 = require(path .. ".third-party.utf8")
-- library info
loveframes.author = "Kenny Shields"
loveframes.version = "11.3"
loveframes.stage = "Alpha"
-- library configurations
loveframes.config = {}
loveframes.config["DIRECTORY"] = nil
loveframes.config["DEFAULTSKIN"] = "Default"
loveframes.config["ACTIVESKIN"] = "Default"
loveframes.config["INDEXSKINIMAGES"] = true
loveframes.config["DEBUG"] = false
loveframes.config["ENABLE_SYSTEM_CURSORS"] = true
-- misc library vars
loveframes.state = "none"
loveframes.drawcount = 0
loveframes.collisioncount = 0
loveframes.objectcount = 0
loveframes.hoverobject = false
loveframes.modalobject = false
loveframes.inputobject = false
loveframes.downobject = false
loveframes.resizeobject = false
loveframes.dragobject = false
loveframes.hover = false
loveframes.input_cursor_set = false
loveframes.prevcursor = nil
loveframes.basicfont = love.graphics.newFont(12)
loveframes.basicfontsmall = love.graphics.newFont(10)
loveframes.collisions = {}
-- install directory of the library
local dir = loveframes.config["DIRECTORY"] or path
-- replace all "." with "/" in the directory setting
dir = loveframes.utf8.gsub(loveframes.utf8.gsub(dir, "\\", "/"), "(%a)%.(%a)", "%1/%2")
loveframes.config["DIRECTORY"] = dir
-- enable key repeat
love.keyboard.setKeyRepeat(true)
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates all library objects
--]]---------------------------------------------------------
function loveframes.update(dt)
local base = loveframes.base
local input_cursor_set = loveframes.input_cursor_set
loveframes.collisioncount = 0
loveframes.objectcount = 0
loveframes.hover = false
loveframes.hoverobject = false
local downobject = loveframes.downobject
if #loveframes.collisions > 0 then
local top = loveframes.collisions[#loveframes.collisions]
if not downobject then
loveframes.hoverobject = top
else
if downobject == top then
loveframes.hoverobject = top
end
end
end
if loveframes.config["ENABLE_SYSTEM_CURSORS"] then
local hoverobject = loveframes.hoverobject
local arrow = love.mouse.getSystemCursor("arrow")
local curcursor = love.mouse.getCursor()
if hoverobject then
local ibeam = love.mouse.getSystemCursor("ibeam")
local mx, my = love.mouse.getPosition()
if hoverobject.type == "textinput" and not loveframes.resizeobject then
if curcursor ~= ibeam then
love.mouse.setCursor(ibeam)
end
elseif hoverobject.type == "frame" then
if not hoverobject.dragging and hoverobject.canresize then
if loveframes.BoundingBox(hoverobject.x, mx, hoverobject.y, my, 5, 1, 5, 1) then
local sizenwse = love.mouse.getSystemCursor("sizenwse")
if curcursor ~= sizenwse then
love.mouse.setCursor(sizenwse)
end
elseif loveframes.BoundingBox(hoverobject.x + hoverobject.width - 5, mx, hoverobject.y + hoverobject.height - 5, my, 5, 1, 5, 1) then
local sizenwse = love.mouse.getSystemCursor("sizenwse")
if curcursor ~= sizenwse then
love.mouse.setCursor(sizenwse)
end
elseif loveframes.BoundingBox(hoverobject.x + hoverobject.width - 5, mx, hoverobject.y, my, 5, 1, 5, 1) then
local sizenesw = love.mouse.getSystemCursor("sizenesw")
if curcursor ~= sizenesw then
love.mouse.setCursor(sizenesw)
end
elseif loveframes.BoundingBox(hoverobject.x, mx, hoverobject.y + hoverobject.height - 5, my, 5, 1, 5, 1) then
local sizenesw = love.mouse.getSystemCursor("sizenesw")
if curcursor ~= sizenesw then
love.mouse.setCursor(sizenesw)
end
elseif loveframes.BoundingBox(hoverobject.x + 5, mx, hoverobject.y, my, hoverobject.width - 10, 1, 2, 1) then
local sizens = love.mouse.getSystemCursor("sizens")
if curcursor ~= sizens then
love.mouse.setCursor(sizens)
end
elseif loveframes.BoundingBox(hoverobject.x + 5, mx, hoverobject.y + hoverobject.height - 2, my, hoverobject.width - 10, 1, 2, 1) then
local sizens = love.mouse.getSystemCursor("sizens")
if curcursor ~= sizens then
love.mouse.setCursor(sizens)
end
elseif loveframes.BoundingBox(hoverobject.x, mx, hoverobject.y + 5, my, 2, 1, hoverobject.height - 10, 1) then
local sizewe = love.mouse.getSystemCursor("sizewe")
if curcursor ~= sizewe then
love.mouse.setCursor(sizewe)
end
elseif loveframes.BoundingBox(hoverobject.x + hoverobject.width - 2, mx, hoverobject.y + 5, my, 2, 1, hoverobject.height - 10, 1) then
local sizewe = love.mouse.getSystemCursor("sizewe")
if curcursor ~= sizewe then
love.mouse.setCursor(sizewe)
end
else
if not loveframes.resizeobject then
local arrow = love.mouse.getSystemCursor("arrow")
if curcursor ~= arrow then
love.mouse.setCursor(arrow)
end
end
end
end
elseif hoverobject.type == "text" and hoverobject.linkcol and not loveframes.resizeobject then
local hand = love.mouse.getSystemCursor("hand")
if curcursor ~= hand then
love.mouse.setCursor(hand)
end
end
if curcursor ~= arrow then
if hoverobject.type ~= "textinput" and hoverobject.type ~= "frame" and not hoverobject.linkcol and not loveframes.resizeobject then
love.mouse.setCursor(arrow)
elseif hoverobject.type ~= "textinput" and curcursor == ibeam then
love.mouse.setCursor(arrow)
end
end
else
if curcursor ~= arrow and not loveframes.resizeobject then
love.mouse.setCursor(arrow)
end
end
end
loveframes.collisions = {}
base:update(dt)
end
--[[---------------------------------------------------------
- func: draw()
- desc: draws all library objects
--]]---------------------------------------------------------
function loveframes.draw()
local base = loveframes.base
local r, g, b, a = love.graphics.getColor()
local font = love.graphics.getFont()
base:draw()
loveframes.drawcount = 0
if loveframes.config["DEBUG"] then
loveframes.DebugDraw()
end
love.graphics.setColor(r, g, b, a)
if font then
love.graphics.setFont(font)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function loveframes.mousepressed(x, y, button)
local base = loveframes.base
base:mousepressed(x, y, button)
-- close open menus
local bchildren = base.children
local hoverobject = loveframes.hoverobject
for k, v in ipairs(bchildren) do
local otype = v.type
local visible = v.visible
if hoverobject then
local htype = hoverobject.type
if otype == "menu" and visible and htype ~= "menu" and htype ~= "menuoption" then
v:SetVisible(false)
end
else
if otype == "menu" and visible then
v:SetVisible(false)
end
end
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function loveframes.mousereleased(x, y, button)
local base = loveframes.base
base:mousereleased(x, y, button)
-- reset the hover object
if button == 1 then
loveframes.downobject = false
loveframes.selectedobject = false
end
end
--[[---------------------------------------------------------
- func: wheelmoved(x, y)
- desc: called when the player moves a mouse wheel
--]]---------------------------------------------------------
function loveframes.wheelmoved(x, y)
local base = loveframes.base
base:wheelmoved(x, y)
end
--[[---------------------------------------------------------
- func: keypressed(key, isrepeat)
- desc: called when the player presses a key
--]]---------------------------------------------------------
function loveframes.keypressed(key, isrepeat)
local base = loveframes.base
base:keypressed(key, isrepeat)
end
--[[---------------------------------------------------------
- func: keyreleased(key)
- desc: called when the player releases a key
--]]---------------------------------------------------------
function loveframes.keyreleased(key)
local base = loveframes.base
base:keyreleased(key)
end
--[[---------------------------------------------------------
- func: textinput(text)
- desc: called when the user inputs text
--]]---------------------------------------------------------
function loveframes.textinput(text)
local base = loveframes.base
base:textinput(text)
end
loveframes.LoadObjects(dir .. "/objects")
loveframes.LoadTemplates(dir .. "/templates")
loveframes.LoadSkins(dir .. "/skins")
-- create the base gui object
local base = loveframes.objects["base"]
loveframes.base = base:new()
return loveframes

View File

@ -0,0 +1,150 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
loveframes.objects = {}
--[[---------------------------------------------------------
- func: Create(type, parent)
- desc: creates a new object or multiple new objects
(based on the method used) and returns said
object or objects for further manipulation
--]]---------------------------------------------------------
function loveframes.Create(data, parent)
if type(data) == "string" then
local objects = loveframes.objects
local object = objects[data]
local objectcount = loveframes.objectcount
if not object then
loveframes.Error("Error creating object: Invalid object '" ..data.. "'.")
end
-- create the object
local newobject = object:new()
-- apply template properties to the object
loveframes.ApplyTemplatesToObject(newobject)
-- if the object is a tooltip, return it and go no further
if data == "tooltip" then
return newobject
end
-- remove the object if it is an internal
if newobject.internal then
newobject:Remove()
return
end
-- parent the new object by default to the base gui object
newobject.parent = loveframes.base
table.insert(loveframes.base.children, newobject)
-- if the parent argument is not nil, make that argument the object's new parent
if parent then
newobject:SetParent(parent)
end
loveframes.objectcount = objectcount + 1
-- return the object for further manipulation
return newobject
elseif type(data) == "table" then
-- table for creation of multiple objects
local objects = {}
-- this function reads a table that contains a layout of object properties and then
-- creates objects based on those properties
local function CreateObjects(t, o, c)
local child = c or false
local validobjects = loveframes.objects
for k, v in pairs(t) do
-- current default object
local object = validobjects[v.type]:new()
-- insert the object into the table of objects being created
table.insert(objects, object)
-- parent the new object by default to the base gui object
object.parent = loveframes.base
table.insert(loveframes.base.children, object)
if o then
object:SetParent(o)
end
-- loop through the current layout table and assign the properties found
-- to the current object
for i, j in pairs(v) do
if i ~= "children" and i ~= "func" then
if child then
if i == "x" then
object["staticx"] = j
elseif i == "y" then
object["staticy"] = j
else
object[i] = j
end
else
object[i] = j
end
elseif i == "children" then
CreateObjects(j, object, true)
end
end
if v.func then
v.func(object)
end
end
end
-- create the objects
CreateObjects(data)
return objects
end
end
--[[---------------------------------------------------------
- func: NewObject(id, name, inherit_from_base)
- desc: creates a new object
--]]---------------------------------------------------------
function loveframes.NewObject(id, name, inherit_from_base)
local objects = loveframes.objects
local object = false
if inherit_from_base then
local base = objects["base"]
object = loveframes.class(name, base)
objects[id] = object
else
object = loveframes.class(name)
objects[id] = object
end
return object
end
function loveframes.LoadObjects(dir)
local objectlist = loveframes.GetDirectoryContents(dir)
-- loop through a list of all gui objects and require them
for k, v in ipairs(objectlist) do
if v.extension == "lua" then
loveframes.require(v.requirepath)
end
end
end
--return objects
---------- module end ----------
end

View File

@ -0,0 +1,117 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- skins library
loveframes.skins = {}
--[[---------------------------------------------------------
- func: RegisterSkin(skin)
- desc: registers a skin
--]]---------------------------------------------------------
function loveframes.RegisterSkin(skin)
local skins = loveframes.skins
local name = skin.name
local author = skin.author
local version = skin.version
local basename = skin.base
local newskin = false
if name == "" or not name then
loveframes.Error("Skin registration error: Invalid or missing name data.")
end
if author == "" or not author then
loveframes.Error("Skin registration error: Invalid or missing author data.")
end
if version == "" or not version then
loveframes.Error("Skin registration error: Invalid or missing version data.")
end
local namecheck = skins[name]
if namecheck then
loveframes.Error("Skin registration error: A skin with the name '" ..name.. "' already exists.")
end
local dir = skin.directory or loveframes.config["DIRECTORY"] .. "/skins/" ..name
local dircheck = love.filesystem.getInfo(dir) ~= nil and love.filesystem.getInfo(dir)["type"] == "directory"
if not dircheck then
loveframes.Error("Skin registration error: Could not find a directory for skin '" ..name.. "'.")
end
local imagedir = skin.imagedir or dir .. "/images"
local imagedircheck = love.filesystem.getInfo(imagedir) ~= nil and love.filesystem.getInfo(imagedir)["type"] == "directory"
if not imagedircheck then
loveframes.Error("Skin registration error: Could not find an image directory for skin '" ..name.. "'.")
end
if basename then
--local basename = base
local base = skins[basename]
if not base then
loveframes.Error("Could not find base skin '" ..basename.. "' for skin '" ..name.. "'.")
end
newskin = loveframes.DeepCopy(base)
newskin.name = name
newskin.author = author
newskin.version = version
newskin.imagedir = imagedir
local skincontrols = skin.controls
local basecontrols = base.controls
if skincontrols and basecontrols then
for k, v in pairs(skincontrols) do
newskin.controls[k] = v
end
for k, v in pairs(skin) do
if type(v) == "function" then
newskin[k] = v
end
end
end
end
if not newskin then
newskin = skin
end
newskin.dir = dir
local images = {}
local indeximages = loveframes.config["INDEXSKINIMAGES"]
if indeximages then
local imagelist = loveframes.GetDirectoryContents(imagedir)
local filename, extension, image
for k, v in ipairs(imagelist) do
extension = v.extension
filename = v.name .. "." .. extension
if extension == "png" then
image = love.graphics.newImage(v.fullpath)
image:setFilter("nearest", "nearest")
images[filename] = image
end
end
end
newskin.images = images
skins[name] = newskin
end
function loveframes.LoadSkins(dir)
local skinlist = loveframes.GetDirectoryContents(dir)
-- loop through a list of all gui skins and require them
local skin
for k, v in ipairs(skinlist) do
if v.extension == "lua" then
skin = loveframes.require(v.requirepath)
--loveframes.RegisterSkin(skin)
end
end
end
--return skins
---------- module end ----------
end

View File

@ -0,0 +1,85 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- templates library
loveframes.templates = {}
--[[---------------------------------------------------------
- func: RegisterTemplate(template)
- desc: registers a template
--]]---------------------------------------------------------
function loveframes.RegisterTemplate(template)
-- display an error message if template is not a table
if type(template) ~= "table" then
loveframes.Error("Could not register template: Template argument must be a table.")
end
local name = template.name
local base = loveframes.objects["base"]
-- display an error message if a template name was not given
if not name then
loveframes.Error("Could not register template: No template name given.")
end
if name == "Base" then
base:include(template.properties["*"])
end
-- insert the template into the available templates table
loveframes.templates[name] = template
end
--[[---------------------------------------------------------
- func: ApplyTemplatesToObject(object)
- desc: applies the properties of registered templates
to an object
--]]---------------------------------------------------------
function loveframes.ApplyTemplatesToObject(object)
local templates = loveframes.templates
local type = object.type
-- loop through all available templates
for k, v in pairs(templates) do
-- make sure the base template doesn't get applied more than once
if k ~= "Base" then
local properties = v.properties
local hasall = loveframes.TableHasKey(properties, "*")
local hasobject = false
if not hasall then
hasobject = loveframes.TableHasKey(properties, type)
end
if hasall then
for k, v in pairs(properties["*"]) do
object[k] = v
end
elseif hasobject then
-- apply the template properties to the object
for k, v in pairs(properties[type]) do
object[k] = v
end
end
end
end
end
function loveframes.LoadTemplates(dir)
local templatelist = loveframes.GetDirectoryContents(dir)
-- loop through a list of all gui templates and require them
for k, v in ipairs(templatelist) do
if v.extension == "lua" then
local template = require(v.requirepath)
loveframes.RegisterTemplate(template)
end
end
end
--return templates
---------- module end ----------
end

View File

@ -0,0 +1,452 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- util library
--local util = {}
--[[---------------------------------------------------------
- func: SetState(name)
- desc: sets the current state
--]]---------------------------------------------------------
function loveframes.SetState(name)
loveframes.state = name
loveframes.base.state = name
end
--[[---------------------------------------------------------
- func: GetState()
- desc: gets the current state
--]]---------------------------------------------------------
function loveframes.GetState()
return loveframes.state
end
--[[---------------------------------------------------------
- func: SetActiveSkin(name)
- desc: sets the active skin
--]]---------------------------------------------------------
function loveframes.SetActiveSkin(name)
local skin = name and loveframes.skins[name]
if not skin then print("SetActiveSkin: no such skin") return end
loveframes.config["ACTIVESKIN"] = name
local object = loveframes.base
object:SetSkin(name)
end
--[[---------------------------------------------------------
- func: GetActiveSkin()
- desc: gets the active skin
--]]---------------------------------------------------------
function loveframes.GetActiveSkin()
local index = loveframes.config["ACTIVESKIN"]
return loveframes.skins[index]
end
--[[---------------------------------------------------------
- func: BoundingBox(x1, x2, y1, y2, w1, w2, h1, h2)
- desc: checks for a collision between two boxes
- note: I take no credit for this function
--]]---------------------------------------------------------
function loveframes.BoundingBox(x1, x2, y1, y2, w1, w2, h1, h2)
if x1 > x2 + w2 - 1 or y1 > y2 + h2 - 1 or x2 > x1 + w1 - 1 or y2 > y1 + h1 - 1 then
return false
else
return true
end
end
--[[---------------------------------------------------------
- func: GetCollisions(object, table)
- desc: gets all objects colliding with the mouse
--]]---------------------------------------------------------
function loveframes.GetCollisions(object, t)
local x, y = love.mouse.getPosition()
local curstate = loveframes.state
local object = object or loveframes.base
local visible = object.visible
local children = object.children
local internals = object.internals
local objectstate = object.state
local t = t or {}
if objectstate == curstate and visible then
local objectx = object.x
local objecty = object.y
local objectwidth = object.width
local objectheight = object.height
local col = loveframes.BoundingBox(x, objectx, y, objecty, 1, objectwidth, 1, objectheight)
local collide = object.collide
if col and collide then
local clickbounds = object.clickbounds
if clickbounds then
local cx = clickbounds.x
local cy = clickbounds.y
local cwidth = clickbounds.width
local cheight = clickbounds.height
local clickcol = loveframes.BoundingBox(x, cx, y, cy, 1, cwidth, 1, cheight)
if clickcol then
table.insert(t, object)
end
else
table.insert(t, object)
end
end
if children then
for k, v in ipairs(children) do
loveframes.GetCollisions(v, t)
end
end
if internals then
for k, v in ipairs(internals) do
local type = v.type
if type ~= "tooltip" then
loveframes.GetCollisions(v, t)
end
end
end
end
return t
end
--[[---------------------------------------------------------
- func: GetAllObjects(object, table)
- desc: gets all active objects
--]]---------------------------------------------------------
function loveframes.GetAllObjects(object, t)
local object = object or loveframes.base
local internals = object.internals
local children = object.children
local t = t or {}
table.insert(t, object)
if internals then
for k, v in ipairs(internals) do
loveframes.GetAllObjects(v, t)
end
end
if children then
for k, v in ipairs(children) do
loveframes.GetAllObjects(v, t)
end
end
return t
end
--[[---------------------------------------------------------
- func: GetDirectoryContents(directory, table)
- desc: gets the contents of a directory and all of
its subdirectories
--]]---------------------------------------------------------
function loveframes.GetDirectoryContents(dir, t)
local dir = dir
local t = t or {}
local dirs = {}
local files = love.filesystem.getDirectoryItems(dir)
for k, v in ipairs(files) do
local isdir = love.filesystem.getInfo(dir.. "/" ..v) ~= nil and love.filesystem.getInfo(dir.. "/" ..v)["type"] == "directory" --love.filesystem.isDirectory(dir.. "/" ..v)
if isdir == true then
table.insert(dirs, dir.. "/" ..v)
else
local parts = loveframes.SplitString(v, "([.])")
local extension = #parts > 1 and parts[#parts]
if #parts > 1 then
parts[#parts] = nil
end
local name = table.concat(parts, ".")
table.insert(t, {
path = dir,
fullpath = dir.. "/" ..v,
requirepath = loveframes.utf8.gsub(dir, "/", ".") .. "." ..name,
name = name,
extension = extension
})
end
end
for k, v in ipairs(dirs) do
t = loveframes.GetDirectoryContents(v, t)
end
return t
end
--[[---------------------------------------------------------
- func: Round(num, idp)
- desc: rounds a number based on the decimal limit
- note: I take no credit for this function
--]]---------------------------------------------------------
function loveframes.Round(num, idp)
local mult = 10^(idp or 0)
if num >= 0 then
return math.floor(num * mult + 0.5) / mult
else
return math.ceil(num * mult - 0.5) / mult
end
end
--[[---------------------------------------------------------
- func: SplitString(string, pattern)
- desc: splits a string into a table based on a given pattern
- note: I take no credit for this function
--]]---------------------------------------------------------
function loveframes.SplitString(str, pat)
local t = {} -- NOTE: use {n = 0} in Lua-5.0
if pat == " " then
local fpat = "(.-)" .. pat
local last_end = 1
local s, e, cap = loveframes.utf8.find(str, fpat, 1)
while s do
if s ~= #str then
cap = cap .. " "
end
if s ~= 1 or cap ~= "" then
table.insert(t,cap)
end
last_end = e+1
s, e, cap = loveframes.utf8.find(str, fpat, last_end)
end
if last_end <= #str then
cap = loveframes.utf8.sub(str, last_end)
table.insert(t, cap)
end
else
local fpat = "(.-)" .. pat
local last_end = 1
local s, e, cap = loveframes.utf8.find(str, fpat, 1)
while s do
if s ~= 1 or cap ~= "" then
table.insert(t,cap)
end
last_end = e+1
s, e, cap = loveframes.utf8.find(str, fpat, last_end)
end
if last_end <= #str then
cap = loveframes.utf8.sub(str, last_end)
table.insert(t, cap)
end
end
return t
end
--[[---------------------------------------------------------
- func: RemoveAll()
- desc: removes all gui elements
--]]---------------------------------------------------------
function loveframes.RemoveAll()
loveframes.base.children = {}
loveframes.base.internals = {}
loveframes.hoverobject = false
loveframes.downobject = false
loveframes.modalobject = false
loveframes.inputobject = false
loveframes.hover = false
end
--[[---------------------------------------------------------
- func: TableHasValue(table, value)
- desc: checks to see if a table has a specific value
--]]---------------------------------------------------------
function loveframes.TableHasValue(table, value)
for k, v in pairs(table) do
if v == value then
return true
end
end
return false
end
--[[---------------------------------------------------------
- func: TableHasKey(table, key)
- desc: checks to see if a table has a specific key
--]]---------------------------------------------------------
function loveframes.TableHasKey(table, key)
return table[key] ~= nil
end
--[[---------------------------------------------------------
- func: Error(message)
- desc: displays a formatted error message
--]]---------------------------------------------------------
function loveframes.Error(message)
error("[Love Frames] " ..message)
end
--[[---------------------------------------------------------
- func: GetCollisionCount()
- desc: gets the total number of objects colliding with
the mouse
--]]---------------------------------------------------------
function loveframes.GetCollisionCount()
return loveframes.collisioncount
end
--[[---------------------------------------------------------
- func: GetHover()
- desc: returns loveframes.hover, can be used to check
if the mouse is colliding with a visible
Love Frames object
--]]---------------------------------------------------------
function loveframes.GetHover()
return loveframes.hover
end
--[[---------------------------------------------------------
- func: RectangleCollisionCheck(rect1, rect2)
- desc: checks for a collision between two rectangles
based on two tables containing rectangle sizes
and positions
--]]---------------------------------------------------------
function loveframes.RectangleCollisionCheck(rect1, rect2)
return loveframes.BoundingBox(rect1.x, rect2.x, rect1.y, rect2.y, rect1.width, rect2.width, rect1.height, rect2.height)
end
--[[---------------------------------------------------------
- func: DeepCopy(orig)
- desc: copies a table
- note: I take not credit for this function
--]]---------------------------------------------------------
function loveframes.DeepCopy(orig)
local orig_type = type(orig)
local copy
if orig_type == 'table' then
copy = {}
for orig_key, orig_value in next, orig, nil do
copy[loveframes.DeepCopy(orig_key)] = loveframes.DeepCopy(orig_value)
end
setmetatable(copy, loveframes.DeepCopy(getmetatable(orig)))
else -- number, string, boolean, etc
copy = orig
end
return copy
end
--[[---------------------------------------------------------
- func: GetHoverObject()
- desc: returns loveframes.hoverobject
--]]---------------------------------------------------------
function loveframes.GetHoverObject()
return loveframes.hoverobject
end
--[[---------------------------------------------------------
- func: IsCtrlDown()
- desc: checks for ctrl, for use with multiselect, copy,
paste, and such. On OS X it actually looks for cmd.
--]]---------------------------------------------------------
function loveframes.IsCtrlDown()
if love._os == "OS X" then
return love.keyboard.isDown("lgui") or love.keyboard.isDown("rgui")
end
return love.keyboard.isDown("lctrl") or love.keyboard.isDown("rctrl")
end
function loveframes.Color(s, a)
local r, g, b = string.match(s, '#?(%x%x)(%x%x)(%x%x)')
if r == nil then return end
return tonumber(r, 16) / 0xFF, tonumber(g, 16) / 0xFF, tonumber(b, 16) / 0xFF, a or 1
end
--[[---------------------------------------------------------
- func: draw()
- desc: draws debug information
--]]---------------------------------------------------------
function loveframes.DebugDraw()
local infox = 5
local infoy = 40
local topcol = {type = "None", children = {}, x = 0, y = 0, width = 0, height = 0}
local hoverobject = loveframes.hoverobject
--local objects = loveframes.GetAllObjects()
local version = loveframes.version
local stage = loveframes.stage
local basedir = loveframes.config["DIRECTORY"]
local loveversion = love._version
local fps = love.timer.getFPS()
local deltatime = love.timer.getDelta()
local font = loveframes.basicfontsmall
if hoverobject then
topcol = hoverobject
end
-- show frame docking zones
if topcol.type == "frame" then
for k, v in pairs(topcol.dockzones) do
love.graphics.setLineWidth(1)
love.graphics.setColor(255/255, 0, 0, 100/255)
love.graphics.rectangle("fill", v.x, v.y, v.width, v.height)
love.graphics.setColor(255/255, 0, 0, 255/255)
love.graphics.rectangle("line", v.x, v.y, v.width, v.height)
end
end
-- outline the object that the mouse is hovering over
love.graphics.setColor(255/255, 204/255, 51/255, 255/255)
love.graphics.setLineWidth(2)
love.graphics.rectangle("line", topcol.x - 1, topcol.y - 1, topcol.width + 2, topcol.height + 2)
-- draw main debug box
love.graphics.setFont(font)
love.graphics.setColor(0, 0, 0, 200/255)
love.graphics.rectangle("fill", infox, infoy, 200, 70)
love.graphics.setColor(255/255, 0, 0, 255/255)
love.graphics.print("Love Frames - Debug (" ..version.. " - " ..stage.. ")", infox + 5, infoy + 5)
love.graphics.setColor(255/255, 255/255, 255/255, 255/255)
love.graphics.print("LOVE Version: " ..loveversion, infox + 10, infoy + 20)
love.graphics.print("FPS: " ..fps, infox + 10, infoy + 30)
love.graphics.print("Delta Time: " ..deltatime, infox + 10, infoy + 40)
love.graphics.print("Total Objects: " ..loveframes.objectcount, infox + 10, infoy + 50)
-- draw object information if needed
if topcol.type ~= "base" then
love.graphics.setColor(0, 0, 0, 200/255)
love.graphics.rectangle("fill", infox, infoy + 75, 200, 100)
love.graphics.setColor(255/255, 0, 0, 255/255)
love.graphics.print("Object Information", infox + 5, infoy + 80)
love.graphics.setColor(255/255, 255/255, 255/255, 255/255)
love.graphics.print("Type: " ..topcol.type, infox + 10, infoy + 95)
if topcol.children then
love.graphics.print("# of children: " .. #topcol.children, infox + 10, infoy + 105)
else
love.graphics.print("# of children: 0", infox + 10, infoy + 105)
end
if topcol.internals then
love.graphics.print("# of internals: " .. #topcol.internals, infox + 10, infoy + 115)
else
love.graphics.print("# of internals: 0", infox + 10, infoy + 115)
end
love.graphics.print("X: " ..topcol.x, infox + 10, infoy + 125)
love.graphics.print("Y: " ..topcol.y, infox + 10, infoy + 135)
love.graphics.print("Width: " ..topcol.width, infox + 10, infoy + 145)
love.graphics.print("Height: " ..topcol.height, infox + 10, infoy + 155)
end
end
--return util
---------- module end ----------
end

20
loveframes/license.txt Normal file
View File

@ -0,0 +1,20 @@
Copyright (c) 2014 Kenny Shields
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from
the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software in a
product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.

1295
loveframes/objects/base.lua Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,298 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- button object
local newobject = loveframes.NewObject("button", "loveframes_object_button", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "button"
self.text = "Button"
self.width = 80
self.height = 25
self.internal = false
self.down = false
self.clickable = true
self.enabled = true
self.toggleable = false
self.toggle = false
self.OnClick = nil
self.groupIndex = 0
self.checked = false
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
self:CheckHover()
local hover = self.hover
local down = self.down
local downobject = loveframes.downobject
local parent = self.parent
local base = loveframes.base
local update = self.Update
if not hover then
self.down = false
if downobject == self then
self.hover = true
end
else
if downobject == self then
self.down = true
end
end
-- move to parent if there is a parent
if parent ~= base then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local hover = self.hover
if hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
self.down = true
loveframes.downobject = self
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local hover = self.hover
local down = self.down
local clickable = self.clickable
local enabled = self.enabled
local onclick = self.OnClick
if hover and down and clickable and button == 1 then
if enabled then
if self.groupIndex ~= 0 then
local baseparent = self.parent
if baseparent then
for k, v in ipairs(baseparent.children) do
if v.groupIndex then
if v.groupIndex == self.groupIndex then
v.checked = false
end
end
end
end
self.checked = true
end
if onclick then
onclick(self, x, y)
end
if self.toggleable then
local ontoggle = self.OnToggle
self.toggle = not self.toggle
if ontoggle then
ontoggle(self, self.toggle)
end
end
end
end
self.down = false
end
--[[---------------------------------------------------------
- func: SetText(text)
- desc: sets the object's text
--]]---------------------------------------------------------
function newobject:SetText(text)
self.text = text
return self
end
--[[---------------------------------------------------------
- func: GetText()
- desc: gets the object's text
--]]---------------------------------------------------------
function newobject:GetText()
return self.text
end
--[[---------------------------------------------------------
- func: SetImage(image)
- desc: adds an image to the object
--]]---------------------------------------------------------
function newobject:SetImage(image)
if type(image) == "string" then
self.image = love.graphics.newImage(image)
self.image:setFilter("nearest", "nearest")
else
self.image = image
end
end
--[[---------------------------------------------------------
- func: GetImage()
- desc: gets the object's image
--]]---------------------------------------------------------
function newobject:GetImage()
return self.image
end
--[[---------------------------------------------------------
- func: SetClickable(bool)
- desc: sets whether the object can be clicked or not
--]]---------------------------------------------------------
function newobject:SetClickable(bool)
self.clickable = bool
return self
end
--[[---------------------------------------------------------
- func: GetClickable(bool)
- desc: gets whether the object can be clicked or not
--]]---------------------------------------------------------
function newobject:GetClickable()
return self.clickable
end
--[[---------------------------------------------------------
- func: SetClickable(bool)
- desc: sets whether or not the object is enabled
--]]---------------------------------------------------------
function newobject:SetEnabled(bool)
self.enabled = bool
return self
end
--[[---------------------------------------------------------
- func: GetEnabled()
- desc: gets whether or not the object is enabled
--]]---------------------------------------------------------
function newobject:GetEnabled()
return self.enabled
end
--[[---------------------------------------------------------
- func: GetDown()
- desc: gets whether or not the object is currently
being pressed
--]]---------------------------------------------------------
function newobject:GetDown()
return self.down
end
--[[---------------------------------------------------------
- func: SetToggleable(bool)
- desc: sets whether or not the object is toggleable
--]]---------------------------------------------------------
function newobject:SetToggleable(bool)
self.toggleable = bool
return self
end
--[[---------------------------------------------------------
- func: GetToggleable()
- desc: gets whether or not the object is toggleable
--]]---------------------------------------------------------
function newobject:GetToggleable()
return self.toggleable
end
---------- module end ----------
end

View File

@ -0,0 +1,429 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- checkbox object
local newobject = loveframes.NewObject("checkbox", "loveframes_object_checkbox", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "checkbox"
self.width = 0
self.height = 0
self.boxwidth = 16
self.boxheight = 16
self.font = loveframes.basicfont
self.checked = false
self.lastvalue = false
self.internal = false
self.down = true
self.enabled = true
self.internals = {}
self.OnChanged = nil
self.groupIndex = 0
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
self:CheckHover()
local hover = self.hover
local internals = self.internals
local boxwidth = self.boxwidth
local boxheight = self.boxheight
local parent = self.parent
local base = loveframes.base
local update = self.Update
if not hover then
self.down = false
else
if loveframes.downobject == self then
self.down = true
end
end
if not self.down and loveframes.downobject == self then
self.hover = true
end
-- move to parent if there is a parent
if parent ~= base and parent.type ~= "list" then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
if internals[1] then
self.width = boxwidth + 5 + internals[1].width
if internals[1].height == boxheight then
self.height = boxheight
else
if internals[1].height > boxheight then
self.height = internals[1].height
else
self.height = boxheight
end
end
else
self.width = boxwidth
self.height = boxheight
end
for k, v in ipairs(internals) do
v:update(dt)
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local hover = self.hover
if hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
self.down = true
loveframes.downobject = self
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local hover = self.hover
local down = self.down
local enabled = self.enabled
local checked = self.checked
local onchanged = self.OnChanged
if hover and down and enabled and button == 1 then
if checked then
if self.groupIndex == 0 then self.checked = false end
else
if self.groupIndex ~= 0 then
local baseparent = self.parent
if baseparent then
for k, v in ipairs(baseparent.children) do
if v.groupIndex then
if v.groupIndex == self.groupIndex then
v.checked = false
end
end
end
end
end
self.checked = true
end
if onchanged then
onchanged(self, self.checked)
end
end
end
--[[---------------------------------------------------------
- func: SetText(text)
- desc: sets the object's text
--]]---------------------------------------------------------
function newobject:SetText(text)
local boxwidth = self.boxwidth
local boxheight = self.boxheight
if text ~= "" then
self.internals = {}
local textobject = loveframes.Create("text")
local skin = loveframes.GetActiveSkin()
if not skin then
skin = loveframes.config["DEFAULTSKIN"]
end
local directives = skin.directives
if directives then
local default_color = directives.checkbox_text_default_color
local default_shadowcolor = directives.checkbox_text_default_shadowcolor
local default_font = directives.checkbox_text_default_font
if default_color then
textobject.defaultcolor = default_color
end
if default_shadowcolor then
textobject.shadowcolor = default_shadowcolor
end
if default_font then
self.font = default_font
end
end
textobject:Remove()
textobject.parent = self
textobject.state = self.state
textobject.collide = false
textobject:SetFont(self.font)
textobject:SetText(text)
textobject.Update = function(object, dt)
if object.height > boxheight then
object:SetPos(boxwidth + 5, 0)
else
object:SetPos(boxwidth + 5, boxheight/2 - object.height/2)
end
end
table.insert(self.internals, textobject)
else
self.width = boxwidth
self.height = boxheight
self.internals = {}
end
return self
end
--[[---------------------------------------------------------
- func: GetText()
- desc: gets the object's text
--]]---------------------------------------------------------
function newobject:GetText()
local internals = self.internals
local text = internals[1]
if text then
return text.text
else
return false
end
end
--[[---------------------------------------------------------
- func: SetSize(width, height, r1, r2)
- desc: sets the object's size
--]]---------------------------------------------------------
function newobject:SetSize(width, height, r1, r2)
if r1 then
self.boxwidth = self.parent.width * width
else
self.boxwidth = width
end
if r2 then
self.boxheight = self.parent.height * height
else
self.boxheight = height
end
return self
end
--[[---------------------------------------------------------
- func: SetWidth(width, relative)
- desc: sets the object's width
--]]---------------------------------------------------------
function newobject:SetWidth(width, relative)
if relative then
self.boxwidth = self.parent.width * width
else
self.boxwidth = width
end
return self
end
--[[---------------------------------------------------------
- func: SetHeight(height, relative)
- desc: sets the object's height
--]]---------------------------------------------------------
function newobject:SetHeight(height, relative)
if relative then
self.boxheight = self.parent.height * height
else
self.boxheight = height
end
return self
end
--[[---------------------------------------------------------
- func: SetChecked(bool)
- desc: sets whether the object is checked or not
--]]---------------------------------------------------------
function newobject:SetChecked(bool)
local onchanged = self.OnChanged
self.checked = bool
if onchanged then
onchanged(self)
end
return self
end
--[[---------------------------------------------------------
- func: GetChecked()
- desc: gets whether the object is checked or not
--]]---------------------------------------------------------
function newobject:GetChecked()
return self.checked
end
--[[---------------------------------------------------------
- func: SetFont(font)
- desc: sets the font of the object's text
--]]---------------------------------------------------------
function newobject:SetFont(font)
local internals = self.internals
local text = internals[1]
self.font = font
if text then
text:SetFont(font)
end
return self
end
--[[---------------------------------------------------------
- func: newobject:GetFont()
- desc: gets the font of the object's text
--]]---------------------------------------------------------
function newobject:GetFont()
return self.font
end
--[[---------------------------------------------------------
- func: newobject:GetBoxHeight()
- desc: gets the object's box size
--]]---------------------------------------------------------
function newobject:GetBoxSize()
return self.boxwidth, self.boxheight
end
--[[---------------------------------------------------------
- func: newobject:GetBoxWidth()
- desc: gets the object's box width
--]]---------------------------------------------------------
function newobject:GetBoxWidth()
return self.boxwidth
end
--[[---------------------------------------------------------
- func: newobject:GetBoxHeight()
- desc: gets the object's box height
--]]---------------------------------------------------------
function newobject:GetBoxHeight()
return self.boxheight
end
--[[---------------------------------------------------------
- func: SetClickable(bool)
- desc: sets whether or not the object is enabled
--]]---------------------------------------------------------
function newobject:SetEnabled(bool)
self.enabled = bool
return self
end
--[[---------------------------------------------------------
- func: GetEnabled()
- desc: gets whether or not the object is enabled
--]]---------------------------------------------------------
function newobject:GetEnabled()
return self.enabled
end
---------- module end ----------
end

View File

@ -0,0 +1,328 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- collapsiblecategory object
local newobject = loveframes.NewObject("collapsiblecategory", "loveframes_object_collapsiblecategory", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "collapsiblecategory"
self.text = "Category"
self.width = 200
self.height = 25
self.closedheight = 25
self.padding = 5
self.internal = false
self.open = false
self.down = false
self.children = {}
self.OnOpenedClosed = nil
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
local open = self.open
local children = self.children
local curobject = children[1]
local parent = self.parent
local base = loveframes.base
local update = self.Update
self:CheckHover()
-- move to parent if there is a parent
if parent ~= base and parent.type ~= "list" then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
if open and curobject then
curobject:SetWidth(self.width - self.padding * 2)
curobject:update(dt)
elseif not open and curobject then
if curobject:GetVisible() then
curobject:SetVisible(false)
end
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local hover = self.hover
local open = self.open
local children = self.children
local curobject = children[1]
if hover then
local col = loveframes.BoundingBox(self.x, x, self.y, y, self.width, 1, self.closedheight, 1)
if button == 1 and col then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
self.down = true
loveframes.downobject = self
end
end
if open and curobject then
curobject:mousepressed(x, y, button)
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local hover = self.hover
local down = self.down
local clickable = self.clickable
local enabled = self.enabled
local open = self.open
local col = loveframes.BoundingBox(self.x, x, self.y, y, self.width, 1, self.closedheight, 1)
local children = self.children
local curobject = children[1]
if hover and col and down and button == 1 then
if open then
self:SetOpen(false)
else
self:SetOpen(true)
end
self.down = false
end
if open and curobject then
curobject:mousereleased(x, y, button)
end
end
--[[---------------------------------------------------------
- func: SetText(text)
- desc: sets the object's text
--]]---------------------------------------------------------
function newobject:SetText(text)
self.text = text
return self
end
--[[---------------------------------------------------------
- func: GetText()
- desc: gets the object's text
--]]---------------------------------------------------------
function newobject:GetText()
return self.text
end
--[[---------------------------------------------------------
- func: SetObject(object)
- desc: sets the category's object
--]]---------------------------------------------------------
function newobject:SetObject(object)
local children = self.children
local curobject = children[1]
if curobject then
curobject:Remove()
self.children = {}
end
object:Remove()
object.parent = self
object:SetState(self.state)
object:SetWidth(self.width - self.padding*2)
object:SetPos(self.padding, self.closedheight + self.padding)
table.insert(self.children, object)
return self
end
--[[---------------------------------------------------------
- func: SetObject(object)
- desc: sets the category's object
--]]---------------------------------------------------------
function newobject:GetObject()
local children = self.children
local curobject = children[1]
if curobject then
return curobject
else
return false
end
end
--[[---------------------------------------------------------
- func: SetSize(width, height, relative)
- desc: sets the object's size
--]]---------------------------------------------------------
function newobject:SetSize(width, height, relative)
if relative then
self.width = self.parent.width * width
else
self.width = width
end
return self
end
--[[---------------------------------------------------------
- func: SetHeight(height)
- desc: sets the object's height
--]]---------------------------------------------------------
function newobject:SetHeight(height)
return self
end
--[[---------------------------------------------------------
- func: SetClosedHeight(height)
- desc: sets the object's closed height
--]]---------------------------------------------------------
function newobject:SetClosedHeight(height)
self.closedheight = height
return self
end
--[[---------------------------------------------------------
- func: GetClosedHeight()
- desc: gets the object's closed height
--]]---------------------------------------------------------
function newobject:GetClosedHeight()
return self.closedheight
end
--[[---------------------------------------------------------
- func: SetOpen(bool)
- desc: sets whether the object is opened or closed
--]]---------------------------------------------------------
function newobject:SetOpen(bool)
local children = self.children
local curobject = children[1]
local closedheight = self.closedheight
local padding = self.padding
local onopenedclosed = self.OnOpenedClosed
self.open = bool
if not bool then
self.height = closedheight
if curobject then
local curobjectheight = curobject.height
curobject:SetVisible(false)
end
else
if curobject then
local curobjectheight = curobject.height
self.height = closedheight + padding * 2 + curobjectheight
curobject:SetVisible(true)
end
end
-- call the on opened closed callback if it exists
if onopenedclosed then
onopenedclosed(self)
end
return self
end
--[[---------------------------------------------------------
- func: GetOpen()
- desc: gets whether the object is opened or closed
--]]---------------------------------------------------------
function newobject:GetOpen()
return self.open
end
---------- module end ----------
end

View File

@ -0,0 +1,984 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- columnlist object
local newobject = loveframes.NewObject("columnlist", "loveframes_object_columnlist", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: intializes the element
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "columnlist"
self.width = 300
self.height = 100
self.defaultcolumnwidth = 100
self.columnheight = 16
self.buttonscrollamount = 200
self.mousewheelscrollamount = 1500
self.autoscroll = false
self.dtscrolling = true
self.internal = false
self.selectionenabled = true
self.multiselect = false
self.startadjustment = false
self.canresizecolumns = true
self.children = {}
self.internals = {}
self.resizecolumn = nil
self.OnRowClicked = nil
self.OnRowRightClicked = nil
self.OnRowSelected = nil
self.OnScroll = nil
local list = loveframes.objects["columnlistarea"]:new(self)
table.insert(self.internals, list)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
local parent = self.parent
local base = loveframes.base
local children = self.children
local internals = self.internals
local update = self.Update
self:CheckHover()
-- move to parent if there is a parent
if parent ~= base then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
for k, v in ipairs(internals) do
v:update(dt)
end
for k, v in ipairs(children) do
v.columnid = k
v:update(dt)
end
self.startadjustment = false
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: draw()
- desc: draws the object
--]]---------------------------------------------------------
function newobject:draw()
if loveframes.state ~= self.state then
return
end
if not self.visible then
return
end
local vbody = self.internals[1]:GetVerticalScrollBody()
local hbody = self.internals[1]:GetHorizontalScrollBody()
local width = self.width
local height = self.height
if vbody then
width = width - vbody.width
end
if hbody then
height = height - hbody.height
end
local stencilfunc = function()
love.graphics.rectangle("fill", self.x, self.y, width, height)
end
-- set the object's draw order
self:SetDrawOrder()
local drawfunc = self.Draw or self.drawfunc
if drawfunc then
drawfunc(self)
end
local internals = self.internals
if internals then
for k, v in ipairs(internals) do
v:draw()
end
end
love.graphics.stencil(stencilfunc)
love.graphics.setStencilTest("greater", 0)
local children = self.children
if children then
for k, v in ipairs(children) do
v:draw()
end
end
local drawfunc = self.DrawOver or self.drawoverfunc
if drawfunc then
drawfunc(self)
end
love.graphics.setStencilTest()
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local hover = self.hover
local children = self.children
local internals = self.internals
if hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
end
for k, v in ipairs(internals) do
v:mousepressed(x, y, button)
end
for k, v in ipairs(children) do
v:mousepressed(x, y, button)
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local children = self.children
local internals = self.internals
for k, v in ipairs(internals) do
v:mousereleased(x, y, button)
end
for k, v in ipairs(children) do
v:mousereleased(x, y, button)
end
end
--[[---------------------------------------------------------
- func: PositionColumns()
- desc: positions the object's columns
--]]---------------------------------------------------------
function newobject:PositionColumns()
local x = 0
for k, v in ipairs(self.children) do
v:SetPos(x, 0)
x = x + v.width
end
return self
end
--[[---------------------------------------------------------
- func: AddColumn(name)
- desc: gives the object a new column with the specified
name
--]]---------------------------------------------------------
function newobject:AddColumn(name)
local internals = self.internals
local list = internals[1]
local width = self.width
local height = self.height
loveframes.objects["columnlistheader"]:new(name, self)
self:PositionColumns()
list:SetSize(width, height)
list:SetPos(0, 0)
return self
end
--[[---------------------------------------------------------
- func: AddRow(...)
- desc: adds a row of data to the object's list
--]]---------------------------------------------------------
function newobject:AddRow(...)
local arg = {...}
local internals = self.internals
local list = internals[1]
list:AddRow(arg)
return self
end
--[[---------------------------------------------------------
- func: Getchildrenize()
- desc: gets the size of the object's children
--]]---------------------------------------------------------
function newobject:GetColumnSize()
local children = self.children
local numchildren = #self.children
if numchildren > 0 then
local column = self.children[1]
local colwidth = column.width
local colheight = column.height
return colwidth, colheight
else
return 0, 0
end
end
--[[---------------------------------------------------------
- func: SetSize(width, height, r1, r2)
- desc: sets the object's size
--]]---------------------------------------------------------
function newobject:SetSize(width, height, r1, r2)
local internals = self.internals
local list = internals[1]
if r1 then
self.width = self.parent.width * width
else
self.width = width
end
if r2 then
self.height = self.parent.height * height
else
self.height = height
end
self:PositionColumns()
list:SetSize(width, height)
list:SetPos(0, 0)
list:CalculateSize()
list:RedoLayout()
return self
end
--[[---------------------------------------------------------
- func: SetWidth(width, relative)
- desc: sets the object's width
--]]---------------------------------------------------------
function newobject:SetWidth(width, relative)
local internals = self.internals
local list = internals[1]
if relative then
self.width = self.parent.width * width
else
self.width = width
end
self:PositionColumns()
list:SetSize(width)
list:SetPos(0, 0)
list:CalculateSize()
list:RedoLayout()
return self
end
--[[---------------------------------------------------------
- func: SetHeight(height, relative)
- desc: sets the object's height
--]]---------------------------------------------------------
function newobject:SetHeight(height, relative)
local internals = self.internals
local list = internals[1]
if relative then
self.height = self.parent.height * height
else
self.height = height
end
self:PositionColumns()
list:SetSize(height)
list:SetPos(0, 0)
list:CalculateSize()
list:RedoLayout()
return self
end
--[[---------------------------------------------------------
- func: SetMaxColorIndex(num)
- desc: sets the object's max color index for
alternating row colors
--]]---------------------------------------------------------
function newobject:SetMaxColorIndex(num)
local internals = self.internals
local list = internals[1]
list.colorindexmax = num
return self
end
--[[---------------------------------------------------------
- func: Clear()
- desc: removes all items from the object's list
--]]---------------------------------------------------------
function newobject:Clear()
local internals = self.internals
local list = internals[1]
list:Clear()
return self
end
--[[---------------------------------------------------------
- func: SetAutoScroll(bool)
- desc: sets whether or not the list's scrollbar should
auto scroll to the bottom when a new object is
added to the list
--]]---------------------------------------------------------
function newobject:SetAutoScroll(bool)
local internals = self.internals
local list = internals[1]
local scrollbar = list:GetScrollBar()
self.autoscroll = bool
if list then
if scrollbar then
scrollbar.autoscroll = bool
end
end
return self
end
--[[---------------------------------------------------------
- func: SetButtonScrollAmount(speed)
- desc: sets the scroll amount of the object's scrollbar
buttons
--]]---------------------------------------------------------
function newobject:SetButtonScrollAmount(amount)
self.buttonscrollamount = amount
self.internals[1].buttonscrollamount = amount
return self
end
--[[---------------------------------------------------------
- func: GetButtonScrollAmount()
- desc: gets the scroll amount of the object's scrollbar
buttons
--]]---------------------------------------------------------
function newobject:GetButtonScrollAmount()
return self.buttonscrollamount
end
--[[---------------------------------------------------------
- func: SetMouseWheelScrollAmount(amount)
- desc: sets the scroll amount of the mouse wheel
--]]---------------------------------------------------------
function newobject:SetMouseWheelScrollAmount(amount)
self.mousewheelscrollamount = amount
self.internals[1].mousewheelscrollamount = amount
return self
end
--[[---------------------------------------------------------
- func: GetMouseWheelScrollAmount()
- desc: gets the scroll amount of the mouse wheel
--]]---------------------------------------------------------
function newobject:GetButtonScrollAmount()
return self.mousewheelscrollamount
end
--[[---------------------------------------------------------
- func: SetColumnHeight(height)
- desc: sets the height of the object's columns
--]]---------------------------------------------------------
function newobject:SetColumnHeight(height)
local children = self.children
local internals = self.internals
local list = internals[1]
self.columnheight = height
for k, v in ipairs(children) do
v:SetHeight(height)
end
list:CalculateSize()
list:RedoLayout()
return self
end
--[[---------------------------------------------------------
- func: SetDTScrolling(bool)
- desc: sets whether or not the object should use delta
time when scrolling
--]]---------------------------------------------------------
function newobject:SetDTScrolling(bool)
self.dtscrolling = bool
self.internals[1].dtscrolling = bool
return self
end
--[[---------------------------------------------------------
- func: GetDTScrolling()
- desc: gets whether or not the object should use delta
time when scrolling
--]]---------------------------------------------------------
function newobject:GetDTScrolling()
return self.dtscrolling
end
--[[---------------------------------------------------------
- func: SelectRow(row, ctrl)
- desc: selects the specfied row in the object's list
of rows
--]]---------------------------------------------------------
function newobject:SelectRow(row, ctrl)
local selectionenabled = self.selectionenabled
if not selectionenabled then
return
end
local list = self.internals[1]
local children = list.children
local multiselect = self.multiselect
local onrowselected = self.OnRowSelected
for k, v in ipairs(children) do
if v == row then
if v.selected and ctrl then
v.selected = false
else
v.selected = true
if onrowselected then
onrowselected(self, row, row:GetColumnData())
end
end
elseif v ~= row then
if not (multiselect and ctrl) then
v.selected = false
end
end
end
return self
end
--[[---------------------------------------------------------
- func: DeselectRow(row)
- desc: deselects the specfied row in the object's list
of rows
--]]---------------------------------------------------------
function newobject:DeselectRow(row)
row.selected = false
return self
end
--[[---------------------------------------------------------
- func: GetSelectedRows()
- desc: gets the object's selected rows
--]]---------------------------------------------------------
function newobject:GetSelectedRows()
local rows = {}
local list = self.internals[1]
local children = list.children
for k, v in ipairs(children) do
if v.selected then
table.insert(rows, v)
end
end
return rows
end
--[[---------------------------------------------------------
- func: SetSelectionEnabled(bool)
- desc: sets whether or not the object's rows can be
selected
--]]---------------------------------------------------------
function newobject:SetSelectionEnabled(bool)
self.selectionenabled = bool
return self
end
--[[---------------------------------------------------------
- func: GetSelectionEnabled()
- desc: gets whether or not the object's rows can be
selected
--]]---------------------------------------------------------
function newobject:GetSelectionEnabled()
return self.selectionenabled
end
--[[---------------------------------------------------------
- func: SetMultiselectEnabled(bool)
- desc: sets whether or not the object can have more
than one row selected
--]]---------------------------------------------------------
function newobject:SetMultiselectEnabled(bool)
self.multiselect = bool
return self
end
--[[---------------------------------------------------------
- func: GetMultiselectEnabled()
- desc: gets whether or not the object can have more
than one row selected
--]]---------------------------------------------------------
function newobject:GetMultiselectEnabled()
return self.multiselect
end
--[[---------------------------------------------------------
- func: RemoveColumn(id)
- desc: removes a column
--]]---------------------------------------------------------
function newobject:RemoveColumn(id)
local children = self.children
for k, v in ipairs(children) do
if k == id then
v:Remove()
end
end
return self
end
--[[---------------------------------------------------------
- func: SetColumnName(id, name)
- desc: sets a column's name
--]]---------------------------------------------------------
function newobject:SetColumnName(id, name)
local children = self.children
for k, v in ipairs(children) do
if k == id then
v.name = name
end
end
return self
end
--[[---------------------------------------------------------
- func: GetColumnName(id)
- desc: gets a column's name
--]]---------------------------------------------------------
function newobject:GetColumnName(id)
local children = self.children
for k, v in ipairs(children) do
if k == id then
return v.name
end
end
return false
end
--[[---------------------------------------------------------
- func: SizeToChildren(max)
- desc: sizes the object to match the combined height
of its children
- note: Credit to retupmoc258, the original author of
this method. This version has a few slight
modifications.
--]]---------------------------------------------------------
function newobject:SizeToChildren(max)
local oldheight = self.height
local list = self.internals[1]
local listchildren = list.children
local children = self.children
local width = self.width
local buf = children[1].height
local h = listchildren[1].height
local c = #listchildren
local height = buf + h*c
if max then
height = math.min(max, oldheight)
end
self:SetSize(width, height)
self:PositionColumns()
return self
end
--[[---------------------------------------------------------
- func: RemoveRow(id)
- desc: removes a row from the object's list
--]]---------------------------------------------------------
function newobject:RemoveRow(id)
local list = self.internals[1]
local listchildren = list.children
local row = listchildren[id]
if row then
row:Remove()
end
list:CalculateSize()
list:RedoLayout()
return self
end
--[[---------------------------------------------------------
- func: SetCellText(text, rowid, columnid)
- desc: sets a cell's text
--]]---------------------------------------------------------
function newobject:SetCellText(text, rowid, columnid)
local list = self.internals[1]
local listchildren = list.children
local row = listchildren[rowid]
if row and row.columndata[columnid]then
row.columndata[columnid] = text
end
return self
end
--[[---------------------------------------------------------
- func: GetCellText(rowid, columnid)
- desc: gets a cell's text
--]]---------------------------------------------------------
function newobject:GetCellText(rowid, columnid)
local row = self.internals[1].children[rowid]
if row and row.columndata[columnid] then
return row.columndata[columnid]
else
return false
end
end
--[[---------------------------------------------------------
- func: SetRowColumnData(rowid, columndata)
- desc: sets the columndata of the specified row
--]]---------------------------------------------------------
function newobject:SetRowColumnData(rowid, columndata)
local list = self.internals[1]
local listchildren = list.children
local row = listchildren[rowid]
if row then
for k, v in ipairs(columndata) do
row.columndata[k] = tostring(v)
end
end
return self
end
--[[---------------------------------------------------------
- func: GetTotalColumnWidth()
- desc: gets the combined width of the object's columns
--]]---------------------------------------------------------
function newobject:GetTotalColumnWidth()
local width = 0
for k, v in ipairs(self.children) do
width = width + v.width
end
return width
end
--[[---------------------------------------------------------
- func: SetColumnWidth(id, width)
- desc: sets the width of the specified column
--]]---------------------------------------------------------
function newobject:SetColumnWidth(id, width)
local column = self.children[id]
if column then
column.width = width
local x = 0
for k, v in ipairs(self.children) do
v:SetPos(x)
x = x + v.width
end
self.internals[1]:CalculateSize()
self.internals[1]:RedoLayout()
end
return self
end
--[[---------------------------------------------------------
- func: GetColumnWidth(id)
- desc: gets the width of the specified column
--]]---------------------------------------------------------
function newobject:GetColumnWidth(id)
local column = self.children[id]
if column then
return column.width
end
return false
end
--[[---------------------------------------------------------
- func: ResizeColumns()
- desc: resizes the object's columns to fit within the
width of the object's list area
--]]---------------------------------------------------------
function newobject:ResizeColumns()
local children = self.children
local width = 0
local vbody = self.internals[1]:GetVerticalScrollBody()
if vbody then
width = (self:GetWidth() - vbody:GetWidth())/#children
else
width = self:GetWidth()/#children
end
for k, v in ipairs(children) do
v:SetWidth(width)
self:PositionColumns()
self.internals[1]:CalculateSize()
self.internals[1]:RedoLayout()
end
return self
end
--[[---------------------------------------------------------
- func: SetDefaultColumnWidth(width)
- desc: sets the object's default column width
--]]---------------------------------------------------------
function newobject:SetDefaultColumnWidth(width)
self.defaultcolumnwidth = width
return self
end
--[[---------------------------------------------------------
- func: GetDefaultColumnWidth()
- desc: gets the object's default column width
--]]---------------------------------------------------------
function newobject:GetDefaultColumnWidth()
return self.defaultcolumnwidth
end
--[[---------------------------------------------------------
- func: SetColumnResizeEnabled(bool)
- desc: sets whether or not the object's columns can
be resized
--]]---------------------------------------------------------
function newobject:SetColumnResizeEnabled(bool)
self.canresizecolumns = bool
return self
end
--[[---------------------------------------------------------
- func: GetColumnResizeEnabled()
- desc: gets whether or not the object's columns can
be resized
--]]---------------------------------------------------------
function newobject:GetColumnResizeEnabled()
return self.canresizecolumns
end
--[[---------------------------------------------------------
- func: SizeColumnToData(columnid)
- desc: sizes a column to the width of its largest data
string
--]]---------------------------------------------------------
function newobject:SizeColumnToData(columnid)
local column = self.children[columnid]
local list = self.internals[1]
local largest = 0
for k, v in ipairs(list.children) do
local width = v:GetFont():getWidth(self:GetCellText(k, columnid))
if width > largest then
largest = width + v.textx
end
end
if largest <= 0 then
largest = 10
end
self:SetColumnWidth(columnid, largest)
return self
end
--[[---------------------------------------------------------
- func: SetColumnOrder(curid, newid)
- desc: sets the order of the specified column
--]]---------------------------------------------------------
function newobject:SetColumnOrder(curid, newid)
local column = self.children[curid]
local totalcolumns = #self.children
if column and totalcolumns > 1 and newid <= totalcolumns and newid >= 1 then
column:Remove()
table.insert(self.children, newid, column)
self:PositionColumns()
end
return self
end
---------- module end ----------
end

303
loveframes/objects/form.lua Normal file
View File

@ -0,0 +1,303 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- form object
local newobject = loveframes.NewObject("form", "loveframes_object_form", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "form"
self.name = "Form"
self.layout = "vertical"
self.width = 200
self.height = 50
self.padding = 5
self.spacing = 5
self.topmargin = 12
self.internal = false
self.children = {}
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the element
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
local children = self.children
local parent = self.parent
local base = loveframes.base
local update = self.Update
-- move to parent if there is a parent
if parent ~= base and parent.type ~= "list" then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
self:CheckHover()
for k, v in ipairs(children) do
v:update(dt)
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local children = self.children
local hover = self.hover
if hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
end
for k, v in ipairs(children) do
v:mousepressed(x, y, button)
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local children = self.children
if not visible then
return
end
for k, v in ipairs(children) do
v:mousereleased(x, y, button)
end
end
--[[---------------------------------------------------------
- func: AddItem(object)
- desc: adds an item to the object
--]]---------------------------------------------------------
function newobject:AddItem(object)
local objtype = object.type
if objtype == "frame" then
return
end
local children = self.children
local state = self.state
object:Remove()
object.parent = self
object:SetState(state)
table.insert(children, object)
self:LayoutObjects()
return self
end
--[[---------------------------------------------------------
- func: RemoveItem(object or number)
- desc: removes an item from the object
--]]---------------------------------------------------------
function newobject:RemoveItem(data)
local dtype = type(data)
if dtype == "number" then
local children = self.children
local item = children[data]
if item then
item:Remove()
end
else
data:Remove()
end
self:LayoutObjects()
return self
end
--[[---------------------------------------------------------
- func: LayoutObjects()
- desc: positions the object's children and calculates
a new size for the object
--]]---------------------------------------------------------
function newobject:LayoutObjects()
local layout = self.layout
local padding = self.padding
local spacing = self.spacing
local topmargin = self.topmargin
local children = self.children
local width = padding * 2
local height = padding * 2 + topmargin
local x = padding
local y = padding + topmargin
if layout == "vertical" then
local largest_width = 0
for k, v in ipairs(children) do
v.staticx = x
v.staticy = y
y = y + v.height + spacing
height = height + v.height + spacing
if v.width > largest_width then
largest_width = v.width
end
end
height = height - spacing
self.width = width + largest_width
self.height = height
elseif layout == "horizontal" then
local largest_height = 0
for k, v in ipairs(children) do
v.staticx = x
v.staticy = y
x = x + v.width + spacing
width = width + v.width + spacing
if v.height > largest_height then
largest_height = v.height
end
end
width = width - spacing
self.width = width
self.height = height + largest_height
end
return self
end
--[[---------------------------------------------------------
- func: SetLayoutType(ltype)
- desc: sets the object's layout type
--]]---------------------------------------------------------
function newobject:SetLayoutType(ltype)
self.layout = ltype
return self
end
--[[---------------------------------------------------------
- func: GetLayoutType()
- desc: gets the object's layout type
--]]---------------------------------------------------------
function newobject:GetLayoutType()
return self.layout
end
--[[---------------------------------------------------------
- func: SetTopMargin(margin)
- desc: sets the margin between the top of the object
and its children
--]]---------------------------------------------------------
function newobject:SetTopMargin(margin)
self.topmargin = margin
return self
end
--[[---------------------------------------------------------
- func: GetTopMargin()
- desc: gets the margin between the top of the object
and its children
--]]---------------------------------------------------------
function newobject:GetTopMargin()
return self.topmargin
end
--[[---------------------------------------------------------
- func: SetName(name)
- desc: sets the object's name
--]]---------------------------------------------------------
function newobject:SetName(name)
self.name = name
return self
end
--[[---------------------------------------------------------
- func: GetName()
- desc: gets the object's name
--]]---------------------------------------------------------
function newobject:GetName()
return self.name
end
---------- module end ----------
end

1111
loveframes/objects/frame.lua Normal file

File diff suppressed because it is too large Load Diff

358
loveframes/objects/grid.lua Normal file
View File

@ -0,0 +1,358 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- grid object
local newobject = loveframes.NewObject("grid", "loveframes_object_grid", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "grid"
self.width = 100
self.height = 100
self.prevwidth = 100
self.prevheight = 100
self.rows = 0
self.columns = 0
self.cellwidth = 25
self.cellheight = 25
self.cellpadding = 5
self.itemautosize = false
self.children = {}
self.OnSizeChanged = nil
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
self:CheckHover()
local parent = self.parent
local children = self.children
local base = loveframes.base
-- move to parent if there is a parent
if parent ~= base then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
local cw = self.cellwidth + (self.cellpadding * 2)
local ch = self.cellheight + (self.cellpadding * 2)
local prevwidth = self.prevwidth
local prevheight = self.prevheight
self.width = (self.columns * self.cellwidth) + (self.columns * (self.cellpadding * 2))
self.height = (self.rows * self.cellheight) + (self.rows * (self.cellpadding * 2))
if self.width ~= prevwidth or self.height ~= prevheight then
local onsizechanged = self.OnSizeChanged
self.prevwidth = self.width
self.prevheight = self.height
if onsizechanged then
onsizechanged(self)
end
end
for k, v in ipairs(children) do
local x = 0 + ((cw * v.gridcolumn) - cw ) + (cw/2 - v.width/2)
local y = 0 + ((ch * v.gridrow) - ch) + (ch/2 - v.height/2)
v.staticx = x
v.staticy = y
v:update(dt)
end
local update = self.Update
if update then update(self, dt) end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local children = self.children
local hover = self.hover
if hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
end
for k, v in ipairs(children) do
v:mousepressed(x, y, button)
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local children = self.children
if not visible then
return
end
for k, v in ipairs(children) do
v:mousereleased(x, y, button)
end
end
--[[---------------------------------------------------------
- func: AddItem(object, row, column)
- desc: adds and item to the object
--]]---------------------------------------------------------
function newobject:AddItem(object, row, column)
local itemautosize = self.itemautosize
local children = self.children
object:Remove()
table.insert(children, object)
object.parent = self
object.gridrow = row
object.gridcolumn = column
if itemautosize then
local cw = self.cellwidth + (self.cellpadding * 2)
local ch = self.cellheight + (self.cellpadding * 2)
object.width = cw - (self.cellpadding * 2)
object.height = ch - (self.cellpadding * 2)
end
return self
end
--[[---------------------------------------------------------
- func: GetItem(row, column)
- desc: gets an item from the object at the specified
row and column
--]]---------------------------------------------------------
function newobject:GetItem(row, column)
local children = self.children
for k, v in ipairs(children) do
if v.gridrow == row and v.gridcolumn == column then
return v
end
end
return false
end
--[[---------------------------------------------------------
- func: SetItemAutoSize(bool)
- desc: sets whether or not the object should auto-size
its items
--]]---------------------------------------------------------
function newobject:SetItemAutoSize(bool)
self.itemautosize = bool
return self
end
--[[---------------------------------------------------------
- func: GetItemAutoSize()
- desc: gets whether or not the object should auto-size
its items
--]]---------------------------------------------------------
function newobject:GetItemAutoSize()
return self.itemautosize
end
--[[---------------------------------------------------------
- func: SetRows(rows)
- desc: sets the number of rows the object should have
--]]---------------------------------------------------------
function newobject:SetRows(rows)
self.rows = rows
return self
end
--[[---------------------------------------------------------
- func: SetRows(rows)
- desc: gets the number of rows the object has
--]]---------------------------------------------------------
function newobject:GetRows()
return self.rows
end
--[[---------------------------------------------------------
- func: SetColumns(columns)
- desc: sets the number of columns the object should
have
--]]---------------------------------------------------------
function newobject:SetColumns(columns)
self.columns = columns
return self
end
--[[---------------------------------------------------------
- func: GetColumns()
- desc: gets the number of columns the object has
--]]---------------------------------------------------------
function newobject:GetColumns()
return self.columns
end
--[[---------------------------------------------------------
- func: SetCellWidth(width)
- desc: sets the width of the object's cells
--]]---------------------------------------------------------
function newobject:SetCellWidth(width)
self.cellwidth = width
return self
end
--[[---------------------------------------------------------
- func: GetCellWidth()
- desc: gets the width of the object's cells
--]]---------------------------------------------------------
function newobject:GetCellWidth()
return self.cellwidth
end
--[[---------------------------------------------------------
- func: SetCellHeight(height)
- desc: sets the height of the object's cells
--]]---------------------------------------------------------
function newobject:SetCellHeight(height)
self.cellheight = height
return self
end
--[[---------------------------------------------------------
- func: GetCellHeight()
- desc: gets the height of the object's cells
--]]---------------------------------------------------------
function newobject:GetCellHeight()
return self.cellheight
end
--[[---------------------------------------------------------
- func: SetCellSize(width, height)
- desc: sets the size of the object's cells
--]]---------------------------------------------------------
function newobject:SetCellSize(width, height)
self.cellwidth = width
self.cellheight = height
return self
end
--[[---------------------------------------------------------
- func: GetCellSize()
- desc: gets the size of the object's cells
--]]---------------------------------------------------------
function newobject:GetCellSize()
return self.cellwidth, self.cellheight
end
--[[---------------------------------------------------------
- func: SetCellPadding(padding)
- desc: sets the padding of the object's cells
--]]---------------------------------------------------------
function newobject:SetCellPadding(padding)
self.cellpadding = padding
return self
end
--[[---------------------------------------------------------
- func: GetCellPadding
- desc: gets the padding of the object's cells
--]]---------------------------------------------------------
function newobject:GetCellPadding()
return self.cellpadding
end
---------- module end ----------
end

View File

@ -0,0 +1,385 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- image object
local newobject = loveframes.NewObject("image", "loveframes_object_image", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "image"
self.width = 0
self.height = 0
self.orientation = 0
self.scalex = 1
self.scaley = 1
self.offsetx = 0
self.offsety = 0
self.shearx = 0
self.sheary = 0
self.internal = false
self.image = nil
self.imagecolor = {1, 1, 1, 1}
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
local parent = self.parent
local base = loveframes.base
local update = self.Update
self:CheckHover()
-- move to parent if there is a parent
if parent ~= base then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: SetImage(image)
- desc: sets the object's image
--]]---------------------------------------------------------
function newobject:SetImage(image)
if type(image) == "string" then
self.image = love.graphics.newImage(image)
self.image:setFilter("nearest", "nearest")
else
self.image = image
end
self.width = self.image:getWidth()
self.height = self.image:getHeight()
return self
end
--[[---------------------------------------------------------
- func: GetImage()
- desc: gets the object's image
--]]---------------------------------------------------------
function newobject:GetImage()
return self.image
end
--[[---------------------------------------------------------
- func: SetColor(r, g, b, a)
- desc: sets the object's color
--]]---------------------------------------------------------
function newobject:SetColor(r, g, b, a)
self.imagecolor = {r, g, b, a}
return self
end
--[[---------------------------------------------------------
- func: GetColor()
- desc: gets the object's color
--]]---------------------------------------------------------
function newobject:GetColor()
return unpack(self.imagecolor)
end
--[[---------------------------------------------------------
- func: SetOrientation(orientation)
- desc: sets the object's orientation
--]]---------------------------------------------------------
function newobject:SetOrientation(orientation)
self.orientation = orientation
return self
end
--[[---------------------------------------------------------
- func: GetOrientation()
- desc: gets the object's orientation
--]]---------------------------------------------------------
function newobject:GetOrientation()
return self.orientation
end
--[[---------------------------------------------------------
- func: SetScaleX(scalex)
- desc: sets the object's x scale
--]]---------------------------------------------------------
function newobject:SetScaleX(scalex)
self.scalex = scalex
return self
end
--[[---------------------------------------------------------
- func: GetScaleX()
- desc: gets the object's x scale
--]]---------------------------------------------------------
function newobject:GetScaleX()
return self.scalex
end
--[[---------------------------------------------------------
- func: SetScaleY(scaley)
- desc: sets the object's y scale
--]]---------------------------------------------------------
function newobject:SetScaleY(scaley)
self.scaley = scaley
return self
end
--[[---------------------------------------------------------
- func: GetScaleY()
- desc: gets the object's y scale
--]]---------------------------------------------------------
function newobject:GetScaleY()
return self.scaley
end
--[[---------------------------------------------------------
- func: SetScale(scalex, scaley)
- desc: sets the object's x and y scale
--]]---------------------------------------------------------
function newobject:SetScale(scalex, scaley)
self.scalex = scalex
self.scaley = scaley
return self
end
--[[---------------------------------------------------------
- func: GetScale()
- desc: gets the object's x and y scale
--]]---------------------------------------------------------
function newobject:GetScale()
return self.scalex, self.scaley
end
--[[---------------------------------------------------------
- func: SetOffsetX(x)
- desc: sets the object's x offset
--]]---------------------------------------------------------
function newobject:SetOffsetX(x)
self.offsetx = x
return self
end
--[[---------------------------------------------------------
- func: GetOffsetX()
- desc: gets the object's x offset
--]]---------------------------------------------------------
function newobject:GetOffsetX()
return self.offsetx
end
--[[---------------------------------------------------------
- func: SetOffsetY(y)
- desc: sets the object's y offset
--]]---------------------------------------------------------
function newobject:SetOffsetY(y)
self.offsety = y
return self
end
--[[---------------------------------------------------------
- func: GetOffsetY()
- desc: gets the object's y offset
--]]---------------------------------------------------------
function newobject:GetOffsetY()
return self.offsety
end
--[[---------------------------------------------------------
- func: SetOffset(x, y)
- desc: sets the object's x and y offset
--]]---------------------------------------------------------
function newobject:SetOffset(x, y)
self.offsetx = x
self.offsety = y
return self
end
--[[---------------------------------------------------------
- func: GetOffset()
- desc: gets the object's x and y offset
--]]---------------------------------------------------------
function newobject:GetOffset()
return self.offsetx, self.offsety
end
--[[---------------------------------------------------------
- func: SetShearX(shearx)
- desc: sets the object's x shear
--]]---------------------------------------------------------
function newobject:SetShearX(shearx)
self.shearx = shearx
return self
end
--[[---------------------------------------------------------
- func: GetShearX()
- desc: gets the object's x shear
--]]---------------------------------------------------------
function newobject:GetShearX()
return self.shearx
end
--[[---------------------------------------------------------
- func: SetShearY(sheary)
- desc: sets the object's y shear
--]]---------------------------------------------------------
function newobject:SetShearY(sheary)
self.sheary = sheary
return self
end
--[[---------------------------------------------------------
- func: GetShearY()
- desc: gets the object's y shear
--]]---------------------------------------------------------
function newobject:GetShearY()
return self.sheary
end
--[[---------------------------------------------------------
- func: SetShear(shearx, sheary)
- desc: sets the object's x and y shear
--]]---------------------------------------------------------
function newobject:SetShear(shearx, sheary)
self.shearx = shearx
self.sheary = sheary
return self
end
--[[---------------------------------------------------------
- func: GetShear()
- desc: gets the object's x and y shear
--]]---------------------------------------------------------
function newobject:GetShear()
return self.shearx, self.sheary
end
--[[---------------------------------------------------------
- func: GetImageSize()
- desc: gets the size of the object's image
--]]---------------------------------------------------------
function newobject:GetImageSize()
local image = self.image
if image then
return image:getWidth(), image:getHeight()
end
end
--[[---------------------------------------------------------
- func: GetImageWidth()
- desc: gets the width of the object's image
--]]---------------------------------------------------------
function newobject:GetImageWidth()
local image = self.image
if image then
return image:getWidth()
end
end
--[[---------------------------------------------------------
- func: GetImageWidth()
- desc: gets the height of the object's image
--]]---------------------------------------------------------
function newobject:GetImageHeight()
local image = self.image
if image then
return image:getHeight()
end
end
---------- module end ----------
end

View File

@ -0,0 +1,343 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- imagebutton object
local newobject = loveframes.NewObject("imagebutton", "loveframes_object_imagebutton", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "imagebutton"
self.text = "Image Button"
self.width = 50
self.height = 50
self.internal = false
self.down = false
self.clickable = true
self.enabled = true
self.image = nil
self.imagecolor = {1, 1, 1, 1}
self.OnClick = nil
self.groupIndex = 0
self.checked = false
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
self:CheckHover()
local hover = self.hover
local downobject = loveframes.downobject
local down = self.down
local parent = self.parent
local base = loveframes.base
local update = self.Update
if not hover then
self.down = false
else
if downobject == self then
self.down = true
end
end
if not down and downobject == self then
self.hover = true
end
-- move to parent if there is a parent
if parent ~= base then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local hover = self.hover
if hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
self.down = true
loveframes.downobject = self
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local hover = self.hover
local down = self.down
local clickable = self.clickable
local enabled = self.enabled
local onclick = self.OnClick
if hover and down and clickable and button == 1 then
if enabled then
if self.groupIndex ~= 0 then
local baseparent = self.parent
if baseparent then
for k, v in ipairs(baseparent.children) do
if v.groupIndex then
if v.groupIndex == self.groupIndex then
v.checked = false
end
end
end
end
self.checked = true
end
if onclick then
onclick(self, x, y)
end
end
end
self.down = false
end
--[[---------------------------------------------------------
- func: SetText(text)
- desc: sets the object's text
--]]---------------------------------------------------------
function newobject:SetText(text)
self.text = text
return self
end
--[[---------------------------------------------------------
- func: GetText()
- desc: gets the object's text
--]]---------------------------------------------------------
function newobject:GetText()
return self.text
end
--[[---------------------------------------------------------
- func: SetClickable(bool)
- desc: sets whether the object can be clicked or not
--]]---------------------------------------------------------
function newobject:SetClickable(bool)
self.clickable = bool
return self
end
--[[---------------------------------------------------------
- func: GetClickable(bool)
- desc: gets whether the object can be clicked or not
--]]---------------------------------------------------------
function newobject:GetClickable()
return self.clickable
end
--[[---------------------------------------------------------
- func: SetClickable(bool)
- desc: sets whether the object is enabled or not
--]]---------------------------------------------------------
function newobject:SetEnabled(bool)
self.enabled = bool
return self
end
--[[---------------------------------------------------------
- func: GetEnabled()
- desc: gets whether the object is enabled or not
--]]---------------------------------------------------------
function newobject:GetEnabled()
return self.enabled
end
--[[---------------------------------------------------------
- func: SetImage(image)
- desc: sets the object's image
--]]---------------------------------------------------------
function newobject:SetImage(image)
if type(image) == "string" then
self.image = love.graphics.newImage(image)
self.image:setFilter("nearest", "nearest")
else
self.image = image
end
return self
end
--[[---------------------------------------------------------
- func: GetImage()
- desc: gets whether the object is enabled or not
--]]---------------------------------------------------------
function newobject:GetImage()
return self.image
end
--[[---------------------------------------------------------
- func: SizeToImage()
- desc: makes the object the same size as its image
--]]---------------------------------------------------------
function newobject:SizeToImage()
local image = self.image
if image then
self.width = image:getWidth()
self.height = image:getHeight()
end
return self
end
--[[---------------------------------------------------------
- func: GetImageSize()
- desc: gets the size of the object's image
--]]---------------------------------------------------------
function newobject:GetImageSize()
local image = self.image
if image then
return image:getWidth(), image:getHeight()
end
end
--[[---------------------------------------------------------
- func: GetImageWidth()
- desc: gets the width of the object's image
--]]---------------------------------------------------------
function newobject:GetImageWidth()
local image = self.image
if image then
return image:getWidth()
end
end
--[[---------------------------------------------------------
- func: GetImageWidth()
- desc: gets the height of the object's image
--]]---------------------------------------------------------
function newobject:GetImageHeight()
local image = self.image
if image then
return image:getHeight()
end
end
--[[---------------------------------------------------------
- func: SetColor(r, g, b, a)
- desc: sets the object's color
--]]---------------------------------------------------------
function newobject:SetColor(r, g, b, a)
self.imagecolor = {r, g, b, a}
return self
end
--[[---------------------------------------------------------
- func: GetColor()
- desc: gets the object's color
--]]---------------------------------------------------------
function newobject:GetColor()
return unpack(self.imagecolor)
end
---------- module end ----------
end

View File

@ -0,0 +1,159 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- closebutton class
local newobject = loveframes.NewObject("closebutton", "loveframes_object_closebutton", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "closebutton"
self.width = 16
self.height = 16
self.internal = true
self.hover = false
self.down = false
self.autoposition = true
self.OnClick = function() end
-- apply template properties to the object
loveframes.ApplyTemplatesToObject(self)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
self:CheckHover()
local hover = self.hover
local down = self.down
local downobject = loveframes.downobject
local parent = self.parent
local base = loveframes.base
local update = self.Update
if not hover then
self.down = false
else
if loveframes.downobject == self then
self.down = true
end
end
if not down and downobject == self then
self.hover = true
end
if self.autoposition then
self.staticx = self.parent.width - self.width - 4
self.staticy = 4
end
-- move to parent if there is a parent
if parent ~= base then
self.x = parent.x + self.staticx
self.y = parent.y + self.staticy
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local visible = self.visible
if not visible then
return
end
local hover = self.hover
if hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
self.down = true
loveframes.downobject = self
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local visible = self.visible
if not visible then
return
end
local hover = self.hover
local onclick = self.OnClick
if hover and self.down then
if button == 1 then
onclick(x, y, self)
end
end
self.down = false
end
--[[---------------------------------------------------------
- func: SetAutoPosition(bool)
- desc: sets whether or not the object should be
positioned automatically
--]]---------------------------------------------------------
function newobject:SetAutoPosition(bool)
self.autoposition = bool
end
--[[---------------------------------------------------------
- func: GetAutoPosition()
- desc: gets whether or not the object should be
positioned automatically
--]]---------------------------------------------------------
function newobject:GetAutoPosition()
return self.autoposition
end
---------- module end ----------
end

View File

@ -0,0 +1,469 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- columnlistarea class
local newobject = loveframes.NewObject("columnlistarea", "loveframes_object_columnlistarea", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: intializes the element
--]]---------------------------------------------------------
function newobject:initialize(parent)
self.type = "columnlistarea"
self.display = "vertical"
self.parent = parent
self.width = 80
self.height = 25
self.clickx = 0
self.clicky = 0
self.offsety = 0
self.offsetx = 0
self.extrawidth = 0
self.extraheight = 0
self.rowcolorindex = 1
self.rowcolorindexmax = 2
self.buttonscrollamount = parent.buttonscrollamount
self.mousewheelscrollamount = parent.mousewheelscrollamount
self.vbar = false
self.hbar = false
self.dtscrolling = parent.dtscrolling
self.internal = true
self.internals = {}
self.children = {}
-- apply template properties to the object
loveframes.ApplyTemplatesToObject(self)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
if not self.visible then
if not self.alwaysupdate then
return
end
end
local cwidth, cheight = self.parent:GetColumnSize()
local parent = self.parent
local update = self.Update
local internals = self.internals
self:CheckHover()
-- move to parent if there is a parent
if parent ~= loveframes.base then
self.x = parent.x + self.staticx
self.y = parent.y + self.staticy
end
for k, v in ipairs(self.children) do
local col = loveframes.BoundingBox(self.x, v.x, self.y, v.y, self.width, v.width, self.height, v.height)
if col then
v:update(dt)
end
v:SetClickBounds(self.x, self.y, self.width, self.height)
v.y = (v.parent.y + v.staticy) - self.offsety + cheight
v.x = (v.parent.x + v.staticx) - self.offsetx
end
for k, v in ipairs(self.internals) do
v:update(dt)
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: draw()
- desc: draws the object
--]]---------------------------------------------------------
function newobject:draw()
if loveframes.state ~= self.state then
return
end
if not self.visible then
return
end
local x = self.x
local y = self.y
local width = self.width
local height = self.height
local swidth = width
local sheight = height
if self.vbar then
swidth = swidth - self:GetVerticalScrollBody():GetWidth()
end
if self.hbar then
sheight = sheight - self:GetHorizontalScrollBody():GetHeight()
end
local stencilfunc = function() love.graphics.rectangle("fill", x, y, swidth, sheight) end
self:SetDrawOrder()
local drawfunc = self.Draw or self.drawfunc
if drawfunc then
drawfunc(self)
end
love.graphics.stencil(stencilfunc)
love.graphics.setStencilTest("greater", 0)
local children = self.children
if children then
for k, v in ipairs(self.children) do
local col = loveframes.BoundingBox(self.x, v.x, self.y, v.y, width, v.width, height, v.height)
if col then
v:draw()
end
end
end
love.graphics.setStencilTest()
drawfunc = self.DrawOver or self.drawoverfunc
if drawfunc then
drawfunc(self)
end
local internals = self.internals
if internals then
for k, v in ipairs(self.internals) do
v:draw()
end
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local scrollamount = self.mousewheelscrollamount
if self.hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
end
for k, v in ipairs(self.internals) do
v:mousepressed(x, y, button)
end
for k, v in ipairs(self.children) do
v:mousepressed(x, y, button)
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local internals = self.internals
local children = self.children
for k, v in ipairs(internals) do
v:mousereleased(x, y, button)
end
for k, v in ipairs(children) do
v:mousereleased(x, y, button)
end
end
--[[---------------------------------------------------------
- func: wheelmoved(x, y)
- desc: called when the player moves a mouse wheel
--]]---------------------------------------------------------
function newobject:wheelmoved(x, y)
local scrollamount = self.mousewheelscrollamount
-- FIXME: button is nil
-- if self.hover and button == 1 then
if self.hover then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
end
local bar = false
if self.vbar and self.hbar then
bar = self:GetVerticalScrollBody():GetScrollBar()
elseif self.vbar and not self.hbar then
bar = self:GetVerticalScrollBody():GetScrollBar()
elseif not self.vbar and self.hbar then
bar = self:GetHorizontalScrollBody():GetScrollBar()
end
if self:IsTopList() and bar then
if self.dtscrolling then
local dt = love.timer.getDelta()
bar:Scroll(-y * scrollamount * dt)
else
bar:Scroll(-y * scrollamount)
end
end
end
--[[---------------------------------------------------------
- func: CalculateSize()
- desc: calculates the size of the object's children
--]]---------------------------------------------------------
function newobject:CalculateSize()
local height = self.height
local width = self.width
local parent = self.parent
local itemheight = parent.columnheight
for k, v in ipairs(self.children) do
itemheight = itemheight + v.height
end
self.itemheight = itemheight
self.itemwidth = parent:GetTotalColumnWidth()
local hbarheight = 0
local hbody = self:GetHorizontalScrollBody()
if hbody then
hbarheight = hbody.height
end
if self.itemheight > (height - hbarheight) then
if hbody then
self.itemheight = self.itemheight + hbarheight
end
self.extraheight = self.itemheight - height
if not self.vbar then
local newbar = loveframes.objects["scrollbody"]:new(self, "vertical")
table.insert(self.internals, newbar)
self.vbar = true
newbar:GetScrollBar().autoscroll = parent.autoscroll
self.itemwidth = self.itemwidth + newbar.width
self.extrawidth = self.itemwidth - width
end
else
if self.vbar then
self:GetVerticalScrollBody():Remove()
self.vbar = false
self.offsety = 0
end
end
local vbarwidth = 0
local vbody = self:GetVerticalScrollBody()
if vbody then
vbarwidth = vbody.width
end
if self.itemwidth > (width - vbarwidth) then
if vbody then
self.itemwidth = self.itemwidth + vbarwidth
end
self.extrawidth = self.itemwidth - width
if not self.hbar then
local newbar = loveframes.objects["scrollbody"]:new(self, "horizontal")
table.insert(self.internals, newbar)
self.hbar = true
self.itemheight = self.itemheight + newbar.height
self.extraheight = self.itemheight - height
end
else
if self.hbar then
local hbar = self:GetHorizontalScrollBody()
hbar:Remove()
self.itemheight = self.itemheight - hbar.height
self.extraheight = self.itemheight - height
self.hbar = false
self.offsetx = 0
end
end
end
--[[---------------------------------------------------------
- func: RedoLayout()
- desc: used to redo the layour of the object
--]]---------------------------------------------------------
function newobject:RedoLayout()
local starty = 0
self.rowcolorindex = 1
for k, v in ipairs(self.children) do
v:SetWidth(self.parent:GetTotalColumnWidth())
v.staticx = 0
v.staticy = starty
if self.vbar then
local vbody = self:GetVerticalScrollBody()
vbody.staticx = self.width - vbody.width
if self.hbar then
vbody.height = self.height - self:GetHorizontalScrollBody().height
else
vbody.height = self.height
end
end
if self.hbar then
local hbody = self:GetHorizontalScrollBody()
hbody.staticy = self.height - hbody.height
if self.vbar then
hbody.width = self.width - self:GetVerticalScrollBody().width
else
hbody.width = self.width
end
end
starty = starty + v.height
v.lastheight = v.height
v.colorindex = self.rowcolorindex
if self.rowcolorindex == self.rowcolorindexmax then
self.rowcolorindex = 1
else
self.rowcolorindex = self.rowcolorindex + 1
end
end
end
--[[---------------------------------------------------------
- func: AddRow(data)
- desc: adds a row to the object
--]]---------------------------------------------------------
function newobject:AddRow(data)
local colorindex = self.rowcolorindex
if colorindex == self.rowcolorindexmax then
self.rowcolorindex = 1
else
self.rowcolorindex = colorindex + 1
end
table.insert(self.children, loveframes.objects["columnlistrow"]:new(self, data))
self:CalculateSize()
self:RedoLayout()
self.parent:PositionColumns()
end
--[[---------------------------------------------------------
- func: GetScrollBar()
- desc: gets the object's scroll bar
--]]---------------------------------------------------------
function newobject:GetScrollBar()
if self.bar then
return self.internals[1].internals[1].internals[1]
else
return false
end
end
--[[---------------------------------------------------------
- func: Sort()
- desc: sorts the object's children
--]]---------------------------------------------------------
function newobject:Sort(column, desc)
local children = self.children
self.rowcolorindex = 1
table.sort(children, function(a, b)
if desc then
return (tostring(a.columndata[column]) or a.columndata[column]) < (tostring(b.columndata[column]) or b.columndata[column])
else
return (tostring(a.columndata[column]) or a.columndata[column]) > (tostring(b.columndata[column]) or b.columndata[column])
end
end)
for k, v in ipairs(children) do
local colorindex = self.rowcolorindex
v.colorindex = colorindex
if colorindex == self.rowcolorindexmax then
self.rowcolorindex = 1
else
self.rowcolorindex = colorindex + 1
end
end
self:CalculateSize()
self:RedoLayout()
end
--[[---------------------------------------------------------
- func: Clear()
- desc: removes all items from the object's list
--]]---------------------------------------------------------
function newobject:Clear()
self.children = {}
self:CalculateSize()
self:RedoLayout()
self.parent:PositionColumns()
self.rowcolorindex = 1
end
--[[---------------------------------------------------------
- func: GetVerticalScrollBody()
- desc: gets the object's vertical scroll body
--]]---------------------------------------------------------
function newobject:GetVerticalScrollBody()
for k, v in ipairs(self.internals) do
if v.bartype == "vertical" then
return v
end
end
return false
end
--[[---------------------------------------------------------
- func: GetHorizontalScrollBody()
- desc: gets the object's horizontal scroll body
--]]---------------------------------------------------------
function newobject:GetHorizontalScrollBody()
for k, v in ipairs(self.internals) do
if v.bartype == "horizontal" then
return v
end
end
return false
end
---------- module end ----------
end

View File

@ -0,0 +1,203 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- columnlistheader class
local newobject = loveframes.NewObject("columnlistheader", "loveframes_object_columnlistheader", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: intializes the element
--]]---------------------------------------------------------
function newobject:initialize(name, parent)
self.type = "columnlistheader"
self.parent = parent
self.name = name
self.state = parent.state
self.width = parent.defaultcolumnwidth
self.height = parent.columnheight
self.columnid = 0
self.hover = false
self.down = false
self.clickable = true
self.enabled = true
self.descending = true
self.resizebox = nil
self.internal = true
table.insert(parent.children, self)
local key = 0
for k, v in ipairs(parent.children) do
if v == self then
key = k
end
end
self.OnClick = function(object)
local descending = object.descending
local parent = object.parent
local pinternals = parent.internals
local list = pinternals[1]
if descending then
object.descending = false
else
object.descending = true
end
list:Sort(key, object.descending)
end
-- apply template properties to the object
loveframes.ApplyTemplatesToObject(self)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
if not self.visible then
if not self.alwaysupdate then
return
end
end
local update = self.Update
local parent = self.parent
local list = parent.internals[1]
local vbody = list:GetVerticalScrollBody()
local width = list.width
if vbody then
width = width - vbody.width
end
self.clickbounds = {x = list.x, y = list.y, width = width, height = list.height}
self:CheckHover()
if not self.hover then
self.down = false
else
if loveframes.downobject == self then
self.down = true
end
end
-- move to parent if there is a parent
if parent ~= loveframes.base then
self.x = (parent.x + self.staticx) - parent.internals[1].offsetx
self.y = parent.y + self.staticy
end
local resizecolumn = parent.resizecolumn
if resizecolumn and resizecolumn == self then
local x, y = love.mouse.getPosition()
local start = false
self.width = x - self.x
if self.width < 20 then
self.width = 20
end
parent.startadjustment = true
parent.internals[1]:CalculateSize()
parent.internals[1]:RedoLayout()
elseif resizecolumn and parent.startadjustment then
local header = parent.children[self.columnid - 1]
self.staticx = header.staticx + header.width
end
self.resizebox = {x = self.x + (self.width - 2), y = self.y, width = 4, height = self.height}
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
if not self.parent.resizecolumn and self.parent.canresizecolumns then
local box = self.resizebox
local col = loveframes.BoundingBox(x, box.x, y, box.y, 1, box.width, 1, box.height)
if col then
self.resizing = true
self.parent.resizecolumn = self
end
end
if self.hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" and button == 1 then
baseparent:MakeTop()
end
self.down = true
loveframes.downobject = self
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
if not self.visible then
return
end
local hover = self.hover
local down = self.down
local clickable = self.clickable
local enabled = self.enabled
local onclick = self.OnClick
if hover and down and clickable and button == 1 then
if enabled then
onclick(self, x, y)
end
end
local resizecolumn = self.parent.resizecolumn
if resizecolumn and resizecolumn == self then
self.parent.resizecolumn = nil
end
self.down = false
end
--[[---------------------------------------------------------
- func: SetName(name)
- desc: sets the object's name
--]]---------------------------------------------------------
function newobject:SetName(name)
self.name = name
return self
end
--[[---------------------------------------------------------
- func: GetName()
- desc: gets the object's name
--]]---------------------------------------------------------
function newobject:GetName()
return self.name
end
---------- module end ----------
end

View File

@ -0,0 +1,218 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- columnlistrow class
local newobject = loveframes.NewObject("columnlistrow", "loveframes_object_columnlistrow", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: intializes the element
--]]---------------------------------------------------------
function newobject:initialize(parent, data)
self.type = "columnlistrow"
self.parent = parent
self.state = parent.state
self.colorindex = self.parent.rowcolorindex
self.font = loveframes.basicfontsmall
self.width = 80
self.height = 25
self.textx = 5
self.texty = 5
self.selected = false
self.internal = true
self.columndata = {}
for k, v in ipairs(data) do
self.columndata[k] = tostring(v)
end
-- apply template properties to the object
loveframes.ApplyTemplatesToObject(self)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
if not self.visible then
if not self.alwaysupdate then
return
end
end
local parent = self.parent
local update = self.Update
self:CheckHover()
-- move to parent if there is a parent
if parent ~= loveframes.base then
self.x = parent.x + self.staticx
self.y = parent.y + self.staticy
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
if not self.visible then
return
end
if self.hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
self:GetParent():GetParent():SelectRow(self, loveframes.IsCtrlDown())
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
if not self.visible then
return
end
if self.hover then
local parent = self:GetParent():GetParent()
if button == 1 then
local onrowclicked = parent.OnRowClicked
if onrowclicked then
onrowclicked(parent, self, self.columndata)
end
elseif button == 2 then
local onrowrightclicked = parent.OnRowRightClicked
if onrowrightclicked then
onrowrightclicked(parent, self, self.columndata)
end
end
end
end
--[[---------------------------------------------------------
- func: SetTextPos(x, y)
- desc: sets the positions of the object's text
--]]---------------------------------------------------------
function newobject:SetTextPos(x, y)
self.textx = x
self.texty = y
end
--[[---------------------------------------------------------
- func: GetTextX()
- desc: gets the object's text x position
--]]---------------------------------------------------------
function newobject:GetTextX()
return self.textx
end
--[[---------------------------------------------------------
- func: GetTextY()
- desc: gets the object's text y position
--]]---------------------------------------------------------
function newobject:GetTextY()
return self.texty
end
--[[---------------------------------------------------------
- func: SetFont(font)
- desc: sets the object's font
--]]---------------------------------------------------------
function newobject:SetFont(font)
self.font = font
end
--[[---------------------------------------------------------
- func: GetFont()
- desc: gets the object's font
--]]---------------------------------------------------------
function newobject:GetFont()
return self.font
end
--[[---------------------------------------------------------
- func: GetColorIndex()
- desc: gets the object's color index
--]]---------------------------------------------------------
function newobject:GetColorIndex()
return self.colorindex
end
--[[---------------------------------------------------------
- func: SetColumnData(data)
- desc: sets the object's column data
--]]---------------------------------------------------------
function newobject:SetColumnData(data)
self.columndata = data
end
--[[---------------------------------------------------------
- func: GetColumnData()
- desc: gets the object's column data
--]]---------------------------------------------------------
function newobject:GetColumnData()
return self.columndata
end
--[[---------------------------------------------------------
- func: SetSelected(selected)
- desc: sets whether or not the object is selected
--]]---------------------------------------------------------
function newobject:SetSelected(selected)
self.selected = true
end
--[[---------------------------------------------------------
- func: GetSelected()
- desc: gets whether or not the object is selected
--]]---------------------------------------------------------
function newobject:GetSelected()
return self.selected
end
---------- module end ----------
end

View File

@ -0,0 +1,161 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- linenumberspanel class
local newobject = loveframes.NewObject("linenumberspanel", "loveframes_object_linenumberspanel", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize(parent)
self.parent = parent
self.type = "linenumberspanel"
self.width = 5
self.height = 5
self.offsety = 0
self.staticx = 0
self.staticy = 0
self.internal = true
-- apply template properties to the object
loveframes.ApplyTemplatesToObject(self)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the element
--]]---------------------------------------------------------
function newobject:update(dt)
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
local parent = self.parent
local base = loveframes.base
local update = self.Update
local height = self.parent.height
local parentinternals = parent.internals
self.height = height
self.offsety = self.parent.offsety - self.parent.textoffsety
-- move to parent if there is a parent
if parent ~= base then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
if parentinternals[1] ~= self then
self:Remove()
table.insert(parentinternals, 1, self)
return
end
self:CheckHover()
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: draw()
- desc: draws the object
--]]---------------------------------------------------------
function newobject:draw()
if loveframes.state ~= self.state then
return
end
if not self.visible then
return
end
local x = self.x
local y = self.y
local width = self.width
local height = self.height
local stencilfunc = function() love.graphics.rectangle("fill", self.parent.x, self.parent.y, width, height) end
if self.parent.hbar then
stencilfunc = function() love.graphics.rectangle("fill", self.parent.x, self.parent.y, self.width, self.parent.height - 16) end
end
self:SetDrawOrder()
love.graphics.stencil(stencilfunc)
love.graphics.setStencilTest("greater", 0)
local drawfunc = self.Draw or self.drawfunc
if drawfunc then
drawfunc(self)
end
love.graphics.setStencilTest()
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local visible = self.visible
if not visible then
return
end
local hover = self.hover
if hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local visible = self.visible
if not visible then
return
end
end
--[[---------------------------------------------------------
- func: GetOffsetY()
- desc: gets the object's y offset
--]]---------------------------------------------------------
function newobject:GetOffsetY()
return self.offsety
end
---------- module end ----------
end

View File

@ -0,0 +1,218 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- menuoption object
local newobject = loveframes.NewObject("menuoption", "loveframes_object_menuoption", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize(parent, option_type, menu)
self.type = "menuoption"
self.text = "Option"
self.width = 100
self.height = 25
self.contentwidth = 0
self.contentheight = 0
self.parent = parent
self.option_type = option_type or "option"
self.menu = menu
self.activated = false
self.internal = true
self.icon = false
self.func = nil
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
self:CheckHover()
local hover = self.hover
local parent = self.parent
local option_type = self.option_type
local activated = self.activated
local base = loveframes.base
local update = self.Update
if option_type == "submenu_activator" then
if hover and not activated then
self.menu:SetVisible(true)
self.menu:MoveToTop()
self.activated = true
elseif not hover and activated then
local hoverobject = loveframes.hoverobject
if hoverobject and hoverobject:GetBaseParent() == self.parent then
self.menu:SetVisible(false)
self.activated = false
end
elseif activated then
local screen_width = love.graphics.getWidth()
local screen_height = love.graphics.getHeight()
local sx = self.x
local sy = self.y
local width = self.width
local height = self.height
local x1 = sx + width
if x1 + self.menu.width <= screen_width then
self.menu.x = x1
else
self.menu.x = sx - self.menu.width
end
if sy + self.menu.height <= screen_height then
self.menu.y = sy
else
self.menu.y = (sy + height) - self.menu.height
end
end
end
-- move to parent if there is a parent
if parent ~= base then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local hover = self.hover
local option_type = self.option_type
if hover and option_type ~= "divider" and button == 1 then
local func = self.func
if func then
local text = self.text
func(self, text)
end
local basemenu = self.parent:GetBaseMenu()
basemenu:SetVisible(false)
end
end
--[[---------------------------------------------------------
- func: SetText(text)
- desc: sets the object's text
--]]---------------------------------------------------------
function newobject:SetText(text)
self.text = text
end
--[[---------------------------------------------------------
- func: GetText()
- desc: gets the object's text
--]]---------------------------------------------------------
function newobject:GetText()
return self.text
end
--[[---------------------------------------------------------
- func: SetIcon(icon)
- desc: sets the object's icon
--]]---------------------------------------------------------
function newobject:SetIcon(icon)
if type(icon) == "string" then
self.icon = love.graphics.newImage(icon)
self.icon:setFilter("nearest", "nearest")
elseif type(icon) == "userdata" then
self.icon = icon
end
end
--[[---------------------------------------------------------
- func: GetIcon()
- desc: gets the object's icon
--]]---------------------------------------------------------
function newobject:GetIcon()
return self.icon
end
--[[---------------------------------------------------------
- func: SetFunction(func)
- desc: sets the object's function
--]]---------------------------------------------------------
function newobject:SetFunction(func)
self.func = func
end
---------- module end ----------
end

View File

@ -0,0 +1,79 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- modalbackground class
local newobject = loveframes.NewObject("modalbackground", "loveframes_object_modalbackground", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize(object)
self.type = "modalbackground"
self.width = love.graphics.getWidth()
self.height = love.graphics.getHeight()
self.x = 0
self.y = 0
self.internal = true
self.parent = loveframes.base
self.object = object
table.insert(loveframes.base.children, self)
if self.object.type ~= "frame" then
self:Remove()
end
-- apply template properties to the object
loveframes.ApplyTemplatesToObject(self)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the element
--]]---------------------------------------------------------
function newobject:update(dt)
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
local object = self.object
local update = self.Update
local base = loveframes.base
local basechildren = base.children
self:CheckHover()
if #basechildren > 1 then
if basechildren[#basechildren - 1] ~= self then
self:Remove()
table.insert(basechildren, self)
end
end
if not object:IsActive() then
self:Remove()
loveframes.modalobject = false
end
if update then
update(self, dt)
end
end
---------- module end ----------
end

View File

@ -0,0 +1,420 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- multichoicelist class
local newobject = loveframes.NewObject("multichoicelist", "loveframes_object_multichoicelist", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize(object)
self.type = "multichoicelist"
self.parent = loveframes.base
self.list = object
self.x = object.x
self.y = object.y + self.list.height
self.width = self.list.width
self.height = 0
self.clickx = 0
self.clicky = 0
self.padding = self.list.listpadding
self.spacing = self.list.listspacing
self.buttonscrollamount = object.buttonscrollamount
self.mousewheelscrollamount = object.mousewheelscrollamount
self.offsety = 0
self.offsetx = 0
self.extrawidth = 0
self.extraheight = 0
self.canremove = false
self.dtscrolling = self.list.dtscrolling
self.internal = true
self.vbar = false
self.children = {}
self.internals = {}
for k, v in ipairs(object.choices) do
local row = loveframes.objects["multichoicerow"]:new()
row:SetText(v)
self:AddItem(row)
end
table.insert(loveframes.base.internals, self)
-- apply template properties to the object
loveframes.ApplyTemplatesToObject(self)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
local width = love.graphics.getWidth()
local height = love.graphics.getHeight()
local x, y = love.mouse.getPosition()
local selfcol = loveframes.BoundingBox(x, self.x, y, self.y, 1, self.width, 1, self.height)
local parent = self.parent
local base = loveframes.base
local upadte = self.Update
local internals = self.internals
local children = self.children
-- move to parent if there is a parent
if parent ~= base then
self.x = parent.x + self.staticx
self.y = parent.y + self.staticy
end
if self.x < 0 then
self.x = 0
end
if self.x + self.width > width then
self.x = width - self.width
end
if self.y < 0 then
self.y = 0
end
if self.y + self.height > height then
self.y = height - self.height
end
for k, v in ipairs(internals) do
v:update(dt)
end
for k, v in ipairs(children) do
v:update(dt)
v:SetClickBounds(self.x, self.y, self.width, self.height)
v.y = (v.parent.y + v.staticy) - self.offsety
v.x = (v.parent.x + v.staticx) - self.offsetx
end
if upadte then
upadte(self, dt)
end
end
--[[---------------------------------------------------------
- func: draw()
- desc: draws the object
--]]---------------------------------------------------------
--[[
function newobject:draw()
if loveframes.state ~= self.state then
return
end
if not self.visible then
return
end
self:SetDrawOrder()
local drawfunc = self.Draw or self.drawfunc
if drawfunc then
drawfunc(self)
end
local internals = self.internals
if internals then
for k, v in ipairs(internals) do
v:draw()
end
end
love.graphics.stencil(stencilfunc)
love.graphics.setStencilTest("greater", 0)
local children = self.children
if children then
for k, v in ipairs(children) do
local col = loveframes.BoundingBox(self.x, v.x, self.y, v.y, self.width, v.width, self.height, v.height)
if col then
v:draw()
end
end
end
love.graphics.setStencilTest()
drawfunc = self.DrawOver or self.drawoverfunc
if drawfunc then
drawfunc(self)
end
end
--]]
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local selfcol = loveframes.BoundingBox(x, self.x, y, self.y, 1, self.width, 1, self.height)
local internals = self.internals
local children = self.children
if not selfcol and self.canremove and button == 1 then
self:Close()
end
for k, v in ipairs(internals) do
v:mousepressed(x, y, button)
end
for k, v in ipairs(children) do
v:mousepressed(x, y, button)
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local internals = self.internals
local children = self.children
self.canremove = true
for k, v in ipairs(internals) do
v:mousereleased(x, y, button)
end
for k, v in ipairs(children) do
v:mousereleased(x, y, button)
end
end
--[[---------------------------------------------------------
- func: wheelmoved(x, y)
- desc: called when the player moves a mouse wheel
--]]---------------------------------------------------------
function newobject:wheelmoved(x, y)
local toplist = self:IsTopList()
local internals = self.internals
local scrollamount = self.mousewheelscrollamount
if self.vbar and toplist then
local bar = internals[1].internals[1].internals[1]
local dtscrolling = self.dtscrolling
if dtscrolling then
local dt = love.timer.getDelta()
bar:Scroll(-y * scrollamount * dt)
else
bar:Scroll(-y * scrollamount)
end
end
end
--[[---------------------------------------------------------
- func: AddItem(object)
- desc: adds an item to the object
--]]---------------------------------------------------------
function newobject:AddItem(object)
if object.type ~= "multichoicerow" then
return
end
object.parent = self
table.insert(self.children, object)
self:CalculateSize()
self:RedoLayout()
end
--[[---------------------------------------------------------
- func: RemoveItem(object)
- desc: removes an item from the object
--]]---------------------------------------------------------
function newobject:RemoveItem(object)
local children = self.children
for k, v in ipairs(children) do
if v == object then
table.remove(children, k)
end
end
self:CalculateSize()
self:RedoLayout()
end
--[[---------------------------------------------------------
- func: CalculateSize()
- desc: calculates the size of the object's children
--]]---------------------------------------------------------
function newobject:CalculateSize()
self.height = self.padding
if self.list.listheight then
self.height = self.list.listheight
else
for k, v in ipairs(self.children) do
self.height = self.height + (v.height + self.spacing)
end
end
if self.height > love.graphics.getHeight() then
self.height = love.graphics.getHeight()
end
local numitems = #self.children
local height = self.height
local padding = self.padding
local spacing = self.spacing
local itemheight = self.padding
local vbar = self.vbar
local children = self.children
for k, v in ipairs(children) do
itemheight = itemheight + v.height + spacing
end
self.itemheight = (itemheight - spacing) + padding
if self.itemheight > height then
self.extraheight = self.itemheight - height
if not vbar then
local scroll = loveframes.objects["scrollbody"]:new(self, "vertical")
table.insert(self.internals, scroll)
self.vbar = true
end
else
if vbar then
self.internals[1]:Remove()
self.vbar = false
self.offsety = 0
end
end
end
--[[---------------------------------------------------------
- func: RedoLayout()
- desc: used to redo the layour of the object
--]]---------------------------------------------------------
function newobject:RedoLayout()
local children = self.children
local padding = self.padding
local spacing = self.spacing
local starty = padding
local vbar = self.vbar
if #children > 0 then
for k, v in ipairs(children) do
v.staticx = padding
v.staticy = starty
if vbar then
v.width = (self.width - self.internals[1].width) - padding * 2
self.internals[1].staticx = self.width - self.internals[1].width
self.internals[1].height = self.height
else
v.width = self.width - padding * 2
end
starty = starty + v.height
starty = starty + spacing
end
end
end
--[[---------------------------------------------------------
- func: SetPadding(amount)
- desc: sets the object's padding
--]]---------------------------------------------------------
function newobject:SetPadding(amount)
self.padding = amount
end
--[[---------------------------------------------------------
- func: SetSpacing(amount)
- desc: sets the object's spacing
--]]---------------------------------------------------------
function newobject:SetSpacing(amount)
self.spacing = amount
end
--[[---------------------------------------------------------
- func: Close()
- desc: closes the object
--]]---------------------------------------------------------
function newobject:Close()
self:Remove()
self.list.haslist = false
end
---------- module end ----------
end

View File

@ -0,0 +1,157 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- multichoicerow class
local newobject = loveframes.NewObject("multichoicerow", "loveframes_object_multichoicerow", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "multichoicerow"
self.text = ""
self.width = 50
self.height = 25
self.hover = false
self.internal = true
self.down = false
self.canclick = false
-- apply template properties to the object
loveframes.ApplyTemplatesToObject(self)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
local parent = self.parent
local base = loveframes.base
local update = self.Update
self:CheckHover()
if not self.hover then
self.down = false
else
if loveframes.downobject == self then
self.down = true
end
end
if not self.down and loveframes.downobject == self then
self.hover = true
end
-- move to parent if there is a parent
if parent ~= base then
self.x = parent.x + self.staticx
self.y = parent.y + self.staticy
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local visible = self.visible
if not visible then
return
end
local hover = self.hover
if hover and button == 1 then
self.down = true
loveframes.downobject = self
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local visible = self.visible
if not visible then
return
end
local text = self.text
if self.hover and self.down and self.canclick and button == 1 then
self.parent.list:SelectChoice(text)
end
self.down = false
self.canclick = true
end
--[[---------------------------------------------------------
- func: keypressed(key, isrepeat)
- desc: called when the player presses a key
--]]---------------------------------------------------------
function newobject:keypressed(key, isrepeat)
local text = self.text
local selectedobject = loveframes.selectedobject
if key == "return" and selectedobject == self then
self.parent.list:SelectChoice(text)
end
end
--[[---------------------------------------------------------
- func: SetText(text)
- desc: sets the object's text
--]]---------------------------------------------------------
function newobject:SetText(text)
self.text = text
end
--[[---------------------------------------------------------
- func: GetText()
- desc: gets the object's text
--]]---------------------------------------------------------
function newobject:GetText()
return self.text
end
---------- module end ----------
end

View File

@ -0,0 +1,204 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- scrollarea class
local newobject = loveframes.NewObject("scrollarea", "loveframes_object_scrollarea", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize(parent, bartype)
self.type = "scroll-area"
self.bartype = bartype
self.parent = parent
self.x = 0
self.y = 0
self.scrolldelay = 0
self.delayamount = 0.05
self.down = false
self.internal = true
self.internals = {}
table.insert(self.internals, loveframes.objects["scrollbar"]:new(self, bartype))
-- apply template properties to the object
loveframes.ApplyTemplatesToObject(self)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
self:CheckHover()
local base = loveframes.base
local parent = self.parent
local pinternals = parent.internals
local button = pinternals[2]
local bartype = self.bartype
local time = love.timer.getTime()
local x, y = love.mouse.getPosition()
local listo = parent.parent
local down = self.down
local scrolldelay = self.scrolldelay
local delayamount = self.delayamount
local internals = self.internals
local bar = internals[1]
local hover = self.hover
local update = self.Update
if button then
if bartype == "vertical" then
self.staticx = 0
self.staticy = button.height - 1
self.width = parent.width
self.height = parent.height - button.height*2 + 2
elseif bartype == "horizontal" then
self.staticx = button.width - 1
self.staticy = 0
self.width = parent.width - button.width*2 + 2
self.height = parent.height
end
end
-- move to parent if there is a parent
if parent ~= base then
self.x = parent.x + self.staticx
self.y = parent.y + self.staticy
end
if down then
if scrolldelay < time then
self.scrolldelay = time + delayamount
if self.bartype == "vertical" then
if y > bar.y then
bar:Scroll(bar.height)
else
bar:Scroll(-bar.height)
end
elseif self.bartype == "horizontal" then
if x > bar.x then
bar:Scroll(bar.width)
else
bar:Scroll(-bar.width)
end
end
end
if not hover then
self.down = false
end
end
for k, v in ipairs(internals) do
v:update(dt)
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local visible = self.visible
if not visible then
return
end
local listo = self.parent.parent
local time = love.timer.getTime()
local internals = self.internals
local bar = internals[1]
local hover = self.hover
local delayamount = self.delayamount
if hover and button == 1 then
self.down = true
self.scrolldelay = time + delayamount + 0.5
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
if self.bartype == "vertical" then
if y > self.internals[1].y then
bar:Scroll(bar.height)
else
bar:Scroll(-bar.height)
end
elseif self.bartype == "horizontal" then
if x > bar.x then
bar:Scroll(bar.width)
else
bar:Scroll(-bar.width)
end
end
loveframes.downobject = self
end
for k, v in ipairs(internals) do
v:mousepressed(x, y, button)
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local visible = self.visible
if not visible then
return
end
local internals = self.internals
if button == 1 then
self.down = false
end
for k, v in ipairs(internals) do
v:mousereleased(x, y, button)
end
end
--[[---------------------------------------------------------
- func: GetBarType()
- desc: gets the object's bar type
--]]---------------------------------------------------------
function newobject:GetBarType()
return self.bartype
end
---------- module end ----------
end

View File

@ -0,0 +1,358 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- scrollbar class
local newobject = loveframes.NewObject("scrollbar", "loveframes_object_scrollbar", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize(parent, bartype)
self.type = "scrollbar"
self.bartype = bartype
self.parent = parent
self.x = 0
self.y = 0
self.staticx = 0
self.staticy = 0
self.maxx = 0
self.maxy = 0
self.clickx = 0
self.clicky = 0
self.starty = 0
self.lastwidth = 0
self.lastheight = 0
self.lastx = 0
self.lasty = 0
self.internal = true
self.hover = false
self.dragging = false
self.autoscroll = false
self.internal = true
if self.bartype == "vertical" then
self.width = self.parent.width
self.height = 5
elseif self.bartype == "horizontal" then
self.width = 5
self.height = self.parent.height
end
-- apply template properties to the object
loveframes.ApplyTemplatesToObject(self)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
self:CheckHover()
local x, y = love.mouse.getPosition()
local bartype = self.bartype
local cols = {}
local basecols = {}
local dragging = self.dragging
if bartype == "vertical" then
self.width = self.parent.width
elseif bartype == "horizontal" then
self.height = self.parent.height
end
if bartype == "vertical" then
local parent = self.parent
local listo = parent.parent.parent
local height = parent.height * (listo.height/listo.itemheight)
if height < 20 then
self.height = 20
else
self.height = height
end
self.maxy = parent.y + (parent.height - self.height)
self.x = parent.x + parent.width - self.width
self.y = parent.y + self.staticy
if dragging then
if self.staticy ~= self.lasty then
if listo.OnScroll then
listo.OnScroll(listo)
end
self.lasty = self.staticy
end
self.staticy = self.starty + (y - self.clicky)
end
local space = (self.maxy - parent.y)
local remaining = (0 + self.staticy)
local percent = remaining/space
local extra = listo.extraheight * percent
local autoscroll = self.autoscroll
local lastheight = self.lastheight
listo.offsety = 0 + extra
if self.staticy > space then
self.staticy = space
listo.offsety = listo.extraheight
end
if self.staticy < 0 then
self.staticy = 0
listo.offsety = 0
end
if autoscroll then
if listo.itemheight > lastheight then
local type = listo.type
self.lastheight = listo.itemheight
if type == "textinput" then
local indicatory = listo.indicatory
local font = listo.font
local theight = font:getHeight("a")
local y = listo.y
local height = listo.height
local linecount = #listo.lines
local parentheight = self.parent.height
if (indicatory + theight) > (y + height) then
self:Scroll(parentheight/linecount)
end
else
local maxy = self.maxy
self:Scroll(maxy)
end
end
end
elseif bartype == "horizontal" then
local parent = self.parent
local listo = self.parent.parent.parent
local width = self.parent.width * (listo.width/listo.itemwidth)
if width < 20 then
self.width = 20
else
self.width = width
end
self.maxx = parent.x + (parent.width) - self.width
self.x = parent.x + self.staticx
self.y = parent.y + self.staticy
if dragging then
if self.staticx ~= self.lastx then
if listo.OnScroll then
listo.OnScroll(listo)
end
self.lastx = self.staticx
end
self.staticx = self.startx + (x - self.clickx)
end
local space = (self.maxx - parent.x)
local remaining = (0 + self.staticx)
local percent = remaining/space
local extra = listo.extrawidth * percent
local autoscroll = self.autoscroll
local lastwidth = self.lastwidth
listo.offsetx = 0 + extra
if self.staticx > space then
self.staticx = space
listo.offsetx = listo.extrawidth
end
if self.staticx < 0 then
self.staticx = 0
listo.offsetx = 0
end
if autoscroll then
if listo.itemwidth > lastwidth then
self.lastwidth = listo.itemwidth
self:Scroll(self.maxx)
end
end
end
local update = self.Update
if update then update(self, dt) end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local visible = self.visible
local hover = self.hover
if not visible then
return
end
if not hover then
return
end
local baseparent = self:GetBaseParent()
if baseparent.type == "frame" then
baseparent:MakeTop()
end
local dragging = self.dragging
if not dragging then
if button == 1 then
self.starty = self.staticy
self.startx = self.staticx
self.clickx = x
self.clicky = y
self.dragging = true
loveframes.downobject = self
end
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local visible = self.visible
if not visible then
return
end
if self.dragging then
self.dragging = false
end
end
--[[---------------------------------------------------------
- func: SetMaxX(x)
- desc: sets the object's max x position
--]]---------------------------------------------------------
function newobject:SetMaxX(x)
self.maxx = x
end
--[[---------------------------------------------------------
- func: SetMaxY(y)
- desc: sets the object's max y position
--]]---------------------------------------------------------
function newobject:SetMaxY(y)
self.maxy = y
end
--[[---------------------------------------------------------
- func: Scroll(amount)
- desc: scrolls the object
--]]---------------------------------------------------------
function newobject:Scroll(amount)
local bartype = self.bartype
local listo = self.parent.parent.parent
local onscroll = listo.OnScroll
if bartype == "vertical" then
local newy = (self.y + amount)
if newy > self.maxy then
self.staticy = self.maxy - self.parent.y
elseif newy < self.parent.y then
self.staticy = 0
else
self.staticy = self.staticy + amount
end
elseif bartype == "horizontal" then
local newx = (self.x + amount)
if newx > self.maxx then
self.staticx = self.maxx - self.parent.x
elseif newx < self.parent.x then
self.staticx = 0
else
self.staticx = self.staticx + amount
end
end
if onscroll then
onscroll(listo)
end
end
--[[---------------------------------------------------------
- func: ScrollTo(position)
- desc: scrolls the object
--]]---------------------------------------------------------
function newobject:ScrollTo(position)
local bartype = self.bartype
local listo = self.parent.parent.parent
local onscroll = listo.OnScroll
if bartype == "vertical" then
local maxRealPos = self.parent.height - self.height
if position > 1 then
self.staticy = maxRealPos
elseif position < 0 then
self.staticy = 0
else
self.staticy = position * maxRealPos
end
elseif bartype == "horizontal" then
local maxRealPos = self.parent.width - self.width
if position > 1 then
self.staticx = maxRealPos
elseif position < 0 then
self.staticx = 0
else
self.staticx = position * maxRealPos
end
end
if onscroll then
onscroll(listo)
end
end
--[[---------------------------------------------------------
- func: IsDragging()
- desc: gets whether the object is being dragged or not
--]]---------------------------------------------------------
function newobject:IsDragging()
return self.dragging
end
--[[---------------------------------------------------------
- func: GetBarType()
- desc: gets the object's bartype
--]]---------------------------------------------------------
function newobject:GetBarType()
return self.bartype
end
---------- module end ----------
end

View File

@ -0,0 +1,192 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- scrollbar class
local newobject = loveframes.NewObject("scrollbody", "loveframes_object_scrollbody", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize(parent, bartype)
self.type = "scrollbody"
self.bartype = bartype
self.parent = parent
self.x = 0
self.y = 0
self.internal = true
self.internals = {}
if self.bartype == "vertical" then
self.width = 16
self.height = self.parent.height
self.staticx = self.parent.width - self.width
self.staticy = 0
elseif self.bartype == "horizontal" then
self.width = self.parent.width
self.height = 16
self.staticx = 0
self.staticy = self.parent.height - self.height
end
table.insert(self.internals, loveframes.objects["scrollarea"]:new(self, bartype))
local bar = self.internals[1].internals[1]
if self.bartype == "vertical" then
local upbutton = loveframes.objects["scrollbutton"]:new("up")
upbutton.staticx = 0 + self.width - upbutton.width
upbutton.staticy = 0
upbutton.parent = self
upbutton.Update = function(object, dt)
upbutton.staticx = 0 + self.width - upbutton.width
upbutton.staticy = 0
if object.down and object.hover then
local dtscrolling = self.parent.dtscrolling
if dtscrolling then
local dt = love.timer.getDelta()
bar:Scroll(-self.parent.buttonscrollamount * dt)
else
bar:Scroll(-self.parent.buttonscrollamount)
end
end
end
local downbutton = loveframes.objects["scrollbutton"]:new("down")
downbutton.parent = self
downbutton.staticx = 0 + self.width - downbutton.width
downbutton.staticy = 0 + self.height - downbutton.height
downbutton.Update = function(object, dt)
downbutton.staticx = 0 + self.width - downbutton.width
downbutton.staticy = 0 + self.height - downbutton.height
downbutton.x = downbutton.parent.x + downbutton.staticx
downbutton.y = downbutton.parent.y + downbutton.staticy
if object.down and object.hover then
local dtscrolling = self.parent.dtscrolling
if dtscrolling then
local dt = love.timer.getDelta()
bar:Scroll(self.parent.buttonscrollamount * dt)
else
bar:Scroll(self.parent.buttonscrollamount)
end
end
end
table.insert(self.internals, upbutton)
table.insert(self.internals, downbutton)
elseif self.bartype == "horizontal" then
local leftbutton = loveframes.objects["scrollbutton"]:new("left")
leftbutton.parent = self
leftbutton.staticx = 0
leftbutton.staticy = 0
leftbutton.Update = function(object, dt)
leftbutton.staticx = 0
leftbutton.staticy = 0
if object.down and object.hover then
local dtscrolling = self.parent.dtscrolling
if dtscrolling then
local dt = love.timer.getDelta()
bar:Scroll(-self.parent.buttonscrollamount * dt)
else
bar:Scroll(-self.parent.buttonscrollamount)
end
end
end
local rightbutton = loveframes.objects["scrollbutton"]:new("right")
rightbutton.parent = self
rightbutton.staticx = 0 + self.width - rightbutton.width
rightbutton.staticy = 0
rightbutton.Update = function(object, dt)
rightbutton.staticx = 0 + self.width - rightbutton.width
rightbutton.staticy = 0
rightbutton.x = rightbutton.parent.x + rightbutton.staticx
rightbutton.y = rightbutton.parent.y + rightbutton.staticy
if object.down and object.hover then
local dtscrolling = self.parent.dtscrolling
if dtscrolling then
local dt = love.timer.getDelta()
bar:Scroll(self.parent.buttonscrollamount * dt)
else
bar:Scroll(self.parent.buttonscrollamount)
end
end
end
table.insert(self.internals, leftbutton)
table.insert(self.internals, rightbutton)
end
local parentstate = parent.state
self:SetState(parentstate)
-- apply template properties to the object
loveframes.ApplyTemplatesToObject(self)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
self:CheckHover()
local parent = self.parent
local base = loveframes.base
local update = self.Update
local internals = self.internals
-- move to parent if there is a parent
if parent ~= base then
self.x = parent.x + self.staticx
self.y = parent.y + self.staticy
end
-- resize to parent
if parent ~= base then
if self.bartype == "vertical" then
self.height = self.parent.height
self.staticx = self.parent.width - self.width
if parent.hbar then self.height = self.height - parent:GetHorizontalScrollBody().height end
elseif self.bartype == "horizontal" then
self.width = self.parent.width
self.staticy = self.parent.height - self.height
if parent.vbar then self.width = self.width - parent:GetVerticalScrollBody().width end
end
end
for k, v in ipairs(internals) do
v:update(dt)
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: GetScrollBar()
- desc: gets the object's scroll bar
--]]---------------------------------------------------------
function newobject:GetScrollBar()
return self.internals[1].internals[1]
end
---------- module end ----------
end

View File

@ -0,0 +1,139 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- scrollbutton clas
local newobject = loveframes.NewObject("scrollbutton", "loveframes_object_scrollbutton", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize(scrolltype)
self.type = "scrollbutton"
self.scrolltype = scrolltype
self.width = 16
self.height = 16
self.down = false
self.internal = true
self.OnClick = function() end
-- apply template properties to the object
loveframes.ApplyTemplatesToObject(self)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
self:CheckHover()
local hover = self.hover
local parent = self.parent
local base = loveframes.base
local update = self.Update
if not hover then
self.down = false
else
if loveframes.downobject == self then
self.down = true
end
end
if not self.down and loveframes.downobject == self then
self.hover = true
end
-- move to parent if there is a parent
if parent ~= base then
self.x = parent.x + self.staticx
self.y = parent.y + self.staticy
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local visible = self.visible
if not visible then
return
end
local hover = self.hover
if hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent.type == "frame" then
baseparent:MakeTop()
end
self.down = true
loveframes.downobject = self
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local visible = self.visible
if not visible then
return
end
local hover = self.hover
local down = self.down
local onclick = self.OnClick
if hover and down then
if button == 1 then
onclick(x, y, self)
end
end
self.down = false
end
--[[---------------------------------------------------------
- func: GetScrollType()
- desc: gets the object's scroll type
--]]---------------------------------------------------------
function newobject:GetScrollType()
return self.scrolltype
end
---------- module end ----------
end

View File

@ -0,0 +1,228 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- sliderbutton class
local newobject = loveframes.NewObject("sliderbutton", "loveframes_object_sliderbutton", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize(parent)
self.type = "sliderbutton"
self.width = 10
self.height = 20
self.staticx = 0
self.staticy = 0
self.startx = 0
self.clickx = 0
self.starty = 0
self.clicky = 0
self.intervals = true
self.internal = true
self.down = false
self.dragging = false
self.parent = parent
-- apply template properties to the object
loveframes.ApplyTemplatesToObject(self)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
self:CheckHover()
local x, y = love.mouse.getPosition()
local intervals = self.intervals
local progress = 0
local nvalue = 0
local pvalue = self.parent.value
local hover = self.hover
local down = self.down
local downobject = loveframes.downobject
local parent = self.parent
local slidetype = parent.slidetype
local dragging = self.dragging
local base = loveframes.base
local update = self.Update
if not hover then
self.down = false
if downobject == self then
self.hover = true
end
else
if downobject == self then
self.down = true
end
end
if not down and downobject == self then
self.hover = true
end
-- move to parent if there is a parent
if parent ~= base then
self.x = parent.x + self.staticx
self.y = parent.y + self.staticy
end
-- start calculations if the button is being dragged
if dragging then
-- calculations for horizontal sliders
if slidetype == "horizontal" then
self.staticx = self.startx + (x - self.clickx)
progress = self.staticx/(self.parent.width - self.width)
nvalue = self.parent.min + (self.parent.max - self.parent.min) * progress
nvalue = loveframes.Round(nvalue, self.parent.decimals)
-- calculations for vertical sliders
elseif slidetype == "vertical" then
self.staticy = self.starty + (y - self.clicky)
local space = self.parent.height - self.height
local remaining = (self.parent.height - self.height) - self.staticy
local percent = remaining/space
nvalue = self.parent.min + (self.parent.max - self.parent.min) * percent
nvalue = loveframes.Round(nvalue, self.parent.decimals)
end
if nvalue > self.parent.max then
nvalue = self.parent.max
end
if nvalue < self.parent.min then
nvalue = self.parent.min
end
self.parent.value = nvalue
if self.parent.value == -0 then
self.parent.value = math.abs(self.parent.value)
end
if nvalue ~= pvalue and nvalue >= self.parent.min and nvalue <= self.parent.max then
if self.parent.OnValueChanged then
self.parent.OnValueChanged(self.parent, self.parent.value)
end
end
loveframes.downobject = self
end
if slidetype == "horizontal" then
if (self.staticx + self.width) > self.parent.width then
self.staticx = self.parent.width - self.width
end
if self.staticx < 0 then
self.staticx = 0
end
end
if slidetype == "vertical" then
if (self.staticy + self.height) > self.parent.height then
self.staticy = self.parent.height - self.height
end
if self.staticy < 0 then
self.staticy = 0
end
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local visible = self.visible
if not visible then
return
end
local hover = self.hover
if hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
self.down = true
self.dragging = true
self.startx = self.staticx
self.clickx = x
self.starty = self.staticy
self.clicky = y
loveframes.downobject = self
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local visible = self.visible
if not visible then
return
end
local down = self.down
local dragging = self.dragging
if dragging then
local parent = self.parent
local onrelease = parent.OnRelease
if onrelease then
onrelease(parent)
end
end
self.down = false
self.dragging = false
end
--[[---------------------------------------------------------
- func: MoveToX(x)
- desc: moves the object to the specified x position
--]]---------------------------------------------------------
function newobject:MoveToX(x)
self.staticx = x
end
--[[---------------------------------------------------------
- func: MoveToY(y)
- desc: moves the object to the specified y position
--]]---------------------------------------------------------
function newobject:MoveToY(y)
self.staticy = y
end
---------- module end ----------
end

View File

@ -0,0 +1,205 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- tabbutton class
local newobject = loveframes.NewObject("tabbutton", "loveframes_object_tabbutton", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize(parent, text, tabnumber, tip, image, onopened, onclosed)
self.type = "tabbutton"
self.font = loveframes.smallfont
self.text = text
self.tabnumber = tabnumber
self.parent = parent
self.state = parent.state
self.staticx = 0
self.staticy = 0
self.width = 50
self.height = 25
self.internal = true
self.down = false
self.image = nil
self.OnOpened = nil
self.OnClosed = nil
if tip then
self.tooltip = loveframes.objects["tooltip"]:new(self, tip)
self.tooltip:SetFollowCursor(false)
self.tooltip:SetFollowObject(true)
self.tooltip:SetOffsets(0, -(self.tooltip.internals[1]:GetHeight() + 12))
end
if image then
self:SetImage(image)
end
if onopened then
self.OnOpened = onopened
end
if onclosed then
self.OnClosed = onclosed
end
-- apply template properties to the object
loveframes.ApplyTemplatesToObject(self)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
local parent = self.parent
local base = loveframes.base
local update = self.Update
self:CheckHover()
self:SetClickBounds(parent.x, parent.y, parent.width, parent.height)
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local visible = self.visible
if not visible then
return
end
local hover = self.hover
local internals = self.internals
if hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
self.down = true
loveframes.downobject = self
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local visible = self.visible
if not visible then
return
end
local hover = self.hover
local parent = self.parent
local tabnumber = self.tabnumber
if hover and button == 1 then
if button == 1 then
local tab = parent.tab
local internals = parent.internals
local onopened = self.OnOpened
local prevtab = internals[tab]
local onclosed = prevtab.OnClosed
parent:SwitchToTab(tabnumber)
if onopened then
onopened(self)
end
if onclosed then
onclosed(prevtab)
end
end
end
self.down = false
end
--[[---------------------------------------------------------
- func: SetText(text)
- desc: sets the object's text
--]]---------------------------------------------------------
function newobject:SetText(text)
self.text = text
end
--[[---------------------------------------------------------
- func: GetText()
- desc: gets the object's text
--]]---------------------------------------------------------
function newobject:GetText()
return self.text
end
--[[---------------------------------------------------------
- func: SetImage(image)
- desc: adds an image to the object
--]]---------------------------------------------------------
function newobject:SetImage(image)
if type(image) == "string" then
self.image = love.graphics.newImage(image)
self.image:setFilter("nearest", "nearest")
else
self.image = image
end
end
--[[---------------------------------------------------------
- func: GetImage()
- desc: gets the object's image
--]]---------------------------------------------------------
function newobject:GetImage()
return self.image
end
--[[---------------------------------------------------------
- func: GetTabNumber()
- desc: gets the object's tab number
--]]---------------------------------------------------------
function newobject:GetTabNumber()
return self.tabnumber
end
---------- module end ----------
end

View File

@ -0,0 +1,353 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- tooltip class
local newobject = loveframes.NewObject("tooltip", "loveframes_object_tooltip", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize(object, text)
self.type = "tooltip"
self.parent = loveframes.base
self.object = object or nil
self.width = 0
self.height = 0
self.padding = 5
self.xoffset = 10
self.yoffset = -10
self.internal = true
self.followcursor = true
self.followobject = false
self.alwaysupdate = true
self.internals = {}
-- create the object's text
local textobject = loveframes.Create("text")
textobject:Remove()
textobject.parent = self
textobject:SetText(text or "")
textobject:SetPos(10000, 0) -- textobject interferes with hover detection
table.insert(self.internals, textobject)
-- apply template properties to the object
loveframes.ApplyTemplatesToObject(self)
table.insert(loveframes.base.internals, self)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
local internals = self.internals
local textobject = internals[1]
if not visible then
textobject:SetPos(10000, 0) -- textobject interferes with hover detection
if not alwaysupdate then
return
end
end
local padding = self.padding
local object = self.object
local draworder = self.draworder
local update = self.Update
self.width = textobject.width + padding * 2
self.height = textobject.height + padding * 2
if object then
if object == loveframes.base then
self:Remove()
return
end
--local ovisible = object.visible
local ohover = object.hover
local ostate = object.state
if ostate ~= state then
self.visible = false
return
end
self.visible = ohover
if ohover then
local top = self:IsTopInternal()
local followcursor = self.followcursor
local followobject = self.followobject
local xoffset = self.xoffset
local yoffset = self.yoffset
if followcursor then
local height = self.height
local mx, my = love.mouse.getPosition()
self.x = mx + xoffset
self.y = my - height + yoffset
elseif followobject then
local ox = object.x
local oy = object.y
self.x = ox + xoffset
self.y = oy + yoffset
end
if not top then
self:MoveToTop()
end
textobject:SetPos(padding, padding)
end
end
--textobject:SetVisible(self.show)
textobject:SetState(selfstate)
textobject:update(dt)
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: SetFollowCursor(bool)
- desc: sets whether or not the tooltip should follow the
cursor
--]]---------------------------------------------------------
function newobject:SetFollowCursor(bool)
self.followcursor = bool
return self
end
--[[---------------------------------------------------------
- func: GetFollowCursor()
- desc: gets whether or not the tooltip should follow the
cursor
--]]---------------------------------------------------------
function newobject:GetFollowCursor()
return self.followcursor
end
--[[---------------------------------------------------------
- func: SetObject(object)
- desc: sets the tooltip's object
--]]---------------------------------------------------------
function newobject:SetObject(object)
self.object = object
self.x = object.x
self.y = object.y
return self
end
--[[---------------------------------------------------------
- func: GetObject()
- desc: gets the tooltip's object
--]]---------------------------------------------------------
function newobject:GetObject()
return self.object
end
--[[---------------------------------------------------------
- func: SetText(text)
- desc: sets the tooltip's text
--]]---------------------------------------------------------
function newobject:SetText(text)
local internals = self.internals
local textobject = internals[1]
textobject:SetText(text)
return self
end
--[[---------------------------------------------------------
- func: GetText()
- desc: gets the tooltip's text
--]]---------------------------------------------------------
function newobject:GetText()
local internals = self.internals
local textobject = internals[1]
local text = textobject:GetText()
return text
end
--[[---------------------------------------------------------
- func: SetTextMaxWidth(text)
- desc: sets the tooltip's text max width
--]]---------------------------------------------------------
function newobject:SetTextMaxWidth(width)
local internals = self.internals
local textobject = internals[1]
textobject:SetMaxWidth(width)
return self
end
--[[---------------------------------------------------------
- func: SetOffsetX(xoffset)
- desc: sets the tooltip's x offset
--]]---------------------------------------------------------
function newobject:SetOffsetX(xoffset)
self.xoffset = xoffset
return self
end
--[[---------------------------------------------------------
- func: GetOffsetX()
- desc: gets the tooltip's x offset
--]]---------------------------------------------------------
function newobject:GetOffsetX()
return self.xoffset
end
--[[---------------------------------------------------------
- func: SetOffsetY(yoffset)
- desc: sets the tooltip's y offset
--]]---------------------------------------------------------
function newobject:SetOffsetY(yoffset)
self.yoffset = yoffset
return self
end
--[[---------------------------------------------------------
- func: GetOffsetY()
- desc: gets the tooltip's y offset
--]]---------------------------------------------------------
function newobject:GetOffsetY()
return self.yoffset
end
--[[---------------------------------------------------------
- func: SetOffsets(xoffset, yoffset)
- desc: sets the tooltip's x and y offset
--]]---------------------------------------------------------
function newobject:SetOffsets(xoffset, yoffset)
self.xoffset = xoffset
self.yoffset = yoffset
return self
end
--[[---------------------------------------------------------
- func: GetOffsets()
- desc: gets the tooltip's x and y offset
--]]---------------------------------------------------------
function newobject:GetOffsets()
return self.xoffset, self.yoffset
end
--[[---------------------------------------------------------
- func: SetPadding(padding)
- desc: sets the tooltip's padding
--]]---------------------------------------------------------
function newobject:SetPadding(padding)
self.padding = padding
return self
end
--[[---------------------------------------------------------
- func: GetPadding()
- desc: gets the tooltip's padding
--]]---------------------------------------------------------
function newobject:GetPadding()
return self.padding
end
--[[---------------------------------------------------------
- func: SetFont(font)
- desc: sets the tooltip's font
--]]---------------------------------------------------------
function newobject:SetFont(font)
local internals = self.internals
local textobject = internals[1]
textobject:SetFont(font)
return self
end
--[[---------------------------------------------------------
- func: GetFont()
- desc: gets the tooltip's font
--]]---------------------------------------------------------
function newobject:GetFont()
local internals = self.internals
local textobject = internals[1]
return textobject:GetFont()
end
--[[---------------------------------------------------------
- func: SetFollowObject(bool)
- desc: sets whether or not the tooltip should follow
its assigned object
--]]---------------------------------------------------------
function newobject:SetFollowObject(bool)
self.followobject = bool
return self
end
--[[---------------------------------------------------------
- func: GetFollowObject()
- desc: gets whether or not the tooltip should follow
its assigned object
--]]---------------------------------------------------------
function newobject:GetFollowObject()
return self.followobject
end
---------- module end ----------
end

View File

@ -0,0 +1,296 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- button object
local newobject = loveframes.NewObject("treenode", "loveframes_object_treenode", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "treenode"
self.text = "Node"
self.width = 250
self.height = 16
self.level = 0
self.leftpadding = 0
self.lastclick = 0
self.open = false
self.internal = true
self.internals = {}
self.icon = nil
self.OnOpen = nil
self.OnClose = nil
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
self:CheckHover()
local parent = self.parent
local base = loveframes.base
local update = self.Update
local tree = self.tree
self:SetClickBounds(tree.x, tree.y, tree.width, tree.height)
for k, v in ipairs(self.internals) do
if v.type == "treenode" then
if self.open then
v.x = v.tree.x - v.tree.offsetx
v.y = (v.tree.y + self.tree.itemheight) - v.tree.offsety
if v.width > self.tree.itemwidth then
self.tree.itemwidth = v.width
end
self.tree.itemheight = self.tree.itemheight + v.height
v:update(dt)
end
else
v:update(dt)
end
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: draw()
- desc: draws the object
--]]---------------------------------------------------------
function newobject:draw()
if loveframes.state ~= self.state then
return
end
if not self.visible then
return
end
-- set the object's draw order
self:SetDrawOrder()
local drawfunc = self.Draw or self.drawfunc
if drawfunc then
drawfunc(self)
end
local internals = self.internals
if internals then
for k, v in ipairs(internals) do
if v.type == "treenode" then
if self.open then
v:draw()
end
else
v:draw()
end
end
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
for k, v in ipairs(self.internals) do
v:mousepressed(x, y, button)
end
if self.hover and button == 1 then
local time = os.time()
if self.lastclick + 0.40 > time then
self.open = not self.open
end
self.lastclick = time
local onselectnode = self.tree.OnSelectNode
self.tree.selectednode = self
if onselectnode then
onselectnode(self.parent, self)
end
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
for k, v in ipairs(self.internals) do
v:mousereleased(x, y, button)
end
end
--[[---------------------------------------------------------
- func: SetIcon(icon)
- desc: sets the object's icon
--]]---------------------------------------------------------
function newobject:SetIcon(icon)
if type(icon) == "string" then
self.icon = love.graphics.newImage(icon)
self.icon:setFilter("nearest", "nearest")
else
self.icon = icon
end
return self
end
--[[---------------------------------------------------------
- func: GetIcon()
- desc: gets the object's icon
--]]---------------------------------------------------------
function newobject:GetIcon()
return self.icon
end
--[[---------------------------------------------------------
- func: SetText(text)
- desc: sets the object's text
--]]---------------------------------------------------------
function newobject:SetText(text)
self.text = text
return self
end
--[[---------------------------------------------------------
- func: GetText()
- desc: gets the object's text
--]]---------------------------------------------------------
function newobject:GetText()
return self.text
end
--[[---------------------------------------------------------
- func: AddNode(text)
- desc: adds a new node to the object
--]]---------------------------------------------------------
function newobject:AddNode(text)
if not self.internals[1] then
local openbutton = loveframes.objects["treenodebutton"]:new()
openbutton.parent = self
openbutton.staticx = 2
openbutton.staticy = 2
table.insert(self.internals, openbutton)
end
local node = loveframes.objects["treenode"]:new()
node.parent = self
node.tree = self.tree
node.text = text
node.level = self.level + 1
table.insert(self.internals, node)
return node
end
--[[---------------------------------------------------------
- func: RemoveNode(id)
- desc: removes a node from the object
--]]---------------------------------------------------------
function newobject:RemoveNode(id)
id = id + 1
for k, v in ipairs(self.internals) do
if k == id then
v:Remove()
break
end
end
end
--[[---------------------------------------------------------
- func: SetOpen(bool)
- desc: sets whether or not the object is open
--]]---------------------------------------------------------
function newobject:SetOpen(bool)
self.open = bool
return self
end
--[[---------------------------------------------------------
- func: GetOpen()
- desc: gets whether or not the object is open
--]]---------------------------------------------------------
function newobject:GetOpen()
return self.open
end
---------- module end ----------
end

View File

@ -0,0 +1,108 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- button object
local newobject = loveframes.NewObject("treenodebutton", "loveframes_object_treenodebutton", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "treenodebutton"
self.width = 16
self.height = 16
self.internal = true
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
self:CheckHover()
local parent = self.parent
local base = loveframes.base
local update = self.Update
-- move to parent if there is a parent
if parent ~= base then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local hover = self.hover
if hover and button == 1 then
local bool = not self.parent.open
if bool then
local onopen = self.parent.OnOpen
if onopen then
onopen(self.parent)
end
else
local onclose = self.parent.OnClose
if onclose then
onclose(self.parent)
end
end
self.parent:SetOpen(bool)
print("!")
print(self.parent.level)
end
end
---------- module end ----------
end

807
loveframes/objects/list.lua Normal file
View File

@ -0,0 +1,807 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- list object
local newobject = loveframes.NewObject("list", "loveframes_object_list", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "list"
self.display = "vertical"
self.width = 300
self.height = 150
self.clickx = 0
self.clicky = 0
self.padding = 0
self.spacing = 0
self.offsety = 0
self.offsetx = 0
self.extrawidth = 0
self.extraheight = 0
self.buttonscrollamount = 0.10
self.mousewheelscrollamount = 10
self.internal = false
self.hbar = false
self.vbar = false
self.autoscroll = false
self.horizontalstacking = false
self.dtscrolling = false
self.internals = {}
self.children = {}
self.OnScroll = nil
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
self:CheckHover()
local internals = self.internals
local children = self.children
local display = self.display
local parent = self.parent
local horizontalstacking = self.horizontalstacking
local base = loveframes.base
local update = self.Update
-- move to parent if there is a parent
if parent ~= base then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
for k, v in ipairs(internals) do
v:update(dt)
for _, p in pairs(self:GetParents()) do
v.x = v.x - (p.offsetx or 0)
v.y = v.y - (p.offsety or 0)
end
end
local x = self.x
local y = self.y
local width = self.width
local height = self.height
local offsetx = self.offsetx
local offsety = self.offsety
for k, v in ipairs(children) do
v:update(dt)
v:SetClickBounds(x, y, width, height)
v.x = (v.parent.x + v.staticx) - offsetx
v.y = (v.parent.y + v.staticy) - offsety
for _, p in pairs(self:GetParents()) do
v.x = v.x - (p.offsetx or 0)
v.y = v.y - (p.offsety or 0)
end
if display == "vertical" then
if v.lastheight ~= v.height then
self:CalculateSize()
self:RedoLayout()
end
end
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: draw()
- desc: draws the object
--]]---------------------------------------------------------
function newobject:draw()
if loveframes.state ~= self.state then
return
end
if not self.visible then
return
end
local x = self.x
local y = self.y
local width = self.width
local height = self.height
local stencilfunc = function()
love.graphics.rectangle("fill", x, y, width, height)
end
self:SetDrawOrder()
local drawfunc = self.Draw or self.drawfunc
if drawfunc then
drawfunc(self)
end
love.graphics.stencil(stencilfunc)
love.graphics.setStencilTest("greater", 0)
local children = self.children
if children then
for k, v in ipairs(children) do
local col = loveframes.BoundingBox(x, v.x, y, v.y, width, v.width, height, v.height)
if col then
v:draw()
end
end
end
love.graphics.setStencilTest()
local drawfunc = self.DrawOver or self.drawoverfunc
if drawfunc then
drawfunc(self)
end
local internals = self.internals
if internals then
for k, v in ipairs(internals) do
v:draw()
end
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local hover = self.hover
local children = self.children
local internals = self.internals
if hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
end
for k, v in ipairs(internals) do
v:mousepressed(x, y, button)
end
for k, v in ipairs(children) do
v:mousepressed(x, y, button)
end
end
--[[---------------------------------------------------------
- func: wheelmoved(x, y)
- desc: called when the player moves a mouse wheel
--]]---------------------------------------------------------
function newobject:wheelmoved(x, y)
local toplist = self:IsTopList()
local vbar = self.vbar
local hbar = self.hbar
local scrollamount = self.mousewheelscrollamount
if (vbar or hbar) and toplist then
local bar = self:GetScrollBar()
local dtscrolling = self.dtscrolling
if dtscrolling then
local dt = love.timer.getDelta()
bar:Scroll(-y * scrollamount * dt)
else
bar:Scroll(-y * scrollamount)
end
end
end
--[[---------------------------------------------------------
- func: AddItem(object)
- desc: adds an item to the object
--]]---------------------------------------------------------
function newobject:AddItem(object)
local objtype = object.type
if objtype == "frame" then
return
end
local children = self.children
local state = self.state
-- remove the item object from its current parent and make its new parent the list object
object:Remove()
object.parent = self
object:SetState(state)
-- insert the item object into the list object's children table
table.insert(children, object)
-- resize the list and redo its layout
self:CalculateSize()
self:RedoLayout()
return self
end
--[[---------------------------------------------------------
- func: RemoveItem(object or number)
- desc: removes an item from the object
--]]---------------------------------------------------------
function newobject:RemoveItem(data)
local dtype = type(data)
if dtype == "number" then
local children = self.children
local item = children[data]
if item then
item:Remove()
end
else
data:Remove()
end
self:CalculateSize()
self:RedoLayout()
return self
end
--[[---------------------------------------------------------
- func: CalculateSize()
- desc: calculates the size of the object's children
--]]---------------------------------------------------------
function newobject:CalculateSize()
local numitems = #self.children
local height = self.height
local width = self.width
local padding = self.padding
local spacing = self.spacing
local itemheight = self.padding
local itemwidth = self.padding
local display = self.display
local vbar = self.vbar
local hbar = self.hbar
local internals = self.internals
local children = self.children
local horizontalstacking = self.horizontalstacking
if display == "vertical" then
if horizontalstacking then
local curwidth = 0
local maxwidth = width - padding * 2
local prevheight = 0
local scrollbar = self:GetScrollBar()
if scrollbar then
maxwidth = maxwidth - scrollbar.width
end
for k, v in ipairs(children) do
if v.height > prevheight then
prevheight = v.height
end
curwidth = curwidth + v.width + spacing
if children[k + 1] then
if curwidth + children[k + 1].width > maxwidth then
curwidth = padding
itemheight = itemheight + prevheight + spacing
prevheight = 0
end
else
itemheight = itemheight + prevheight + padding
end
end
self.itemheight = itemheight
else
for k, v in ipairs(children) do
itemheight = itemheight + v.height + spacing
end
self.itemheight = (itemheight - spacing) + padding
end
local itemheight = self.itemheight
if itemheight > height then
self.extraheight = itemheight - height
if not vbar then
local scrollbar = loveframes.objects["scrollbody"]:new(self, display)
table.insert(internals, scrollbar)
self.vbar = true
self:GetScrollBar().autoscroll = self.autoscroll
end
else
if vbar then
local bar = internals[1]
bar:Remove()
self.vbar = false
self.offsety = 0
end
end
elseif display == "horizontal" then
for k, v in ipairs(children) do
itemwidth = itemwidth + v.width + spacing
end
self.itemwidth = (itemwidth - spacing) + padding
local itemwidth = self.itemwidth
if itemwidth > width then
self.extrawidth = itemwidth - width
if not hbar then
local scrollbar = loveframes.objects["scrollbody"]:new(self, display)
table.insert(internals, scrollbar)
self.hbar = true
self:GetScrollBar().autoscroll = self.autoscroll
end
else
if hbar then
local bar = internals[1]
bar:Remove()
self.hbar = false
self.offsetx = 0
end
end
end
return self
end
--[[---------------------------------------------------------
- func: RedoLayout()
- desc: used to redo the layout of the object
--]]---------------------------------------------------------
function newobject:RedoLayout()
local width = self.width
local height = self.height
local children = self.children
local internals = self.internals
local padding = self.padding
local spacing = self.spacing
local starty = padding
local startx = padding
local vbar = self.vbar
local hbar = self.hbar
local display = self.display
local horizontalstacking = self.horizontalstacking
local scrollbody, scrollbodywidth, scrollbodyheight
if vbar or hbar then
scrollbody = internals[1]
scrollbodywidth = scrollbody.width
scrollbodyheight = scrollbody.height
end
if #children > 0 then
if display == "vertical" then
if horizontalstacking then
local curwidth = padding
local curheight = padding
local maxwidth = self.width - padding * 2
local prevheight = 0
local scrollbar = self:GetScrollBar()
if scrollbar then
maxwidth = maxwidth - scrollbar.width
end
for k, v in ipairs(children) do
local itemheight = v.height
v.lastheight = itemheight
v.staticx = curwidth
v.staticy = curheight
if v.height > prevheight then
prevheight = v.height
end
if children[k + 1] then
curwidth = curwidth + v.width + spacing
if curwidth + (children[k + 1].width) > maxwidth then
curwidth = padding
curheight = curheight + prevheight + spacing
prevheight = 0
end
end
end
else
for k, v in ipairs(children) do
local itemwidth = v.width
local itemheight = v.height
local retainsize = v.retainsize
v.staticx = padding
v.staticy = starty
v.lastheight = itemheight
if vbar then
if itemwidth + padding > (width - scrollbodywidth) then
v:SetWidth((width - scrollbodywidth) - (padding * 2))
end
if not retainsize then
v:SetWidth((width - scrollbodywidth) - (padding * 2))
end
scrollbody.staticx = width - scrollbodywidth
scrollbody.height = height
else
if not retainsize then
v:SetWidth(width - (padding * 2))
end
end
starty = starty + itemheight
starty = starty + spacing
end
end
elseif display == "horizontal" then
for k, v in ipairs(children) do
local itemwidth = v.width
local itemheight = v.height
local retainsize = v.retainsize
v.staticx = startx
v.staticy = padding
if hbar then
if itemheight + padding > (height - scrollbodyheight) then
v:SetHeight((height - scrollbodyheight) - (padding * 2))
end
if not retainsize then
v:SetHeight((height - scrollbodyheight) - (padding * 2))
end
scrollbody.staticy = height - scrollbodyheight
scrollbody.width = width
else
if not retainsize then
v:SetHeight(height - (padding * 2))
end
end
startx = startx + itemwidth
startx = startx + spacing
end
end
end
return self
end
--[[---------------------------------------------------------
- func: SetDisplayType(type)
- desc: sets the object's display type
--]]---------------------------------------------------------
function newobject:SetDisplayType(type)
local children = self.children
local numchildren = #children
self.display = type
self.vbar = false
self.hbar = false
self.offsetx = 0
self.offsety = 0
self.internals = {}
if numchildren > 0 then
self:CalculateSize()
self:RedoLayout()
end
return self
end
--[[---------------------------------------------------------
- func: GetDisplayType()
- desc: gets the object's display type
--]]---------------------------------------------------------
function newobject:GetDisplayType()
return self.display
end
--[[---------------------------------------------------------
- func: SetPadding(amount)
- desc: sets the object's padding
--]]---------------------------------------------------------
function newobject:SetPadding(amount)
local children = self.children
local numchildren = #children
self.padding = amount
if numchildren > 0 then
self:CalculateSize()
self:RedoLayout()
end
return self
end
--[[---------------------------------------------------------
- func: SetSpacing(amount)
- desc: sets the object's spacing
--]]---------------------------------------------------------
function newobject:SetSpacing(amount)
local children = self.children
local numchildren = #children
self.spacing = amount
if numchildren > 0 then
self:CalculateSize()
self:RedoLayout()
end
return self
end
--[[---------------------------------------------------------
- func: Clear()
- desc: removes all of the object's children
--]]---------------------------------------------------------
function newobject:Clear()
self.children = {}
self:CalculateSize()
self:RedoLayout()
return self
end
--[[---------------------------------------------------------
- func: SetWidth(width, relative)
- desc: sets the object's width
--]]---------------------------------------------------------
function newobject:SetWidth(width, relative)
if relative then
self.width = self.parent.width * width
else
self.width = width
end
self:CalculateSize()
self:RedoLayout()
return self
end
--[[---------------------------------------------------------
- func: SetHeight(height, relative)
- desc: sets the object's height
--]]---------------------------------------------------------
function newobject:SetHeight(height, relative)
if relative then
self.height = self.parent.height * height
else
self.height = height
end
self:CalculateSize()
self:RedoLayout()
return self
end
--[[---------------------------------------------------------
- func: SetSize(width, height, r1, r2)
- desc: sets the object's size
--]]---------------------------------------------------------
function newobject:SetSize(width, height, r1, r2)
if r1 then
self.width = self.parent.width * width
else
self.width = width
end
if r2 then
self.height = self.parent.height * height
else
self.height = height
end
self:CalculateSize()
self:RedoLayout()
return self
end
--[[---------------------------------------------------------
- func: GetScrollBar()
- desc: gets the object's scroll bar
--]]---------------------------------------------------------
function newobject:GetScrollBar()
local vbar = self.vbar
local hbar = self.hbar
local internals = self.internals
if vbar or hbar then
local scrollbody = internals[1]
local scrollarea = scrollbody.internals[1]
local scrollbar = scrollarea.internals[1]
return scrollbar
else
return false
end
end
--[[---------------------------------------------------------
- func: SetAutoScroll(bool)
- desc: sets whether or not the list's scrollbar should
auto scroll to the bottom when a new object is
added to the list
--]]---------------------------------------------------------
function newobject:SetAutoScroll(bool)
local scrollbar = self:GetScrollBar()
self.autoscroll = bool
if scrollbar then
scrollbar.autoscroll = bool
end
return self
end
--[[---------------------------------------------------------
- func: GetAutoScroll()
- desc: gets whether or not the list's scrollbar should
auto scroll to the bottom when a new object is
added to the list
--]]---------------------------------------------------------
function newobject:GetAutoScroll()
return self.autoscroll
end
--[[---------------------------------------------------------
- func: SetButtonScrollAmount(speed)
- desc: sets the scroll amount of the object's scrollbar
buttons
--]]---------------------------------------------------------
function newobject:SetButtonScrollAmount(amount)
self.buttonscrollamount = amount
return self
end
--[[---------------------------------------------------------
- func: GetButtonScrollAmount()
- desc: gets the scroll amount of the object's scrollbar
buttons
--]]---------------------------------------------------------
function newobject:GetButtonScrollAmount()
return self.buttonscrollamount
end
--[[---------------------------------------------------------
- func: SetMouseWheelScrollAmount(amount)
- desc: sets the scroll amount of the mouse wheel
--]]---------------------------------------------------------
function newobject:SetMouseWheelScrollAmount(amount)
self.mousewheelscrollamount = amount
return self
end
--[[---------------------------------------------------------
- func: GetMouseWheelScrollAmount()
- desc: gets the scroll amount of the mouse wheel
--]]---------------------------------------------------------
function newobject:GetButtonScrollAmount()
return self.mousewheelscrollamount
end
--[[---------------------------------------------------------
- func: EnableHorizontalStacking(bool)
- desc: enables or disables horizontal stacking
--]]---------------------------------------------------------
function newobject:EnableHorizontalStacking(bool)
local children = self.children
local numchildren = #children
self.horizontalstacking = bool
if numchildren > 0 then
self:CalculateSize()
self:RedoLayout()
end
return self
end
--[[---------------------------------------------------------
- func: GetHorizontalStacking()
- desc: gets whether or not the object allows horizontal
stacking
--]]---------------------------------------------------------
function newobject:GetHorizontalStacking()
return self.horizontalstacking
end
--[[---------------------------------------------------------
- func: SetDTScrolling(bool)
- desc: sets whether or not the object should use delta
time when scrolling
--]]---------------------------------------------------------
function newobject:SetDTScrolling(bool)
self.dtscrolling = bool
return self
end
--[[---------------------------------------------------------
- func: GetDTScrolling()
- desc: gets whether or not the object should use delta
time when scrolling
--]]---------------------------------------------------------
function newobject:GetDTScrolling()
return self.dtscrolling
end
---------- module end ----------
end

287
loveframes/objects/menu.lua Normal file
View File

@ -0,0 +1,287 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- menu object
local newobject = loveframes.NewObject("menu", "loveframes_object_menu", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize(menu)
self.type = "menu"
self.width = 80
self.height = 25
self.largest_item_width = 0
self.largest_item_height = 0
self.is_sub_menu = false
self.internal = false
self.parentmenu = nil
self.options = {}
self.internals = {}
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
self:CheckHover()
local hover = self.hover
local parent = self.parent
local base = loveframes.base
local update = self.Update
-- move to parent if there is a parent
if parent ~= base then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
for k, v in ipairs(self.internals) do
local width = v.contentwidth
local height = v.contentheight
if width > self.largest_item_width then
self.largest_item_width = width
end
if height > self.largest_item_height then
self.largest_item_height = height
end
end
local y = 0
self.height = 0
for k, v in ipairs(self.internals) do
v:SetWidth(self.largest_item_width)
if v.option_type ~= "divider" then
v:SetHeight(self.largest_item_height)
else
v:SetHeight(5)
end
v:SetY(y)
self.height = self.height + v.height
y = y + v.height
v:update(dt)
end
self.width = self.largest_item_width
self.largest_item_width = 0
self.largest_item_height = 0
local screen_width = love.graphics.getWidth()
local screen_height = love.graphics.getHeight()
local sx = self.x
local sy = self.y
local width = self.width
local height = self.height
local x1 = sx + width
if sx + width > screen_width then
self.x = screen_width - width
end
if sy + self.height > screen_height then
self.y = screen_height - self.height
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local internals = self.internals
for k, v in ipairs(internals) do
v:mousereleased(x, y, button)
end
end
--[[---------------------------------------------------------
- func: AddOption(text, icon, func)
- desc: adds an option to the object
--]]---------------------------------------------------------
function newobject:AddOption(text, icon, func)
local menuoption = loveframes.objects["menuoption"]:new(self)
menuoption:SetText(text)
menuoption:SetIcon(icon)
menuoption:SetFunction(func)
table.insert(self.internals, menuoption)
return self
end
--[[---------------------------------------------------------
- func: RemoveOption(id)
- desc: removes an option
--]]---------------------------------------------------------
function newobject:RemoveOption(id)
for k, v in ipairs(self.internals) do
if k == id then
table.remove(self.internals, k)
return
end
end
return self
end
--[[---------------------------------------------------------
- func: AddSubMenu(text, icon, menu)
- desc: adds a submenu to the object
--]]---------------------------------------------------------
function newobject:AddSubMenu(text, icon, menu)
local function activatorFunc(object)
if menu:GetVisible() then
local hoverobject = loveframes.hoverobject
if hoverobject ~= object and hoverobject:GetBaseParent() ~= menu then
menu:SetVisible(false)
end
else
menu:SetVisible(true)
menu:SetPos(object:GetX() + object:GetWidth(), object:GetY())
end
end
menu:SetVisible(false)
local menuoption = loveframes.objects["menuoption"]:new(self, "submenu_activator", menu)
menuoption:SetText(text)
menuoption:SetIcon(icon)
if menu then
menu.is_sub_menu = true
menu.parentmenu = self
end
table.insert(self.internals, menuoption)
return self
end
--[[---------------------------------------------------------
- func: AddDivider()
- desc: adds a divider to the object
--]]---------------------------------------------------------
function newobject:AddDivider()
local menuoption = loveframes.objects["menuoption"]:new(self, "divider")
table.insert(self.internals, menuoption)
return self
end
--[[---------------------------------------------------------
- func: GetBaseMenu(t)
- desc: gets the object's base menu
--]]---------------------------------------------------------
function newobject:GetBaseMenu(t)
local t = t or {}
if self.parentmenu then
table.insert(t, self.parentmenu)
self.parentmenu:GetBaseMenu(t)
else
return self
end
return t[#t]
end
--[[---------------------------------------------------------
- func: SetVisible(bool)
- desc: sets the object's visibility
--]]---------------------------------------------------------
function newobject:SetVisible(bool)
self.visible = bool
if not bool then
local internals = self.internals
for k, v in ipairs(internals) do
if v.menu then
v.activated = false
v.menu:SetVisible(bool)
end
end
end
return self
end
---------- module end ----------
end

View File

@ -0,0 +1,418 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- multichoice object
local newobject = loveframes.NewObject("multichoice", "loveframes_object_multichoice", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "multichoice"
self.choice = ""
self.text = "Select an option"
self.width = 200
self.height = 25
self.listpadding = 0
self.listspacing = 0
self.buttonscrollamount = 200
self.mousewheelscrollamount = 1500
self.sortfunc = function(a, b) return a < b end
self.haslist = false
self.dtscrolling = true
self.enabled = true
self.internal = false
self.choices = {}
self.listheight = nil
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
local parent = self.parent
local base = loveframes.base
local update = self.Update
self:CheckHover()
-- move to parent if there is a parent
if parent ~= base then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local hover = self.hover
local haslist = self.haslist
local enabled = self.enabled
if hover and not haslist and enabled and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
self.haslist = true
self.list = loveframes.objects["multichoicelist"]:new(self)
self.list:SetState(self.state)
loveframes.downobject = self
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
end
--[[---------------------------------------------------------
- func: AddChoice(choice)
- desc: adds a choice to the current list of choices
--]]---------------------------------------------------------
function newobject:AddChoice(choice)
local choices = self.choices
table.insert(choices, choice)
return self
end
--[[---------------------------------------------------------
- func: RemoveChoice(choice)
- desc: removes the specified choice from the object's
list of choices
--]]---------------------------------------------------------
function newobject:RemoveChoice(choice)
local choices = self.choices
for k, v in ipairs(choices) do
if v == choice then
table.remove(choices, k)
break
end
end
return self
end
--[[---------------------------------------------------------
- func: SetChoice(choice)
- desc: sets the current choice
--]]---------------------------------------------------------
function newobject:SetChoice(choice)
self.choice = choice
return self
end
--[[---------------------------------------------------------
- func: SelectChoice(choice)
- desc: selects a choice
--]]---------------------------------------------------------
function newobject:SelectChoice(choice)
local onchoiceselected = self.OnChoiceSelected
self.choice = choice
if self.list then
self.list:Close()
end
if onchoiceselected then
onchoiceselected(self, choice)
end
return self
end
--[[---------------------------------------------------------
- func: SetListHeight(height)
- desc: sets the height of the list of choices
--]]---------------------------------------------------------
function newobject:SetListHeight(height)
self.listheight = height
return self
end
--[[---------------------------------------------------------
- func: SetPadding(padding)
- desc: sets the padding of the list of choices
--]]---------------------------------------------------------
function newobject:SetPadding(padding)
self.listpadding = padding
return self
end
--[[---------------------------------------------------------
- func: SetSpacing(spacing)
- desc: sets the spacing of the list of choices
--]]---------------------------------------------------------
function newobject:SetSpacing(spacing)
self.listspacing = spacing
return self
end
--[[---------------------------------------------------------
- func: GetValue()
- desc: gets the value (choice) of the object
--]]---------------------------------------------------------
function newobject:GetValue()
return self.choice
end
--[[---------------------------------------------------------
- func: GetChoice()
- desc: gets the current choice (same as get value)
--]]---------------------------------------------------------
function newobject:GetChoice()
return self.choice
end
--[[---------------------------------------------------------
- func: SetText(text)
- desc: sets the object's text
--]]---------------------------------------------------------
function newobject:SetText(text)
self.text = text
return self
end
--[[---------------------------------------------------------
- func: GetText()
- desc: gets the object's text
--]]---------------------------------------------------------
function newobject:GetText()
return self.text
end
--[[---------------------------------------------------------
- func: SetButtonScrollAmount(speed)
- desc: sets the scroll amount of the object's scrollbar
buttons
--]]---------------------------------------------------------
function newobject:SetButtonScrollAmount(amount)
self.buttonscrollamount = amount
return self
end
--[[---------------------------------------------------------
- func: GetButtonScrollAmount()
- desc: gets the scroll amount of the object's scrollbar
buttons
--]]---------------------------------------------------------
function newobject:GetButtonScrollAmount()
return self.buttonscrollamount
end
--[[---------------------------------------------------------
- func: SetMouseWheelScrollAmount(amount)
- desc: sets the scroll amount of the mouse wheel
--]]---------------------------------------------------------
function newobject:SetMouseWheelScrollAmount(amount)
self.mousewheelscrollamount = amount
return self
end
--[[---------------------------------------------------------
- func: GetMouseWheelScrollAmount()
- desc: gets the scroll amount of the mouse wheel
--]]---------------------------------------------------------
function newobject:GetButtonScrollAmount()
return self.mousewheelscrollamount
end
--[[---------------------------------------------------------
- func: SetDTScrolling(bool)
- desc: sets whether or not the object should use delta
time when scrolling
--]]---------------------------------------------------------
function newobject:SetDTScrolling(bool)
self.dtscrolling = bool
return self
end
--[[---------------------------------------------------------
- func: GetDTScrolling()
- desc: gets whether or not the object should use delta
time when scrolling
--]]---------------------------------------------------------
function newobject:GetDTScrolling()
return self.dtscrolling
end
--[[---------------------------------------------------------
- func: Sort(func)
- desc: sorts the object's choices
--]]---------------------------------------------------------
function newobject:Sort(func)
local default = self.sortfunc
if func then
table.sort(self.choices, func)
else
table.sort(self.choices, default)
end
return self
end
--[[---------------------------------------------------------
- func: SetSortFunction(func)
- desc: sets the object's default sort function
--]]---------------------------------------------------------
function newobject:SetSortFunction(func)
self.sortfunc = func
return self
end
--[[---------------------------------------------------------
- func: GetSortFunction(func)
- desc: gets the object's default sort function
--]]---------------------------------------------------------
function newobject:GetSortFunction()
return self.sortfunc
end
--[[---------------------------------------------------------
- func: Clear()
- desc: removes all choices from the object's list
of choices
--]]---------------------------------------------------------
function newobject:Clear()
self.choices = {}
self.choice = ""
self.text = "Select an option"
return self
end
--[[---------------------------------------------------------
- func: SetClickable(bool)
- desc: sets whether or not the object is enabled
--]]---------------------------------------------------------
function newobject:SetEnabled(bool)
self.enabled = bool
return self
end
--[[---------------------------------------------------------
- func: GetEnabled()
- desc: gets whether or not the object is enabled
--]]---------------------------------------------------------
function newobject:GetEnabled()
return self.enabled
end
---------- module end ----------
end

View File

@ -0,0 +1,485 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- numberbox object
local newobject = loveframes.NewObject("numberbox", "loveframes_object_numberbox", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "numberbox"
self.width = 80
self.height = 20
self.value = 0
self.increaseamount = 1
self.decreaseamount = 1
self.min = -100
self.max = 100
self.delay = 0
self.decimals = 0
self.internal = false
self.canmodify = false
self.lastbuttonclicked = false
self.internals = {}
self.OnValueChanged = nil
local input = loveframes.objects["textinput"]:new()
input.parent = self
input:SetSize(50, 20)
input:SetUsable({"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", ".", "-"})
input:SetTabReplacement("")
input:SetText(self.value)
input.OnTextChanged = function(object)
local value = self.value
local newvalue = tonumber(object.lines[1])
if not newvalue then
self.value = value
input:SetText(value)
return
end
self.value = newvalue
if self.value > self.max then
self.value = self.max
object:SetText(self.value)
end
if self.value < self.min then
self.value = self.min
object:SetText(self.value)
end
if value ~= self.value then
if self.OnValueChanged then
self.OnValueChanged(self, self.value)
end
end
end
input.Update = function(object)
object:SetSize(object.parent.width - 20, object.parent.height)
end
local increasebutton = loveframes.objects["button"]:new()
increasebutton.parent = self
increasebutton:SetWidth(21)
increasebutton:SetText("+")
increasebutton.OnClick = function()
local canmodify = self.canmodify
if not canmodify then
self:ModifyValue("add")
else
self.canmodify = false
end
end
increasebutton.Update = function(object)
local time = 0
time = love.timer.getTime()
local delay = self.delay
local down = object.down
local canmodify = self.canmodify
local lastbuttonclicked = self.lastbuttonclicked
object:SetPos(object.parent.width - 21, 0)
object:SetHeight(object.parent.height/2 + 1)
if down and not canmodify then
self:ModifyValue("add")
self.canmodify = true
self.delay = time + 0.80
self.lastbuttonclicked = object
elseif down and canmodify and delay < time then
self:ModifyValue("add")
self.delay = time + 0.02
elseif not down and canmodify and lastbuttonclicked == object then
self.canmodify = false
self.delay = time + 0.80
end
end
local decreasesbutton = loveframes.objects["button"]:new()
decreasesbutton.parent = self
decreasesbutton:SetWidth(21)
decreasesbutton:SetText("-")
decreasesbutton.OnClick = function()
local canmodify = self.canmodify
if not canmodify then
self:ModifyValue("subtract")
else
self.canmodify = false
end
end
decreasesbutton.Update = function(object)
local time = 0
time = love.timer.getTime()
local delay = self.delay
local down = object.down
local canmodify = self.canmodify
local lastbuttonclicked = self.lastbuttonclicked
object:SetPos(object.parent.width - 21, object.parent.height/2)
object:SetHeight(object.parent.height/2)
if down and not canmodify then
self:ModifyValue("subtract")
self.canmodify = true
self.delay = time + 0.80
self.lastbuttonclicked = object
elseif down and canmodify and delay < time then
self:ModifyValue("subtract")
self.delay = time + 0.02
elseif not down and canmodify and lastbuttonclicked == object then
self.canmodify = false
self.delay = time + 0.80
end
end
table.insert(self.internals, input)
table.insert(self.internals, increasebutton)
table.insert(self.internals, decreasesbutton)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the element
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
local internals = self.internals
local parent = self.parent
local base = loveframes.base
local update = self.Update
-- move to parent if there is a parent
if parent ~= base and parent.type ~= "list" then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
self:CheckHover()
for k, v in ipairs(internals) do
v:update(dt)
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local internals = self.internals
local hover = self.hover
if hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
end
for k, v in ipairs(internals) do
v:mousepressed(x, y, button)
end
end
--[[---------------------------------------------------------
- func: SetValue(value)
- desc: sets the object's value
--]]---------------------------------------------------------
function newobject:SetValue(value)
local min = self.min
local curvalue = self.value
local value = tonumber(value) or min
local internals = self.internals
local input = internals[1]
local onvaluechanged = self.OnValueChanged
self.value = value
input:SetText(value)
if value ~= curvalue and onvaluechanged then
onvaluechanged(self, value)
end
return self
end
--[[---------------------------------------------------------
- func: GetValue()
- desc: gets the object's value
--]]---------------------------------------------------------
function newobject:GetValue()
return self.value
end
--[[---------------------------------------------------------
- func: SetIncreaseAmount(amount)
- desc: sets the object's increase amount
--]]---------------------------------------------------------
function newobject:SetIncreaseAmount(amount)
self.increaseamount = amount
return self
end
--[[---------------------------------------------------------
- func: GetIncreaseAmount()
- desc: gets the object's increase amount
--]]---------------------------------------------------------
function newobject:GetIncreaseAmount()
return self.increaseamount
end
--[[---------------------------------------------------------
- func: SetDecreaseAmount(amount)
- desc: sets the object's decrease amount
--]]---------------------------------------------------------
function newobject:SetDecreaseAmount(amount)
self.decreaseamount = amount
return self
end
--[[---------------------------------------------------------
- func: GetDecreaseAmount()
- desc: gets the object's decrease amount
--]]---------------------------------------------------------
function newobject:GetDecreaseAmount()
return self.decreaseamount
end
--[[---------------------------------------------------------
- func: SetMax(max)
- desc: sets the object's maximum value
--]]---------------------------------------------------------
function newobject:SetMax(max)
local internals = self.internals
local input = internals[1]
local onvaluechanged = self.OnValueChanged
self.max = max
if self.value > max then
self.value = max
input:SetValue(max)
if onvaluechanged then
onvaluechanged(self, max)
end
end
return self
end
--[[---------------------------------------------------------
- func: GetMax()
- desc: gets the object's maximum value
--]]---------------------------------------------------------
function newobject:GetMax()
return self.max
end
--[[---------------------------------------------------------
- func: SetMin(min)
- desc: sets the object's minimum value
--]]---------------------------------------------------------
function newobject:SetMin(min)
local internals = self.internals
local input = internals[1]
local onvaluechanged = self.OnValueChanged
self.min = min
if self.value < min then
self.value = min
input:SetValue(min)
if onvaluechanged then
onvaluechanged(self, min)
end
end
return self
end
--[[---------------------------------------------------------
- func: GetMin()
- desc: gets the object's minimum value
--]]---------------------------------------------------------
function newobject:GetMin()
return self.min
end
--[[---------------------------------------------------------
- func: SetMinMax()
- desc: sets the object's minimum and maximum values
--]]---------------------------------------------------------
function newobject:SetMinMax(min, max)
local internals = self.internals
local input = internals[1]
local onvaluechanged = self.OnValueChanged
self.min = min
self.max = max
if self.value > max then
self.value = max
input:SetValue(max)
if onvaluechanged then
onvaluechanged(self, max)
end
end
if self.value < min then
self.value = min
input:SetValue(min)
if onvaluechanged then
onvaluechanged(self, min)
end
end
return self
end
--[[---------------------------------------------------------
- func: GetMinMax()
- desc: gets the object's minimum and maximum values
--]]---------------------------------------------------------
function newobject:GetMinMax()
return self.min, self.max
end
--[[---------------------------------------------------------
- func: ModifyValue(type)
- desc: modifies the object's value
--]]---------------------------------------------------------
function newobject:ModifyValue(type)
local value = self.value
local internals = self.internals
local input = internals[1]
local decimals = self.decimals
local onvaluechanged = self.OnValueChanged
if not value then
return
end
if type == "add" then
local increaseamount = self.increaseamount
local max = self.max
self.value = value + increaseamount
if self.value > max then
self.value = max
end
self.value = loveframes.Round(self.value, decimals)
input:SetText(self.value)
if value ~= self.value then
if onvaluechanged then
onvaluechanged(self, self.value)
end
end
elseif type == "subtract" then
local decreaseamount = self.decreaseamount
local min = self.min
self.value = value - decreaseamount
if self.value < min then
self.value = min
end
self.value = loveframes.Round(self.value, decimals)
input:SetText(self.value)
if value ~= self.value then
if onvaluechanged then
onvaluechanged(self, self.value)
end
end
end
return self
end
--[[---------------------------------------------------------
- func: SetDecimals(decimals)
- desc: sets how many decimals the object's value
can have
--]]---------------------------------------------------------
function newobject:SetDecimals(decimals)
self.decimals = decimals
return self
end
--[[---------------------------------------------------------
- func: GetDecimals()
- desc: gets how many decimals the object's value
can have
--]]---------------------------------------------------------
function newobject:GetDecimals()
return self.decimals
end
---------- module end ----------
end

View File

@ -0,0 +1,134 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- panel object
local newobject = loveframes.NewObject("panel", "loveframes_object_panel", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "panel"
self.width = 200
self.height = 50
self.internal = false
self.children = {}
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the element
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
local children = self.children
local parent = self.parent
local base = loveframes.base
local update = self.Update
-- move to parent if there is a parent
if parent ~= base and parent.type ~= "list" then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
self:CheckHover()
for k, v in ipairs(children) do
v:update(dt)
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local children = self.children
local hover = self.hover
if hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
end
for k, v in ipairs(children) do
v:mousepressed(x, y, button)
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local children = self.children
if not visible then
return
end
for k, v in ipairs(children) do
v:mousereleased(x, y, button)
end
end
---------- module end ----------
end

View File

@ -0,0 +1,318 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- progressbar object
local newobject = loveframes.NewObject("progressbar", "loveframes_object_progressbar", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "progressbar"
self.text = ""
self.width = 100
self.height = 25
self.min = 0
self.max = 10
self.value = 0
self.barwidth = 0
self.lerprate = 1000
self.lerpvalue = 0
self.lerpto = 0
self.lerpfrom = 0
self.completed = false
self.lerp = false
self.internal = false
self.OnComplete = nil
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
local lerp = self.lerp
local lerprate = self.lerprate
local lerpvalue = self.lerpvalue
local lerpto = self.lerpto
local lerpfrom = self.lerpfrom
local value = self.value
local completed = self.completed
local parent = self.parent
local base = loveframes.base
local update = self.Update
local oncomplete = self.OnComplete
self:CheckHover()
-- caclulate barwidth
if lerp then
if lerpfrom < lerpto then
if lerpvalue < lerpto then
self.lerpvalue = lerpvalue + lerprate*dt
elseif lerpvalue > lerpto then
self.lerpvalue = lerpto
end
elseif lerpfrom > lerpto then
if lerpvalue > lerpto then
self.lerpvalue = lerpvalue - lerprate*dt
elseif lerpvalue < lerpto then
self.lerpvalue = lerpto
end
elseif lerpfrom == lerpto then
self.lerpvalue = lerpto
end
self.barwidth = self.lerpvalue/self.max * self.width
-- min check
if self.lerpvalue < self.min then
self.lerpvalue = self.min
end
-- max check
if self.lerpvalue > self.max then
self.lerpvalue = self.max
end
else
self.barwidth = value/self.max * self.width
-- min max check
if value < self.min then
self.value = self.min
elseif value > self.max then
self.value = self.max
end
end
-- move to parent if there is a parent
if parent ~= base then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
-- completion check
if not completed then
if self.value >= self.max then
self.completed = true
if oncomplete then
oncomplete(self)
end
end
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: SetMax(max)
- desc: sets the object's maximum value
--]]---------------------------------------------------------
function newobject:SetMax(max)
self.max = max
return self
end
--[[---------------------------------------------------------
- func: GetMax()
- desc: gets the object's maximum value
--]]---------------------------------------------------------
function newobject:GetMax()
return self.max
end
--[[---------------------------------------------------------
- func: SetMin(min)
- desc: sets the object's minimum value
--]]---------------------------------------------------------
function newobject:SetMin(min)
self.min = min
return self
end
--[[---------------------------------------------------------
- func: GetMin()
- desc: gets the object's minimum value
--]]---------------------------------------------------------
function newobject:GetMin()
return self.min
end
--[[---------------------------------------------------------
- func: SetMinMax()
- desc: sets the object's minimum and maximum values
--]]---------------------------------------------------------
function newobject:SetMinMax(min, max)
self.min = min
self.max = max
return self
end
--[[---------------------------------------------------------
- func: GetMinMax()
- desc: gets the object's minimum and maximum values
--]]---------------------------------------------------------
function newobject:GetMinMax()
return self.min, self.max
end
--[[---------------------------------------------------------
- func: SetValue(value)
- desc: sets the object's value
--]]---------------------------------------------------------
function newobject:SetValue(value)
local lerp = self.lerp
if lerp then
self.lerpvalue = self.lerpvalue
self.lerpto = value
self.lerpfrom = self.lerpvalue
self.value = value
else
self.value = value
end
return self
end
--[[---------------------------------------------------------
- func: GetValue()
- desc: gets the object's value
--]]---------------------------------------------------------
function newobject:GetValue()
return self.value
end
--[[---------------------------------------------------------
- func: SetLerp(bool)
- desc: sets whether or not the object should lerp
when changing between values
--]]---------------------------------------------------------
function newobject:SetLerp(bool)
self.lerp = bool
self.lerpto = self:GetValue()
self.lerpvalue = self:GetValue()
return self
end
--[[---------------------------------------------------------
- func: GetLerp()
- desc: gets whether or not the object should lerp
when changing between values
--]]---------------------------------------------------------
function newobject:GetLerp()
return self.lerp
end
--[[---------------------------------------------------------
- func: SetLerpRate(rate)
- desc: sets the object's lerp rate
--]]---------------------------------------------------------
function newobject:SetLerpRate(rate)
self.lerprate = rate
return self
end
--[[---------------------------------------------------------
- func: GetLerpRate()
- desc: gets the object's lerp rate
--]]---------------------------------------------------------
function newobject:GetLerpRate()
return self.lerprate
end
--[[---------------------------------------------------------
- func: GetCompleted()
- desc: gets whether or not the object has reached its
maximum value
--]]---------------------------------------------------------
function newobject:GetCompleted()
return self.completed
end
--[[---------------------------------------------------------
- func: GetBarWidth()
- desc: gets the object's bar width
--]]---------------------------------------------------------
function newobject:GetBarWidth()
return self.barwidth
end
--[[---------------------------------------------------------
- func: SetText(text)
- desc: sets the object's text
--]]---------------------------------------------------------
function newobject:SetText(text)
self.text = text
return self
end
--[[---------------------------------------------------------
- func: GetText()
- desc: gets the object's text
--]]---------------------------------------------------------
function newobject:GetText()
return self.text
end
---------- module end ----------
end

View File

@ -0,0 +1,429 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- radiobutton object
local newobject = loveframes.NewObject("radiobutton", "loveframes_object_radiobutton", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "radiobutton"
self.width = 0
self.height = 0
self.boxwidth = 20
self.boxheight = 20
self.font = loveframes.basicfont
self.checked = false
self.lastvalue = false
self.internal = false
self.down = true
self.enabled = true
self.internals = {}
self.OnChanged = function () end
self.group = {}
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
self:CheckHover()
local hover = self.hover
local internals = self.internals
local boxwidth = self.boxwidth
local boxheight = self.boxheight
local parent = self.parent
local base = loveframes.base
local update = self.Update
if not hover then
self.down = false
else
if loveframes.downobject == self then
self.down = true
end
end
if not self.down and loveframes.downobject == self then
self.hover = true
end
-- move to parent if there is a parent
if parent ~= base and parent.type ~= "list" then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
if internals[1] then
self.width = boxwidth + 5 + internals[1].width
if internals[1].height == boxheight then
self.height = boxheight
else
if internals[1].height > boxheight then
self.height = internals[1].height
else
self.height = boxheight
end
end
else
self.width = boxwidth
self.height = boxheight
end
for k, v in ipairs(internals) do
v:update(dt)
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local hover = self.hover
if hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
self.down = true
loveframes.downobject = self
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
if loveframes.state ~= self.state then
return
end
if not self.visible then
return
end
if self.hover and self.down and self.enabled and button == 1 then
if not self.checked then
-- a radio button can only be unchecked by checking another radio button
self:SetChecked(true)
end
end
end
--[[---------------------------------------------------------
- func: SetText(text)
- desc: sets the object's text
--]]---------------------------------------------------------
function newobject:SetText(text)
local boxwidth = self.boxwidth
local boxheight = self.boxheight
if text ~= "" then
self.internals = {}
local textobject = loveframes.Create("text")
local skin = loveframes.GetActiveSkin()
if not skin then
skin = loveframes.config["DEFAULTSKIN"]
end
local directives = skin.directives
if directives then
local default_color = directives.radiobutton_text_default_color
local default_shadowcolor = directives.radiobutton_text_default_shadowcolor
local default_font = directives.radiobutton_text_default_font
if default_color then
textobject.defaultcolor = default_color
end
if default_shadowcolor then
textobject.shadowcolor = default_shadowcolor
end
if default_font then
self.font = default_font
end
end
textobject:Remove()
textobject.parent = self
textobject.state = self.state
textobject.collide = false
textobject:SetFont(self.font)
textobject:SetText(text)
textobject.Update = function(object, dt)
if object.height > boxheight then
object:SetPos(boxwidth + 5, 0)
else
object:SetPos(boxwidth + 5, boxheight/2 - object.height/2)
end
end
table.insert(self.internals, textobject)
else
self.width = boxwidth
self.height = boxheight
self.internals = {}
end
return self
end
--[[---------------------------------------------------------
- func: GetText()
- desc: gets the object's text
--]]---------------------------------------------------------
function newobject:GetText()
local internals = self.internals
local text = internals[1]
if text then
return text.text
else
return false
end
end
--[[---------------------------------------------------------
- func: SetSize(width, height, r1, r2)
- desc: sets the object's size
--]]---------------------------------------------------------
function newobject:SetSize(width, height, r1, r2)
if r1 then
self.boxwidth = self.parent.width * width
else
self.boxwidth = width
end
if r2 then
self.boxheight = self.parent.height * height
else
self.boxheight = height
end
return self
end
--[[---------------------------------------------------------
- func: SetWidth(width, relative)
- desc: sets the object's width
--]]---------------------------------------------------------
function newobject:SetWidth(width, relative)
if relative then
self.boxwidth = self.parent.width * width
else
self.boxwidth = width
end
return self
end
--[[---------------------------------------------------------
- func: SetHeight(height, relative)
- desc: sets the object's height
--]]---------------------------------------------------------
function newobject:SetHeight(height, relative)
if relative then
self.boxheight = self.parent.height * height
else
self.boxheight = height
end
return self
end
--[[---------------------------------------------------------
- func: SetChecked(bool)
- desc: sets whether the object is checked or not
--]]---------------------------------------------------------
function newobject:SetChecked(checked)
if self.checked ~= checked then
self.checked = checked
self:OnChanged(checked)
end
if checked then
for _, button in pairs(self.group) do
if button ~= self and button.checked then
button:SetChecked(false)
end
end
end
return self
end
--[[---------------------------------------------------------
- func: GetChecked()
- desc: gets whether the object is checked or not
--]]---------------------------------------------------------
function newobject:GetChecked()
return self.checked
end
--[[---------------------------------------------------------
- func: SetGroup()
- desc: set the object's group. only one radio button in a
group is checked at a time.
--]]---------------------------------------------------------
function newobject:SetGroup(group)
self.group = group
self.group[self] = self
end
--[[---------------------------------------------------------
- func: GetGroup()
- desc: gets the object's group
--]]---------------------------------------------------------
function newobject:GetGroup(group)
return self.group
end
--[[---------------------------------------------------------
- func: SetFont(font)
- desc: sets the font of the object's text
--]]---------------------------------------------------------
function newobject:SetFont(font)
local internals = self.internals
local text = internals[1]
self.font = font
if text then
text:SetFont(font)
end
return self
end
--[[---------------------------------------------------------
- func: newobject:GetFont()
- desc: gets the font of the object's text
--]]---------------------------------------------------------
function newobject:GetFont()
return self.font
end
--[[---------------------------------------------------------
- func: newobject:GetBoxHeight()
- desc: gets the object's box size
--]]---------------------------------------------------------
function newobject:GetBoxSize()
return self.boxwidth, self.boxheight
end
--[[---------------------------------------------------------
- func: newobject:GetBoxWidth()
- desc: gets the object's box width
--]]---------------------------------------------------------
function newobject:GetBoxWidth()
return self.boxwidth
end
--[[---------------------------------------------------------
- func: newobject:GetBoxHeight()
- desc: gets the object's box height
--]]---------------------------------------------------------
function newobject:GetBoxHeight()
return self.boxheight
end
--[[---------------------------------------------------------
- func: SetClickable(bool)
- desc: sets whether or not the object is enabled
--]]---------------------------------------------------------
function newobject:SetEnabled(bool)
self.enabled = bool
return self
end
--[[---------------------------------------------------------
- func: GetEnabled()
- desc: gets whether or not the object is enabled
--]]---------------------------------------------------------
function newobject:GetEnabled()
return self.enabled
end
---------- module end ----------
end

View File

@ -0,0 +1,514 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- slider object
local newobject = loveframes.NewObject("slider", "loveframes_object_slider", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "slider"
self.text = "Slider"
self.slidetype = "horizontal"
self.width = 5
self.height = 5
self.max = 10
self.min = 0
self.value = 0
self.decimals = 5
self.scrollincrease = 1
self.scrolldecrease = 1
self.scrollable = true
self.enabled = true
self.internal = false
self.internals = {}
self.OnValueChanged = nil
self.OnRelease = nil
-- create the slider button
local sliderbutton = loveframes.objects["sliderbutton"]:new(self)
sliderbutton.state = self.state
table.insert(self.internals, sliderbutton)
-- set initial value to minimum
self:SetValue(self.min)
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
local internals = self.internals
local sliderbutton = internals[1]
local parent = self.parent
local base = loveframes.base
local update = self.Update
self:CheckHover()
-- move to parent if there is a parent
if parent ~= base and parent.type ~= "list" then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
if sliderbutton then
local slidetype = self.slidetype
local buttonwidth = sliderbutton.width
local buttonheight = sliderbutton.height
if slidetype == "horizontal" then
self.height = buttonheight
elseif slidetype == "vertical" then
self.width = buttonwidth
end
end
-- update internals
for k, v in ipairs(self.internals) do
v:update(dt)
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local enabled = self.enabled
if not enabled then
return
end
local internals = self.internals
local hover = self.hover
local slidetype = self.slidetype
local scrollable = self.scrollable
if hover and button == 1 then
if slidetype == "horizontal" then
local xpos = x - self.x
local button = internals[1]
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
button:MoveToX(xpos)
button.down = true
button.dragging = true
button.startx = button.staticx
button.clickx = x
elseif slidetype == "vertical" then
local ypos = y - self.y
local button = internals[1]
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
button:MoveToY(ypos)
button.down = true
button.dragging = true
button.starty = button.staticy
button.clicky = y
end
elseif hover and scrollable and button == "wu" then
local value = self.value
local increase = self.scrollincrease
local newvalue = value + increase
self:SetValue(newvalue)
elseif hover and scrollable and button == "wd" then
local value = self.value
local decrease = self.scrolldecrease
local newvalue = value - decrease
self:SetValue(newvalue)
end
for k, v in ipairs(internals) do
v:mousepressed(x, y, button)
end
end
--[[---------------------------------------------------------
- func: SetValue(value)
- desc: sets the object's value
--]]---------------------------------------------------------
function newobject:SetValue(value)
if value > self.max then
return
end
if value < self.min then
return
end
local decimals = self.decimals
local newval = loveframes.Round(value, decimals)
local internals = self.internals
local onvaluechanged = self.OnValueChanged
-- set the new value
self.value = newval
-- slider button object
local sliderbutton = internals[1]
local slidetype = self.slidetype
local width = self.width
local height = self.height
local min = self.min
local max = self.max
-- move the slider button to the new position
if slidetype == "horizontal" then
local xpos = width * ((newval - min) / (max - min))
sliderbutton:MoveToX(xpos)
elseif slidetype == "vertical" then
local ypos = height - height * ((newval - min) / (max - min))
sliderbutton:MoveToY(ypos)
end
-- call OnValueChanged
if onvaluechanged then
onvaluechanged(self, newval)
end
return self
end
--[[---------------------------------------------------------
- func: GetValue()
- desc: gets the object's value
--]]---------------------------------------------------------
function newobject:GetValue()
return self.value
end
--[[---------------------------------------------------------
- func: SetMax(max)
- desc: sets the object's maximum value
--]]---------------------------------------------------------
function newobject:SetMax(max)
self.max = max
if self.value > self.max then
self.value = self.max
end
return self
end
--[[---------------------------------------------------------
- func: GetMax()
- desc: gets the object's maximum value
--]]---------------------------------------------------------
function newobject:GetMax()
return self.max
end
--[[---------------------------------------------------------
- func: SetMin(min)
- desc: sets the object's minimum value
--]]---------------------------------------------------------
function newobject:SetMin(min)
self.min = min
if self.value < self.min then
self.value = self.min
end
return self
end
--[[---------------------------------------------------------
- func: GetMin()
- desc: gets the object's minimum value
--]]---------------------------------------------------------
function newobject:GetMin()
return self.min
end
--[[---------------------------------------------------------
- func: SetMinMax()
- desc: sets the object's minimum and maximum values
--]]---------------------------------------------------------
function newobject:SetMinMax(min, max)
self.min = min
self.max = max
if self.value > self.max then
self.value = self.max
end
if self.value < self.min then
self.value = self.min
end
return self
end
--[[---------------------------------------------------------
- func: GetMinMax()
- desc: gets the object's minimum and maximum values
--]]---------------------------------------------------------
function newobject:GetMinMax()
return self.min, self.max
end
--[[---------------------------------------------------------
- func: SetText(name)
- desc: sets the objects's text
--]]---------------------------------------------------------
function newobject:SetText(text)
self.text = text
return self
end
--[[---------------------------------------------------------
- func: GetText()
- desc: gets the objects's text
--]]---------------------------------------------------------
function newobject:GetText()
return self.text
end
--[[---------------------------------------------------------
- func: SetDecimals(decimals)
- desc: sets how many decimals the object's value
can have
--]]---------------------------------------------------------
function newobject:SetDecimals(decimals)
self.decimals = decimals
return self
end
--[[---------------------------------------------------------
- func: GetDecimals()
- desc: gets how many decimals the object's value
can have
--]]---------------------------------------------------------
function newobject:GetDecimals()
return self.decimals
end
--[[---------------------------------------------------------
- func: SetButtonSize(width, height)
- desc: sets the objects's button size
--]]---------------------------------------------------------
function newobject:SetButtonSize(width, height)
local internals = self.internals
local sliderbutton = internals[1]
if sliderbutton then
sliderbutton.width = width
sliderbutton.height = height
end
return self
end
--[[---------------------------------------------------------
- func: GetButtonSize()
- desc: gets the objects's button size
--]]---------------------------------------------------------
function newobject:GetButtonSize()
local internals = self.internals
local sliderbutton = internals[1]
if sliderbutton then
return sliderbutton.width, sliderbutton.height
end
end
--[[---------------------------------------------------------
- func: SetSlideType(slidetype)
- desc: sets the objects's slide type
--]]---------------------------------------------------------
function newobject:SetSlideType(slidetype)
self.slidetype = slidetype
if slidetype == "vertical" then
self:SetValue(self.min)
end
return self
end
--[[---------------------------------------------------------
- func: GetSlideType()
- desc: gets the objects's slide type
--]]---------------------------------------------------------
function newobject:GetSlideType()
return self.slidetype
end
--[[---------------------------------------------------------
- func: SetScrollable(bool)
- desc: sets whether or not the object can be scrolled
via the mouse wheel
--]]---------------------------------------------------------
function newobject:SetScrollable(bool)
self.scrollable = bool
return self
end
--[[---------------------------------------------------------
- func: GetScrollable()
- desc: gets whether or not the object can be scrolled
via the mouse wheel
--]]---------------------------------------------------------
function newobject:GetScrollable()
return self.scrollable
end
--[[---------------------------------------------------------
- func: SetScrollIncrease(increase)
- desc: sets the amount to increase the object's value
by when scrolling with the mouse wheel
--]]---------------------------------------------------------
function newobject:SetScrollIncrease(increase)
self.scrollincrease = increase
return self
end
--[[---------------------------------------------------------
- func: GetScrollIncrease()
- desc: gets the amount to increase the object's value
by when scrolling with the mouse wheel
--]]---------------------------------------------------------
function newobject:GetScrollIncrease()
return self.scrollincrease
end
--[[---------------------------------------------------------
- func: SetScrollDecrease(decrease)
- desc: sets the amount to decrease the object's value
by when scrolling with the mouse wheel
--]]---------------------------------------------------------
function newobject:SetScrollDecrease(decrease)
self.scrolldecrease = decrease
return self
end
--[[---------------------------------------------------------
- func: GetScrollDecrease()
- desc: gets the amount to decrease the object's value
by when scrolling with the mouse wheel
--]]---------------------------------------------------------
function newobject:GetScrollDecrease()
return self.scrolldecrease
end
--[[---------------------------------------------------------
- func: SetEnabled(bool)
- desc: sets whether or not the object is enabled
--]]---------------------------------------------------------
function newobject:SetEnabled(bool)
self.enabled = bool
return self
end
--[[---------------------------------------------------------
- func: GetEnabled()
- desc: gets whether or not the object is enabled
--]]---------------------------------------------------------
function newobject:GetEnabled()
return self.enabled
end
---------- module end ----------
end

765
loveframes/objects/tabs.lua Normal file
View File

@ -0,0 +1,765 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- tabs object
local newobject = loveframes.NewObject("tabs", "loveframes_object_tabs", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "tabs"
self.width = 100
self.height = 50
self.clickx = 0
self.clicky = 0
self.offsetx = 0
self.tab = 1
self.tabnumber = 1
self.padding = 5
self.tabheight = 25
self.previoustabheight = 25
self.buttonscrollamount = 200
self.mousewheelscrollamount = 1500
self.buttonareax = 0
self.buttonareawidth = self.width
self.autosize = true
self.autobuttonareawidth = true
self.dtscrolling = true
self.internal = false
self.tooltipfont = loveframes.basicfontsmall
self.internals = {}
self.children = {}
self:AddScrollButtons()
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the element
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
local x, y = love.mouse.getPosition()
local tabheight = self.tabheight
local padding = self.padding
local autosize = self.autosize
local autobuttonareawidth = self.autobuttonareawidth
local padding = self.padding
local children = self.children
local numchildren = #children
local internals = self.internals
local tab = self.tab
local parent = self.parent
local base = loveframes.base
local update = self.Update
-- move to parent if there is a parent
if parent ~= base then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
self:CheckHover()
if numchildren > 0 and tab == 0 then
self.tab = 1
end
if autobuttonareawidth then
local width = self.width
self.buttonareawidth = width
end
local pos = 0
for k, v in ipairs(internals) do
v:update(dt)
if v.type == "tabbutton" then
v.x = (v.parent.x + v.staticx) + pos + self.offsetx + self.buttonareax
v.y = (v.parent.y + v.staticy)
pos = pos + v.width - 1
end
end
if #self.children > 0 then
self.children[self.tab]:update(dt)
self.children[self.tab]:SetPos(padding, tabheight + padding)
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: draw()
- desc: draws the object
--]]---------------------------------------------------------
function newobject:draw()
if loveframes.state ~= self.state then
return
end
if not self.visible then
return
end
local x = self.x
local y = self.y
local width = self.width
local height = self.height
local tabheight = self:GetHeightOfButtons()
local stencilfunc = function() love.graphics.rectangle("fill", x + self.buttonareax, y, self.buttonareawidth, height) end
self:SetDrawOrder()
local drawfunc = self.Draw or self.drawfunc
if drawfunc then
drawfunc(self)
end
love.graphics.stencil(stencilfunc)
love.graphics.setStencilTest("greater", 0)
local internals = self.internals
if internals then
for k, v in ipairs(internals) do
local col = loveframes.BoundingBox(x + self.buttonareax, v.x, self.y, v.y, self.buttonareawidth, v.width, tabheight, v.height)
if col or v.type == "scrollbutton" then
v:draw()
end
end
end
love.graphics.setStencilTest()
local children = self.children
if #children > 0 then
children[self.tab]:draw()
end
drawfunc = self.DrawOver or self.drawoverfunc
if drawfunc then
drawfunc(self)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local children = self.children
local internals = self.internals
local numchildren = #children
local numinternals = #internals
local tab = self.tab
local hover = self.hover
if hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
end
for k, v in ipairs(internals) do
v:mousepressed(x, y, button)
end
if numchildren > 0 then
children[tab]:mousepressed(x, y, button)
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local children = self.children
local numchildren = #children
local tab = self.tab
local internals = self.internals
if not visible then
return
end
for k, v in ipairs(internals) do
v:mousereleased(x, y, button)
end
if numchildren > 0 then
children[tab]:mousereleased(x, y, button)
end
end
--[[---------------------------------------------------------
- func: wheelmoved(x, y)
- desc: called when the player moves a mouse wheel
--]]---------------------------------------------------------
function newobject:wheelmoved(x, y)
local internals = self.internals
local numinternals = #internals
if y < 0 then
local buttonheight = self:GetHeightOfButtons()
local col = loveframes.BoundingBox(self.x, x, self.y, y, self.width, 1, buttonheight, 1)
local visible = internals[numinternals - 1]:GetVisible()
if col and visible then
local scrollamount = -y * self.mousewheelscrollamount
local dtscrolling = self.dtscrolling
if dtscrolling then
local dt = love.timer.getDelta()
self.offsetx = self.offsetx + scrollamount * dt
else
self.offsetx = self.offsetx + scrollamount
end
if self.offsetx > 0 then
self.offsetx = 0
end
end
elseif y > 0 then
local buttonheight = self:GetHeightOfButtons()
local col = loveframes.BoundingBox(self.x, x, self.y, y, self.width, 1, buttonheight, 1)
local visible = internals[numinternals]:GetVisible()
if col and visible then
local bwidth = self:GetWidthOfButtons()
local scrollamount = y * self.mousewheelscrollamount
local dtscrolling = self.dtscrolling
if dtscrolling then
local dt = love.timer.getDelta()
self.offsetx = self.offsetx - scrollamount * dt
else
self.offsetx = self.offsetx - scrollamount
end
if ((self.offsetx + bwidth) + self.width) < self.width then
self.offsetx = -(bwidth + 10)
end
end
end
end
--[[---------------------------------------------------------
- func: AddTab(name, object, tip, image)
- desc: adds a new tab to the tab panel
--]]---------------------------------------------------------
function newobject:AddTab(name, object, tip, image, onopened, onclosed)
local padding = self.padding
local autosize = self.autosize
local retainsize = self.retainsize
local tabnumber = self.tabnumber
local tabheight = self.tabheight
local internals = self.internals
local state = self.state
object:Remove()
object.parent = self
object:SetState(state)
object.staticx = 0
object.staticy = 0
if tabnumber ~= 1 then
object.visible = false
end
local tab = loveframes.objects["tabbutton"]:new(self, name, tabnumber, tip, image, onopened, onclosed)
table.insert(self.children, object)
table.insert(self.internals, #self.internals - 1, tab)
self.tabnumber = tabnumber + 1
if autosize and not retainsize then
object:SetSize(self.width - padding * 2, (self.height - tabheight) - padding * 2)
end
return tab
end
--[[---------------------------------------------------------
- func: AddScrollButtons()
- desc: creates scroll buttons fot the tab panel
- note: for internal use only
--]]---------------------------------------------------------
function newobject:AddScrollButtons()
local internals = self.internals
local state = self.state
for k, v in ipairs(internals) do
if v.type == "scrollbutton" then
table.remove(internals, k)
end
end
local leftbutton = loveframes.objects["scrollbutton"]:new("left")
leftbutton.parent = self
leftbutton:SetPos(0, 0)
leftbutton:SetSize(15, 25)
leftbutton:SetAlwaysUpdate(true)
leftbutton.Update = function(object, dt)
object.staticx = 0
object.staticy = 0
if self.offsetx ~= 0 then
object.visible = true
else
object.visible = false
object.down = false
object.hover = false
end
if object.down then
if self.offsetx > 0 then
self.offsetx = 0
elseif self.offsetx ~= 0 then
local scrollamount = self.buttonscrollamount
local dtscrolling = self.dtscrolling
if dtscrolling then
local dt = love.timer.getDelta()
self.offsetx = self.offsetx + scrollamount * dt
else
self.offsetx = self.offsetx + scrollamount
end
end
end
end
local rightbutton = loveframes.objects["scrollbutton"]:new("right")
rightbutton.parent = self
rightbutton:SetPos(self.width - 15, 0)
rightbutton:SetSize(15, 25)
rightbutton:SetAlwaysUpdate(true)
rightbutton.Update = function(object, dt)
object.staticx = self.width - object.width
object.staticy = 0
local bwidth = self:GetWidthOfButtons()
if (self.offsetx + bwidth) - (self.buttonareax * 2 - 1) > self.width then
object.visible = true
else
object.visible = false
object.down = false
object.hover = false
end
if object.down then
if ((self.x + self.offsetx) + bwidth) ~= (self.x + self.width) then
local scrollamount = self.buttonscrollamount
local dtscrolling = self.dtscrolling
if dtscrolling then
local dt = love.timer.getDelta()
self.offsetx = self.offsetx - scrollamount * dt
else
self.offsetx = self.offsetx - scrollamount
end
end
end
end
leftbutton.state = state
rightbutton.state = state
table.insert(internals, leftbutton)
table.insert(internals, rightbutton)
end
--[[---------------------------------------------------------
- func: GetWidthOfButtons()
- desc: gets the total width of all of the tab buttons
--]]---------------------------------------------------------
function newobject:GetWidthOfButtons()
local width = 0
local internals = self.internals
for k, v in ipairs(internals) do
if v.type == "tabbutton" then
width = width + v.width
end
end
return width
end
--[[---------------------------------------------------------
- func: GetHeightOfButtons()
- desc: gets the height of one tab button
--]]---------------------------------------------------------
function newobject:GetHeightOfButtons()
return self.tabheight
end
--[[---------------------------------------------------------
- func: SwitchToTab(tabnumber)
- desc: makes the specified tab the active tab
--]]---------------------------------------------------------
function newobject:SwitchToTab(tabnumber)
local children = self.children
for k, v in ipairs(children) do
v.visible = false
end
self.tab = tabnumber
self.children[tabnumber].visible = true
return self
end
--[[---------------------------------------------------------
- func: SetScrollButtonSize(width, height)
- desc: sets the size of the scroll buttons
--]]---------------------------------------------------------
function newobject:SetScrollButtonSize(width, height)
local internals = self.internals
for k, v in ipairs(internals) do
if v.type == "scrollbutton" then
v:SetSize(width, height)
end
end
return self
end
--[[---------------------------------------------------------
- func: SetPadding(paddint)
- desc: sets the padding for the tab panel
--]]---------------------------------------------------------
function newobject:SetPadding(padding)
self.padding = padding
return self
end
--[[---------------------------------------------------------
- func: SetPadding(paddint)
- desc: gets the padding of the tab panel
--]]---------------------------------------------------------
function newobject:GetPadding()
return self.padding
end
--[[---------------------------------------------------------
- func: SetTabHeight(height)
- desc: sets the height of the tab buttons
--]]---------------------------------------------------------
function newobject:SetTabHeight(height)
local autosize = self.autosize
local padding = self.padding
local previoustabheight = self.previoustabheight
local children = self.children
local internals = self.internals
self.tabheight = height
local tabheight = self.tabheight
if tabheight ~= previoustabheight then
for k, v in ipairs(children) do
local retainsize = v.retainsize
if autosize and not retainsize then
v:SetSize(self.width - padding*2, (self.height - tabheight) - padding*2)
end
end
self.previoustabheight = tabheight
end
for k, v in ipairs(internals) do
if v.type == "tabbutton" then
v:SetHeight(self.tabheight)
end
end
return self
end
--[[---------------------------------------------------------
- func: SetToolTipFont(font)
- desc: sets the height of the tab buttons
--]]---------------------------------------------------------
function newobject:SetToolTipFont(font)
local internals = self.internals
for k, v in ipairs(internals) do
if v.type == "tabbutton" and v.tooltip then
v.tooltip:SetFont(font)
end
end
return self
end
--[[---------------------------------------------------------
- func: GetTabNumber()
- desc: gets the object's tab number
--]]---------------------------------------------------------
function newobject:GetTabNumber()
return self.tab
end
--[[---------------------------------------------------------
- func: RemoveTab(id)
- desc: removes a tab from the object
--]]---------------------------------------------------------
function newobject:RemoveTab(id)
local children = self.children
local internals = self.internals
local tab = children[id]
if tab then
tab:Remove()
end
for k, v in ipairs(internals) do
if v.type == "tabbutton" then
if v.tabnumber == id then
v:Remove()
end
end
end
local tabnumber = 1
for k, v in ipairs(internals) do
if v.type == "tabbutton" then
v.tabnumber = tabnumber
tabnumber = tabnumber + 1
end
end
self.tabnumber = tabnumber
return self
end
--[[---------------------------------------------------------
- func: SetButtonScrollAmount(speed)
- desc: sets the scroll amount of the object's scrollbar
buttons
--]]---------------------------------------------------------
function newobject:SetButtonScrollAmount(amount)
self.buttonscrollamount = amount
return self
end
--[[---------------------------------------------------------
- func: GetButtonScrollAmount()
- desc: gets the scroll amount of the object's scrollbar
buttons
--]]---------------------------------------------------------
function newobject:GetButtonScrollAmount()
return self.buttonscrollamount
end
--[[---------------------------------------------------------
- func: SetMouseWheelScrollAmount(amount)
- desc: sets the scroll amount of the mouse wheel
--]]---------------------------------------------------------
function newobject:SetMouseWheelScrollAmount(amount)
self.mousewheelscrollamount = amount
return self
end
--[[---------------------------------------------------------
- func: GetMouseWheelScrollAmount()
- desc: gets the scroll amount of the mouse wheel
--]]---------------------------------------------------------
function newobject:GetButtonScrollAmount()
return self.mousewheelscrollamount
end
--[[---------------------------------------------------------
- func: SetDTScrolling(bool)
- desc: sets whether or not the object should use delta
time when scrolling
--]]---------------------------------------------------------
function newobject:SetDTScrolling(bool)
self.dtscrolling = bool
return self
end
--[[---------------------------------------------------------
- func: GetDTScrolling()
- desc: gets whether or not the object should use delta
time when scrolling
--]]---------------------------------------------------------
function newobject:GetDTScrolling()
return self.dtscrolling
end
--[[---------------------------------------------------------
- func: SetTabObject(id, object)
- desc: sets the object of a tab
--]]---------------------------------------------------------
function newobject:SetTabObject(id, object)
local children = self.children
local internals = self.internals
local tab = children[id]
local state = self.state
if tab then
tab:Remove()
object:Remove()
object.parent = self
object:SetState(state)
object.staticx = 0
object.staticy = 0
children[id] = object
end
return self
end
--[[---------------------------------------------------------
- func: SetButtonAreaX(x)
- desc: sets the x position of the object's button area
--]]---------------------------------------------------------
function newobject:SetButtonAreaX(x)
self.buttonareax = x
return self
end
--[[---------------------------------------------------------
- func: GetButtonAreaX()
- desc: gets the x position of the object's button area
--]]---------------------------------------------------------
function newobject:GetButtonAreaX()
return self.buttonareax
end
--[[---------------------------------------------------------
- func: SetButtonAreaWidth(width)
- desc: sets the width of the object's button area
--]]---------------------------------------------------------
function newobject:SetButtonAreaWidth(width)
self.buttonareawidth = width
return self
end
--[[---------------------------------------------------------
- func: GetButtonAreaWidth()
- desc: gets the width of the object's button area
--]]---------------------------------------------------------
function newobject:GetButtonAreaWidth()
return self.buttonareawidth
end
--[[---------------------------------------------------------
- func: SetAutoButtonAreaWidth(bool)
- desc: sets whether or not the width of the object's
button area should be adjusted automatically
--]]---------------------------------------------------------
function newobject:SetAutoButtonAreaWidth(bool)
self.autobuttonareawidth = bool
return self
end
--[[---------------------------------------------------------
- func: GetAutoButtonAreaWidth()
- desc: gets whether or not the width of the object's
button area should be adjusted automatically
--]]---------------------------------------------------------
function newobject:GetAutoButtonAreaWidth()
return self.autobuttonareawidth
end
---------- module end ----------
end

802
loveframes/objects/text.lua Normal file
View File

@ -0,0 +1,802 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
--[[------------------------------------------------
-- note: the text wrapping of this object is
experimental and not final
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- text object
local newobject = loveframes.NewObject("text", "loveframes_object_text", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "text"
self.text = ""
self.font = loveframes.basicfont
self.width = 5
self.height = 5
self.maxw = 0
self.shadowxoffset = 1
self.shadowyoffset = 1
self.lines = 0
self.formattedtext = {}
self.original = {}
self.defaultcolor = {0, 0, 0, 1}
self.shadowcolor = {0, 0, 0, 1}
self.linkcolor = {0, .4, 1, 1}
self.linkhovercolor = {0, 0, 1, 1}
self.ignorenewlines = false
self.shadow = false
self.linkcol = false
self.internal = false
self.linksenabled = false
self.detectlinks = false
self.OnClickLink = nil
local skin = loveframes.GetActiveSkin()
if not skin then
skin = loveframes.config["DEFAULTSKIN"]
end
local directives = skin.directives
if directives then
local text_default_color = directives.text_default_color
local text_default_shadowcolor = directives.text_default_shadowcolor
local text_default_font = directives.text_default_font
if text_default_color then
self.defaultcolor = text_default_color
end
if text_default_shadowcolor then
self.shadowcolor = text_default_shadowcolor
end
if text_default_font then
self.font = text_default_font
end
end
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
local parent = self.parent
local base = loveframes.base
local update = self.Update
self:CheckHover()
local hover = self.hover
local linksenabled = self.linksenabled
local linkcol = false
if hover and linksenabled and not loveframes.resizeobject then
local formattedtext = self.formattedtext
local x = self.x
local y = self.y
for k, v in ipairs(formattedtext) do
local link = v.link
if link then
local mx, my = love.mouse.getPosition()
local font = v.font
local linkx = v.x
local linky = v.y
local text = v.text
local twidth = font:getWidth(text)
local theight = font:getHeight()
local col = loveframes.BoundingBox(x + linkx, mx, y + linky, my, twidth, 1, theight, 1)
v.hover = false
if col then
v.hover = true
linkcol = true
end
end
end
self.linkcol = linkcol
end
-- move to parent if there is a parent
if parent ~= base then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
local hover = self.hover
if hover and button == 1 then
local baseparent = self:GetBaseParent()
if baseparent and baseparent.type == "frame" then
baseparent:MakeTop()
end
local linksenabled = self.linksenabled
if linksenabled then
local formattedtext = self.formattedtext
local objx = self.x
local objy = self.y
for k, v in ipairs(formattedtext) do
local link = v.link
if link then
local linkx = v.x
local linky = v.y
local font = v.font
local text = v.text
local twidth = font:getWidth(text)
local theight = font:getHeight()
local col = loveframes.BoundingBox(objx + linkx, x, objy + linky, y, twidth, 1, theight, 1)
if col then
local onclicklink = self.OnClickLink
if onclicklink then
onclicklink(self, text)
end
end
end
end
end
end
end
--[[---------------------------------------------------------
- func: SetText(text)
- desc: sets the object's text
--]]---------------------------------------------------------
function newobject:SetText(t)
local dtype = type(t)
local maxw = self.maxw
local font = self.font
local defaultcolor = self.defaultcolor
local inserts = {}
local prevcolor = defaultcolor
local prevlinkcolor = self.linkcolor
local prevlinkhovercolor = self.linkhovercolor
local prevfont = font
local link = false
local tdata
self.text = ""
self.formattedtext = {}
if dtype == "string" then
tdata = {t}
self.original = {t}
elseif dtype == "number" then
tdata = {tostring(t)}
self.original = {tostring(t)}
elseif dtype == "table" then
tdata = t
self.original = t
else
return
end
for k, v in ipairs(tdata) do
dtype = type(v)
if dtype == "table" then
if v.color then
prevcolor = v.color
end
if v.linkcolor then
prevlinkcolor = v.linkcolor
end
if v.linkhovercolor then
prevlinkhovercolor = v.linkhovercolor
end
if v.font then
prevfont = v.font
end
if v.link then
link = true
else
link = false
end
elseif dtype == "number" then
table.insert(self.formattedtext, {
font = prevfont,
color = prevcolor,
linkcolor = prevlinkcolor,
linkhovercolor = prevlinkhovercolor,
link = link,
text = tostring(v)
})
elseif dtype == "string" then
if self.ignorenewlines then
v = loveframes.utf8.gsub(v, "\n", " ")
end
v = loveframes.utf8.gsub(v, string.char(9), " ")
v = loveframes.utf8.gsub(v, "\n", " \n ")
local parts = loveframes.SplitString(v, " ")
for i, j in ipairs(parts) do
table.insert(self.formattedtext, {
font = prevfont,
color = prevcolor,
linkcolor = prevlinkcolor,
linkhovercolor = prevlinkhovercolor,
link = link,
text = j
})
end
end
end
if maxw > 0 then
for k, v in ipairs(self.formattedtext) do
local data = v.text
local width = v.font:getWidth(data)
local curw = 0
local new = ""
local key = k
if width > maxw then
table.remove(self.formattedtext, k)
for n=1, loveframes.utf8.len(data) do
local item = loveframes.utf8.sub(data, n, n)
local itemw = v.font:getWidth(item)
if n ~= loveframes.utf8.len(data) then
if (curw + itemw) > maxw then
table.insert(inserts, {
key = key,
font = v.font,
color = v.color,
linkcolor = prevlinkcolor,
linkhovercolor = v.linkhovercolor,
link = v.link,
text = new
})
new = item
curw = 0 + itemw
key = key + 1
else
new = new .. item
curw = curw + itemw
end
else
new = new .. item
table.insert(inserts, {
key = key,
font = v.font,
color = v.color,
linkcolor = prevlinkcolor,
linkhovercolor = v.linkhovercolor,
link = v.link,
text = new
})
end
end
end
end
end
for k, v in ipairs(inserts) do
table.insert(self.formattedtext, v.key, {
font = v.font,
color = v.color,
linkcolor = prevlinkcolor,
linkhovercolor = v.linkhovercolor,
link = v.link,
text = v.text
})
end
local textdata = self.formattedtext
local maxw = self.maxw
local font = self.font
local twidth = 0
local drawx = 0
local drawy = 0
local lines = 1
local textwidth = 0
local lastwidth = 0
local totalwidth = 0
local x = self.x
local y = self.y
local prevtextwidth = 0
local prevtextheight = 0
local prevlargestheight = 0
local largestwidth = 0
local largestheight = 0
local initialwidth = 0
local detectlinks = self.detectlinks
for k, v in ipairs(textdata) do
local text = v.text
local color = v.color
if detectlinks then
if loveframes.utf8.len(text) > 7 and (loveframes.utf8.sub(text, 1, 7) == "http://" or loveframes.utf8.sub(text, 1, 8) == "https://") then
v.link = true
end
end
if type(text) == "string" then
self.text = self.text .. text
local width = v.font:getWidth(text)
local height = v.font:getHeight("a")
if height > largestheight then
largestheight = height
prevlargestheight = height
end
totalwidth = totalwidth + width
if maxw > 0 then
if k ~= 1 then
if string.byte(text) == 10 then
twidth = 0
drawx = 0
width = 0
drawy = drawy + largestheight
largestheight = 0
text = ""
lines = lines + 1
elseif (twidth + width) > maxw then
twidth = 0 + width
drawx = 0
drawy = drawy + largestheight
largestheight = 0
lines = lines + 1
else
twidth = twidth + width
drawx = drawx + prevtextwidth
end
else
twidth = twidth + width
end
prevtextwidth = width
prevtextheight = height
v.x = drawx
v.y = drawy
else
if string.byte(text) == 10 then
twidth = 0
drawx = 0
width = 0
drawy = drawy + largestheight
largestheight = 0
text = ""
lines = lines + 1
if lastwidth < textwidth then
lastwidth = textwidth
end
if largestwidth < textwidth then
largestwidth = textwidth
end
textwidth = 0
else
drawx = drawx + prevtextwidth
textwidth = textwidth + width
end
prevtextwidth = width
prevtextheight = height
v.x = drawx
v.y = drawy
end
end
end
self.lines = lines
if lastwidth == 0 then
textwidth = totalwidth
end
if textwidth < largestwidth then
textwidth = largestwidth
end
if maxw > 0 then
self.width = maxw
else
self.width = textwidth
end
self.height = drawy + prevlargestheight
return self
end
--[[---------------------------------------------------------
- func: GetText()
- desc: gets the object's text
--]]---------------------------------------------------------
function newobject:GetText()
return self.text
end
--[[---------------------------------------------------------
- func: GetFormattedText()
- desc: gets the object's formatted text
--]]---------------------------------------------------------
function newobject:GetFormattedText()
return self.formattedtext
end
--[[---------------------------------------------------------
- func: DrawText()
- desc: draws the object's text
--]]---------------------------------------------------------
function newobject:DrawText()
local textdata = self.formattedtext
local x = self.x
local y = self.y
local shadow = self.shadow
local shadowxoffset = self.shadowxoffset
local shadowyoffset = self.shadowyoffset
local shadowcolor = self.shadowcolor
local inlist, list = self:IsInList()
local printfunc = function(text, x, y)
love.graphics.print(text, math.floor(x + 0.5), math.floor(y + 0.5))
end
for k, v in ipairs(textdata) do
local textx = v.x
local texty = v.y
local text = v.text
local color = v.color
local font = v.font
local link = v.link
local theight = font:getHeight("a")
if inlist then
local listy = list.y
local listhieght = list.height
if (y + texty) <= (listy + listhieght) and y + ((texty + theight)) >= listy then
love.graphics.setFont(font)
if shadow then
love.graphics.setColor(unpack(shadowcolor))
printfunc(text, x + textx + shadowxoffset, y + texty + shadowyoffset)
end
if link then
local linkcolor = v.linkcolor
local linkhovercolor = v.linkhovercolor
local hover = v.hover
if hover then
love.graphics.setColor(linkhovercolor)
else
love.graphics.setColor(linkcolor)
end
else
love.graphics.setColor(unpack(color))
end
printfunc(text, x + textx, y + texty)
end
else
love.graphics.setFont(font)
if shadow then
love.graphics.setColor(unpack(shadowcolor))
printfunc(text, x + textx + shadowxoffset, y + texty + shadowyoffset)
end
if link then
local linkcolor = v.linkcolor
local linkhovercolor = v.linkhovercolor
local hover = v.hover
if hover then
love.graphics.setColor(linkhovercolor)
else
love.graphics.setColor(linkcolor)
end
else
love.graphics.setColor(unpack(color))
end
printfunc(text, x + textx, y + texty)
end
end
return self
end
--[[---------------------------------------------------------
- func: SetMaxWidth(width)
- desc: sets the object's maximum width
--]]---------------------------------------------------------
function newobject:SetMaxWidth(width)
local original = self.original
self.maxw = width
self:SetText(original)
return self
end
--[[---------------------------------------------------------
- func: GetMaxWidth()
- desc: gets the object's maximum width
--]]---------------------------------------------------------
function newobject:GetMaxWidth()
return self.maxw
end
--[[---------------------------------------------------------
- func: SetWidth(width, relative)
- desc: sets the object's width
--]]---------------------------------------------------------
function newobject:SetWidth(width, relative)
if relative then
self:SetMaxWidth(self.parent.width * width)
else
self:SetMaxWidth(width)
end
return self
end
--[[---------------------------------------------------------
- func: SetHeight()
- desc: sets the object's height
--]]---------------------------------------------------------
function newobject:SetHeight(height)
return
end
--[[---------------------------------------------------------
- func: SetSize(width, height, relative)
- desc: sets the object's size
--]]---------------------------------------------------------
function newobject:SetSize(width, height, relative)
if relative then
self:SetMaxWidth(self.parent.width * width)
else
self:SetMaxWidth(width)
end
return self
end
--[[---------------------------------------------------------
- func: SetFont(font)
- desc: sets the object's font
- note: font argument must be a font object
--]]---------------------------------------------------------
function newobject:SetFont(font)
local original = self.original
self.font = font
if original then
self:SetText(original)
end
return self
end
--[[---------------------------------------------------------
- func: GetFont()
- desc: gets the object's font
--]]---------------------------------------------------------
function newobject:GetFont()
return self.font
end
--[[---------------------------------------------------------
- func: GetLines()
- desc: gets the number of lines the object's text uses
--]]---------------------------------------------------------
function newobject:GetLines()
return self.lines
end
--[[---------------------------------------------------------
- func: SetIgnoreNewlines(bool)
- desc: sets whether the object should ignore \n or not
--]]---------------------------------------------------------
function newobject:SetIgnoreNewlines(bool)
self.ignorenewlines = bool
return self
end
--[[---------------------------------------------------------
- func: GetIgnoreNewlines()
- desc: gets whether the object should ignore \n or not
--]]---------------------------------------------------------
function newobject:GetIgnoreNewlines()
return self.ignorenewlines
end
--[[---------------------------------------------------------
- func: SetShadow(bool)
- desc: sets whether or not the object should draw a
shadow behind its text
--]]---------------------------------------------------------
function newobject:SetShadow(bool)
self.shadow = bool
return self
end
--[[---------------------------------------------------------
- func: GetShadow()
- desc: gets whether or not the object should draw a
shadow behind its text
--]]---------------------------------------------------------
function newobject:GetShadow()
return self.shadow
end
--[[---------------------------------------------------------
- func: SetShadowOffsets(offsetx, offsety)
- desc: sets the object's x and y shadow offsets
--]]---------------------------------------------------------
function newobject:SetShadowOffsets(offsetx, offsety)
self.shadowxoffset = offsetx
self.shadowyoffset = offsety
return self
end
--[[---------------------------------------------------------
- func: GetShadowOffsets()
- desc: gets the object's x and y shadow offsets
--]]---------------------------------------------------------
function newobject:GetShadowOffsets()
return self.shadowxoffset, self.shadowyoffset
end
--[[---------------------------------------------------------
- func: SetShadowColor(r, g, b, a)
- desc: sets the object's shadow color
--]]---------------------------------------------------------
function newobject:SetShadowColor(r, g, b, a)
self.shadowcolor = {r, g, b, a}
return self
end
--[[---------------------------------------------------------
- func: GetShadowColor()
- desc: gets the object's shadow color
--]]---------------------------------------------------------
function newobject:GetShadowColor()
return self.shadowcolor
end
--[[---------------------------------------------------------
- func: SetDefaultColor(r, g, b, a)
- desc: sets the object's default text color
--]]---------------------------------------------------------
function newobject:SetDefaultColor(r, g, b, a)
self.defaultcolor = {r, g, b, a}
return self
end
--[[---------------------------------------------------------
- func: GetDefaultColor()
- desc: gets whether or not the object should draw a
shadow behind its text
--]]---------------------------------------------------------
function newobject:GetDefaultColor()
return self.defaultcolor
end
--[[---------------------------------------------------------
- func: SetLinksEnabled(enabled)
- desc: sets whether or not the object should process
urls into clickable links
--]]---------------------------------------------------------
function newobject:SetLinksEnabled(enabled)
self.linksenabled = enabled
return self
end
--[[---------------------------------------------------------
- func: GetLinksEnabled()
- desc: gets whether or not the object should process
urls into clickable links
--]]---------------------------------------------------------
function newobject:GetLinksEnabled()
return self.linksenabled
end
--[[---------------------------------------------------------
- func: SetDetectLinks(detect)
- desc: sets whether or not the object should detect
links when processing new text
--]]---------------------------------------------------------
function newobject:SetDetectLinks(detect)
self.detectlinks = detect
return self
end
--[[---------------------------------------------------------
- func: GetDetectLinks()
- desc: gets whether or not the object should detect
links when processing new text
--]]---------------------------------------------------------
function newobject:GetDetectLinks()
return self.detectlinks
end
---------- module end ----------
end

File diff suppressed because it is too large Load Diff

342
loveframes/objects/tree.lua Normal file
View File

@ -0,0 +1,342 @@
--[[------------------------------------------------
-- Love Frames - A GUI library for LOVE --
-- Copyright (c) 2012-2014 Kenny Shields --
--]]------------------------------------------------
return function(loveframes)
---------- module start ----------
-- tree object
local newobject = loveframes.NewObject("tree", "loveframes_object_tree", true)
--[[---------------------------------------------------------
- func: initialize()
- desc: initializes the object
--]]---------------------------------------------------------
function newobject:initialize()
self.type = "tree"
self.width = 200
self.height = 200
self.offsetx = 0
self.offsety = 0
self.itemwidth = 0
self.itemheight = 0
self.extrawidth = 0
self.extraheight = 0
self.buttonscrollamount = 0.10
self.vbar = false
self.hbar = false
self.internal = false
self.selectednode = false
self.OnSelectNode = nil
self.children = {}
self.internals = {}
self:SetDrawFunc()
end
--[[---------------------------------------------------------
- func: update(deltatime)
- desc: updates the object
--]]---------------------------------------------------------
function newobject:update(dt)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
local alwaysupdate = self.alwaysupdate
if not visible then
if not alwaysupdate then
return
end
end
self:CheckHover()
local parent = self.parent
local base = loveframes.base
local update = self.Update
-- move to parent if there is a parent
if parent ~= base then
self.x = self.parent.x + self.staticx
self.y = self.parent.y + self.staticy
end
self.itemwidth = 0
self.itemheight = 0
for k, v in ipairs(self.children) do
v.x = (v.parent.x + v.staticx) - self.offsetx
v.y = (self.y + self.itemheight) - self.offsety
if v.width > self.itemwidth then
self.itemwidth = v.width
end
self.itemheight = self.itemheight + v.height
v:update(dt)
end
if self.vbar then
self.itemwidth = self.itemwidth + 16 + 5
end
self.extrawidth = self.itemwidth - self.width
self.extraheight = self.itemheight - self.height
if self.itemheight > self.height then
if not self.vbar then
local scrollbody = loveframes.objects["scrollbody"]:new(self, "vertical")
table.insert(self.internals, scrollbody)
self.vbar = true
if self.hbar then
local vbody = self:GetVerticalScrollBody()
local vbodyheight = vbody:GetHeight() - 15
local hbody = self:GetHorizontalScrollBody()
local hbodywidth = hbody:GetWidth() - 15
vbody:SetHeight(vbodyheight)
hbody:SetWidth(hbodywidth)
end
end
else
if self.vbar then
self:GetVerticalScrollBody():Remove()
self.vbar = false
self.offsety = 0
if self.hbar then
local hbody = self:GetHorizontalScrollBody()
local hbodywidth = hbody:GetWidth() - 15
hbody:SetWidth(hbodywidth)
end
end
end
if self.itemwidth > self.width then
if not self.hbar then
local scrollbody = loveframes.objects["scrollbody"]:new(self, "horizontal")
table.insert(self.internals, scrollbody)
self.hbar = true
if self.vbar then
local vbody = self:GetVerticalScrollBody()
local hbody = self:GetHorizontalScrollBody()
vbody:SetHeight(vbody:GetHeight() - 15)
hbody:SetWidth(hbody:GetWidth() - 15)
end
end
else
if self.hbar then
self:GetHorizontalScrollBody():Remove()
self.hbar = false
self.offsetx = 0
if self.vbar then
local vbody = self:GetVerticalScrollBody()
if vbody then
vbody:SetHeight(vbody:GetHeight() + 15)
end
end
end
end
for k, v in ipairs(self.internals) do
v:update(dt)
end
if update then
update(self, dt)
end
end
--[[---------------------------------------------------------
- func: draw()
- desc: draws the object
--]]---------------------------------------------------------
function newobject:draw()
if loveframes.state ~= self.state then
return
end
if not self.visible then
return
end
local stencilfunc
if self.vbar and not self.hbar then
stencilfunc = function() love.graphics.rectangle("fill", self.x, self.y, self.width - 16, self.height) end
elseif self.hbar and not self.vbar then
stencilfunc = function() love.graphics.rectangle("fill", self.x, self.y, self.width, self.height - 16) end
elseif self.vbar and self.hbar then
stencilfunc = function() love.graphics.rectangle("fill", self.x, self.y, self.width - 16, self.height - 16) end
end
self:SetDrawOrder()
love.graphics.stencil(stencilfunc)
love.graphics.setStencilTest("greater", 0)
local drawfunc = self.Draw or self.drawfunc
if drawfunc then
drawfunc(self)
end
local children = self.children
if children then
for k, v in ipairs(children) do
v:draw()
end
end
love.graphics.setStencilTest()
local internals = self.internals
if internals then
for k, v in ipairs(internals) do
v:draw()
end
end
end
--[[---------------------------------------------------------
- func: mousepressed(x, y, button)
- desc: called when the player presses a mouse button
--]]---------------------------------------------------------
function newobject:mousepressed(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
for k, v in ipairs(self.internals) do
v:mousepressed(x, y, button)
end
for k, v in ipairs(self.children) do
v:mousepressed(x, y, button)
end
end
--[[---------------------------------------------------------
- func: mousereleased(x, y, button)
- desc: called when the player releases a mouse button
--]]---------------------------------------------------------
function newobject:mousereleased(x, y, button)
local state = loveframes.state
local selfstate = self.state
if state ~= selfstate then
return
end
local visible = self.visible
if not visible then
return
end
for k, v in ipairs(self.internals) do
v:mousereleased(x, y, button)
end
for k, v in ipairs(self.children) do
v:mousereleased(x, y, button)
end
end
--[[---------------------------------------------------------
- func: AddNode(text)
- desc: adds a node to the object
--]]---------------------------------------------------------
function newobject:AddNode(text)
local node = loveframes.objects["treenode"]:new()
node.parent = self
node.tree = self
node.text = text
node.staticx = 0
node.staticy = self.itemheight
table.insert(self.children, node)
return node
end
--[[---------------------------------------------------------
- func: RemoveNode(id)
- desc: removes a node from the object
--]]---------------------------------------------------------
function newobject:RemoveNode(id)
for k, v in ipairs(self.children) do
if k == id then
v:Remove()
break
end
end
end
--[[---------------------------------------------------------
- func: GetVerticalScrollBody()
- desc: gets the object's vertical scroll body
--]]---------------------------------------------------------
function newobject:GetVerticalScrollBody()
local vbar = self.vbar
local internals = self.internals
local item = false
if vbar then
for k, v in ipairs(internals) do
if v.type == "scrollbody" and v.bartype == "vertical" then
item = v
end
end
end
return item
end
--[[---------------------------------------------------------
- func: GetHorizontalScrollBody()
- desc: gets the object's horizontal scroll body
--]]---------------------------------------------------------
function newobject:GetHorizontalScrollBody()
local hbar = self.hbar
local internals = self.internals
local item = false
if hbar then
for k, v in ipairs(internals) do
if v.type == "scrollbody" and v.bartype == "horizontal" then
item = v
end
end
end
return item
end
---------- module end ----------
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

View File

@ -0,0 +1,519 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="256"
height="256"
viewBox="0 0 256 256"
version="1.1"
id="svg8"
inkscape:version="0.92.1 r15371"
sodipodi:docname="drawing.svg">
<defs
id="defs2">
<linearGradient
id="linearGradient4579"
osb:paint="solid">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4577" />
</linearGradient>
<linearGradient
id="linearGradient4573"
osb:paint="solid">
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="0"
id="stop4571" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4573"
id="linearGradient4575"
x1="-24"
y1="477.26664"
x2="-8"
y2="477.26664"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4573"
id="linearGradient4581"
x1="2e-07"
y1="294.88327"
x2="4.2333331"
y2="294.88327"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.7795276,0,0,3.7795276,0,-637.25295)" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#ffffff"
borderopacity="1"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="0.35"
inkscape:cx="400"
inkscape:cy="560"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:showpageshadow="false"
inkscape:pagecheckerboard="false"
units="px"
guidecolor="#9191ff"
guideopacity="0.49803922"
guidehicolor="#ff9191"
guidehiopacity="0.49803922"
inkscape:snap-bbox="true"
inkscape:bbox-paths="false"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="false"
inkscape:snap-intersection-paths="false"
inkscape:snap-smooth-nodes="true"
inkscape:object-nodes="true"
inkscape:object-paths="false"
scale-x="1">
<inkscape:grid
type="xygrid"
id="grid4485"
empspacing="8"
color="#6969ff"
opacity="0.1254902"
empcolor="#8c69ff"
empopacity="0.25098039" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-229.26664)">
<rect
style="opacity:1;fill:url(#linearGradient4575);fill-opacity:1;stroke:none;stroke-width:2.00000238;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="rect4487"
width="16"
height="16.000008"
x="-24"
y="469.26663"
ry="0"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96" />
<g
id="radio-off"
inkscape:label="#g4553">
<rect
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
ry="0"
y="469.26651"
x="7.5590555e-07"
height="15.999994"
width="15.999999"
id="use4500"
style="opacity:0.25;fill:url(#linearGradient4581);fill-opacity:1;stroke:none;stroke-width:2.00000143;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<path
id="path4489"
transform="translate(0,229.26664)"
d="M 8 240 C 3.5817219 240 -2.2091392e-07 243.58172 0 248 C -2.2091392e-07 252.41828 3.5817219 256 8 256 C 12.418278 256 16 252.41828 16 248 C 16 243.58172 12.418278 240 8 240 z M 8 241 A 7 7.0000129 0 0 1 15 248 A 7 7.0000129 0 0 1 8 255 A 7 7.0000129 0 0 1 1 248 A 7 7.0000129 0 0 1 8 241 z "
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.99999988;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<ellipse
ry="7.5000138"
rx="7.5"
cy="477.26663"
cx="8"
id="path4494"
style="opacity:0.15;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:4.28571796;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
</g>
<g
id="radio-on"
inkscape:label="radio-on"
transform="matrix(3.7795276,0,0,3.7795276,1.5880691e-7,-637.25295)">
<rect
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
ry="0"
y="292.7666"
x="6.3499999"
height="4.2333317"
width="4.2333331"
id="use4502"
style="opacity:0.25;fill:url(#linearGradient4573);fill-opacity:1;stroke:none;stroke-width:0.52916706;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<ellipse
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.60476083;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="ellipse4506"
cx="8.4666672"
cy="294.8833"
rx="1.0583333"
ry="1.0583297" />
<path
id="path4521"
transform="matrix(0.26458333,0,0,0.26458333,0,229.26664)"
d="m 32,240 c -4.418278,0 -8,3.58169 -8,8 0,4.41827 3.581722,8 8,8 4.418278,0 8,-3.58173 8,-8 0,-4.41831 -3.581722,-8 -8,-8 z m 0,6 a 1.9999999,1.9999945 0 0 1 2,2 1.9999999,1.9999945 0 0 1 -2,2 1.9999999,1.9999945 0 0 1 -2,-2 1.9999999,1.9999945 0 0 1 2,-2 z"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.99999988;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
inkscape:connector-curvature="0" />
</g>
<g
id="check-off"
inkscape:label="#g4549"
transform="matrix(3.7795276,0,0,3.7795276,0,-637.25295)">
<rect
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
ry="0"
y="286.41663"
x="2e-07"
height="4.2333317"
width="4.2333331"
id="use4518"
style="opacity:0.25;fill:url(#linearGradient4573);fill-opacity:1;stroke:none;stroke-width:0.52916706;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<path
id="rect4526"
transform="matrix(0.26458333,0,0,0.26458333,0,229.26664)"
d="m 2,216 c -1.10799994,0 -2,0.892 -2,2 v 12 c 0,1.108 0.89200006,2 2,2 h 12 c 1.108,0 2,-0.892 2,-2 v -12 c 0,-1.108 -0.892,-2 -2,-2 z m -1,1 h 14 v 14 H 1 Z"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.99999988;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssssssssccccc" />
<rect
y="286.61508"
x="0.1984375"
height="3.8364582"
width="3.8364582"
id="rect4531"
style="opacity:0.15;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.54806548;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
</g>
<g
id="check-on"
inkscape:label="#g4554"
transform="matrix(3.7795276,0,0,3.7795276,1.5880691e-7,-637.25295)">
<rect
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
ry="0"
y="286.41663"
x="6.3499999"
height="4.2333317"
width="4.2333331"
id="use4514"
style="opacity:0.25;fill:url(#linearGradient4573);fill-opacity:1;stroke:none;stroke-width:0.52916706;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<path
id="rect4533"
transform="matrix(0.26458333,0,0,0.26458333,0,229.26664)"
d="m 26,216 c -1.108,0 -2,0.892 -2,2 v 12 c 0,1.108 0.892,2 2,2 h 12 c 1.108,0 2,-0.892 2,-2 v -12 c 0,-1.108 -0.892,-2 -2,-2 z m 9,9 h -2 v 2 h -2 v -2 h -2 v -2 h 2 v -2 h 2 v 2 h 2 z"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.99999988;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssssssssccccccccccccc" />
<rect
y="286.68121"
x="6.614583"
height="3.7041667"
width="3.7041667"
id="rect4544"
style="opacity:0.25;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
</g>
<g
id="arrow-up"
inkscape:label="#g4673"
transform="matrix(3.7795278,0,0,3.7795278,-4.3501574e-6,-637.25301)">
<rect
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
ry="0"
y="286.41663"
x="19.049999"
height="4.2333317"
width="4.2333331"
id="use4508"
style="opacity:0.25;fill:url(#linearGradient4573);fill-opacity:1;stroke:none;stroke-width:0.52916706;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="rect4655"
transform="matrix(0.26458333,0,0,0.26458333,0,229.26664)"
d="m 80,221 -4.999999,5 h 10 z"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.99999988;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
</g>
<g
inkscape:label="#g4673"
id="arrow-down"
transform="matrix(-3.7795278,0,0,-3.7795278,160,1567.7863)">
<rect
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
ry="0"
y="286.41663"
x="19.049999"
height="4.2333317"
width="4.2333331"
id="use4675"
style="opacity:0.25;fill:url(#linearGradient4573);fill-opacity:1;stroke:none;stroke-width:0.52916706;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.99999988;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 80,221 -4.999999,5 h 10 z"
transform="matrix(0.26458333,0,0,0.26458333,0,229.26664)"
id="path4677"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
</g>
<g
inkscape:label="#g4673"
id="arrow-right"
transform="matrix(0,3.779529,-3.779529,0,1194.52,373.26661)">
<rect
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
ry="0"
y="286.41663"
x="19.049999"
height="4.2333317"
width="4.2333331"
id="use4681"
style="opacity:0.25;fill:url(#linearGradient4573);fill-opacity:1;stroke:none;stroke-width:0.52916706;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.99999988;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 80,221 -4.999999,5 h 10 z"
transform="matrix(0.26458333,0,0,0.26458333,0,229.26664)"
id="path4683"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
</g>
<g
inkscape:label="#g4673"
id="arrow-left"
transform="matrix(0,-3.779529,3.779529,0,-986.52,557.26667)">
<rect
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
ry="0"
y="286.41663"
x="19.049999"
height="4.2333317"
width="4.2333331"
id="use4687"
style="opacity:0.25;fill:url(#linearGradient4573);fill-opacity:1;stroke:none;stroke-width:0.52916706;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.99999988;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 80,221 -4.999999,5 h 10 z"
transform="matrix(0.26458333,0,0,0.26458333,0,229.26664)"
id="path4689"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
</g>
<g
inkscape:label="#g4653"
id="collapse"
transform="matrix(3.7795278,0,0,3.7795278,-48.000017,-661.25298)">
<rect
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
ry="0"
y="286.41663"
x="12.7"
height="4.2333317"
width="4.2333331"
id="use4524"
style="opacity:0.25;fill:url(#linearGradient4573);fill-opacity:1;stroke:none;stroke-width:0.52916706;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<rect
y="-15.875"
x="288.26871"
height="2.116663"
width="0.52916324"
id="rect4529"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
transform="rotate(90)" />
</g>
<g
inkscape:label="#g4653"
id="expand"
transform="matrix(3.7795278,0,0,3.7795278,-24.000004,-661.25298)">
<rect
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
ry="0"
y="286.41663"
x="12.7"
height="4.2333317"
width="4.2333331"
id="use4533"
style="opacity:0.25;fill:url(#linearGradient4573);fill-opacity:1;stroke:none;stroke-width:0.52916706;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="rect4535"
width="0.52916789"
height="2.1166754"
x="14.552083"
y="287.47498" />
<rect
y="-15.875"
x="288.26871"
height="2.1166668"
width="0.52916324"
id="rect4537"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
transform="rotate(90)" />
</g>
<g
inkscape:label="#g4554"
id="tree-node-button-close"
transform="matrix(3.7795276,0,0,3.7795276,24,-661.25295)">
<rect
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
ry="0"
y="286.41663"
x="6.3499999"
height="4.2333317"
width="4.2333331"
id="use4541"
style="opacity:0.25;fill:url(#linearGradient4573);fill-opacity:1;stroke:none;stroke-width:0.52916706;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<path
sodipodi:nodetypes="sssssssssccccc"
inkscape:connector-curvature="0"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.99999988;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 26,216 c -1.108,0 -2,0.892 -2,2 v 12 c 0,1.108 0.892,2 2,2 h 12 c 1.108,0 2,-0.892 2,-2 v -12 c 0,-1.108 -0.892,-2 -2,-2 z m 12,9 H 26 v -2 h 12 z"
transform="matrix(0.26458333,0,0,0.26458333,0,229.26664)"
id="path4543" />
</g>
<g
inkscape:label="#g4554"
id="tree-node-button-open"
transform="matrix(3.7795276,0,0,3.7795276,48,-661.25295)">
<rect
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
ry="0"
y="286.41663"
x="6.3499999"
height="4.2333317"
width="4.2333331"
id="use4549"
style="opacity:0.25;fill:url(#linearGradient4573);fill-opacity:1;stroke:none;stroke-width:0.52916706;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<path
sodipodi:nodetypes="sssssssssccccccccccccc"
inkscape:connector-curvature="0"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.99999988;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 26,216 c -1.108,0 -2,0.892 -2,2 v 12 c 0,1.108 0.892,2 2,2 h 12 c 1.108,0 2,-0.892 2,-2 v -12 c 0,-1.108 -0.892,-2 -2,-2 z m 12,9 h -5 v 5 h -2 v -5 h -5 v -2 h 5 v -5 h 2 v 5 h 5 z"
transform="matrix(0.26458333,0,0,0.26458333,0,229.26664)"
id="path4551" />
</g>
<g
id="close"
inkscape:label="#g4570"
transform="matrix(3.7795278,0,0,3.7795278,-2.8201574e-6,-637.253)">
<rect
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
ry="0"
y="286.41663"
x="12.7"
height="4.2333317"
width="4.2333331"
id="use4510"
style="opacity:0.25;fill:url(#linearGradient4573);fill-opacity:1;stroke:none;stroke-width:0.52916706;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<rect
transform="rotate(-45)"
y="212.91331"
x="-193.81148"
height="3.175"
width="0.52916664"
id="rect4646"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<rect
transform="rotate(45)"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="rect4648"
width="0.52916664"
height="3.175"
x="214.23624"
y="191.95938" />
</g>
<g
id="multichoice-arrow"
inkscape:label="#g4588"
transform="matrix(3.7795278,0,0,3.7795278,-2.2136603e-5,-637.25301)">
<rect
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
ry="0"
y="-297"
x="-16.933338"
height="4.2333317"
width="4.2333331"
id="use4693"
style="opacity:0.25;fill:url(#linearGradient4573);fill-opacity:1;stroke:none;stroke-width:0.52916706;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
transform="scale(-1)" />
<rect
transform="rotate(45)"
y="196.6687"
x="219.21014"
height="2.1166666"
width="0.52916664"
id="rect4579"
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="rect4583"
width="0.52916664"
height="2.1166666"
x="198.25621"
y="217.62263"
transform="matrix(-0.70710678,0.70710678,0.70710678,0.70710678,0,0)" />
</g>
<g
id="slider"
inkscape:label="#g4651"
transform="matrix(3.7795278,0,0,3.7795278,-5.7011931e-6,-637.25301)">
<rect
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
ry="0"
y="280.06662"
x="25.4"
height="4.2333317"
width="4.2333331"
id="use4590"
style="opacity:0.25;fill:url(#linearGradient4573);fill-opacity:1;stroke:none;stroke-width:0.52916706;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<path
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="M 27.516667,280.06664 A 2.1166665,2.1166665 0 0 0 25.4,282.18331 a 2.1166665,2.1166665 0 0 0 2.116667,2.11666 2.1166665,2.1166665 0 0 0 2.116666,-2.11666 2.1166665,2.1166665 0 0 0 -2.116666,-2.11667 z m 0,0.52917 a 1.5875,1.5874941 0 0 1 1.5875,1.5875 1.5875,1.5874941 0 0 1 -1.5875,1.5875 1.5875,1.5874941 0 0 1 -1.5875,-1.5875 1.5875,1.5874941 0 0 1 1.5875,-1.5875 z"
id="path4592"
inkscape:connector-curvature="0" />
<ellipse
ry="1.8520854"
rx="1.8520833"
cy="282.18332"
cx="27.516666"
id="path4635"
style="opacity:0.35;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.4630211;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers" />
<ellipse
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.19843718;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
id="ellipse4645"
cx="27.516666"
cy="282.18332"
rx="0.79374993"
ry="0.79374754" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

Some files were not shown because too many files have changed in this diff Show More