Docs -> frames
Updated the frame object in docs
This commit is contained in:
BIN
docs/_media/dynamic-frames.mp4
Normal file
BIN
docs/_media/dynamic-frames.mp4
Normal file
Binary file not shown.
BIN
docs/_media/frames-with-menubars.mp4
Normal file
BIN
docs/_media/frames-with-menubars.mp4
Normal file
Binary file not shown.
BIN
docs/_media/frames-with-sidebar.mp4
Normal file
BIN
docs/_media/frames-with-sidebar.mp4
Normal file
Binary file not shown.
BIN
docs/_media/resizable-frames.mp4
Normal file
BIN
docs/_media/resizable-frames.mp4
Normal file
Binary file not shown.
BIN
docs/_media/scrollable-frames.mp4
Normal file
BIN
docs/_media/scrollable-frames.mp4
Normal file
Binary file not shown.
@@ -28,6 +28,7 @@ some special functionality to create very advanced programs.
|
||||
|[setScrollAmount](objects/Frame/setScrollAmount.md)|Sets how far the user is allowed to scroll
|
||||
|
||||
This is how you would implement frames via xml:
|
||||
|
||||
```xml
|
||||
<frame>
|
||||
<frame width="parent.w * 0.5" bg="red">
|
||||
@@ -37,4 +38,297 @@ This is how you would implement frames via xml:
|
||||
<textfield bg="green" x="2" width="parent.w-2" />
|
||||
</frame>
|
||||
</frame>
|
||||
```
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
Here are some examples on how you can use frames to create very advanced programs. Because of the screen size limitation of CC:Tweaked frames can become very useful in almost every scenario. You will find some examples here on how you could implement them.
|
||||
|
||||
### Menubar for switching frames
|
||||
|
||||
This is a example on how you can create a menubar which switches your frames (without animation).
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt") -- we need basalt here
|
||||
|
||||
local main = basalt.createFrame():setTheme({FrameBG = colors.lightGray, FrameFG = colors.black}) -- we change the default bg and fg color for frames
|
||||
|
||||
local sub = { -- here we create a table where we gonna add some frames
|
||||
main:addFrame():setPosition(1, 2):setSize("parent.w", "parent.h - 1"), -- obviously the first one should be shown on program start
|
||||
main:addFrame():setPosition(1, 2):setSize("parent.w", "parent.h - 1"):hide(),
|
||||
main:addFrame():setPosition(1, 2):setSize("parent.w", "parent.h - 1"):hide(),
|
||||
}
|
||||
|
||||
local function openSubFrame(id) -- we create a function which switches the frame for us
|
||||
if(sub[id]~=nil)then
|
||||
for k,v in pairs(sub)do
|
||||
v:hide()
|
||||
end
|
||||
sub[id]:show()
|
||||
end
|
||||
end
|
||||
|
||||
local menubar = main:addMenubar():setScrollable() -- we create a menubar in our main frame.
|
||||
:setSize("parent.w")
|
||||
:onChange(function(self, val)
|
||||
openSubFrame(self:getItemIndex()) -- here we open the sub frame based on the table index
|
||||
end)
|
||||
:addItem("Example 1")
|
||||
:addItem("Example 2")
|
||||
:addItem("Example 3")
|
||||
|
||||
-- Now we can change our sub frames, if you want to access a sub frame just use sub[subid], some examples:
|
||||
sub[1]:addButton():setPosition(2, 2)
|
||||
|
||||
sub[2]:addLabel():setText("Hello World!"):setPosition(2, 2)
|
||||
|
||||
sub[3]:addLabel():setText("Now we're on example 3!"):setPosition(2, 2)
|
||||
sub[3]:addButton():setText("No functionality"):setPosition(2, 4):setSize(18, 3)
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
<video width="600" controls autoplay loop muted>
|
||||
<source src="./_media/frames-with-menubars.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
### Sidebar with buttons to switch frames
|
||||
|
||||
Here we will find out how to create a sidebar (which are also just frames) - the sidebar should have buttons to opens the frames for us.
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt") -- we need basalt here
|
||||
|
||||
local main = basalt.createFrame():setTheme({FrameBG = colors.lightGray, FrameFG = colors.black})
|
||||
|
||||
--[[
|
||||
Here we create the sidebar, on focus it should change the position to parent.w - (self.w-1) which "opens the frame"
|
||||
when the focus gets lost we simply change the position to "parent.w"
|
||||
As you can see we add :setZIndex(25) - this makes sure the sidebar frame is always more important than our normal sub frames.
|
||||
:setScrollable just makes the sidebar frame scrollable (in case you're adding more frames)
|
||||
]]
|
||||
local sidebar = main:addFrame():setBackground(colors.gray):setPosition("parent.w", 1):setSize(15, "parent.h"):setZIndex(25):setScrollable()
|
||||
:onGetFocus(function(self)
|
||||
self:setPosition("parent.w - (self.w-1)")
|
||||
end)
|
||||
:onLoseFocus(function(self)
|
||||
self:setPosition("parent.w")
|
||||
end)
|
||||
|
||||
-- Once again we add 3 frames, the first one should be immediatly visible
|
||||
local sub = {
|
||||
main:addFrame():setPosition(1, 1):setSize("parent.w", "parent.h"),
|
||||
main:addFrame():setPosition(1, 1):setSize("parent.w", "parent.h"):hide(),
|
||||
main:addFrame():setPosition(1, 1):setSize("parent.w", "parent.h"):hide(),
|
||||
}
|
||||
|
||||
--This part of the code adds buttons based on the sub table.
|
||||
local y = 2
|
||||
for k,v in pairs(sub)do
|
||||
sidebar:addButton():setText("Example "..k) -- creating the button and adding a name k is just the index
|
||||
:setBackground(colors.black)
|
||||
:setForeground(colors.lightGray)
|
||||
:setSize("parent.w - 2", 3)
|
||||
:setPosition(2, y)
|
||||
:onClick(function() -- here we create a on click event which hides ALL sub frames and then shows the one which is linked to the button
|
||||
for a, b in pairs(sub)do
|
||||
b:hide()
|
||||
v:show()
|
||||
end
|
||||
end)
|
||||
y = y + 4
|
||||
end
|
||||
|
||||
sub[1]:addButton():setPosition(2, 2)
|
||||
|
||||
sub[2]:addLabel():setText("Hello World!"):setPosition(2, 2)
|
||||
|
||||
sub[3]:addLabel():setText("Now we're on example 3!"):setPosition(2, 2)
|
||||
sub[3]:addButton():setText("No functionality"):setPosition(2, 4):setSize(18, 3)
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
<video width="600" controls autoplay loop muted>
|
||||
<source src="./_media/frames-with-sidebar.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
### Movable frames with a program object
|
||||
|
||||
In this example you will see how you can add movable frames with a program object in it. It also shows you how you dynamically add new frames.
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local main = basalt.createFrame():setTheme({FrameBG = colors.lightGray, FrameFG = colors.black})
|
||||
|
||||
local id = 1
|
||||
local processes = {}
|
||||
|
||||
local function openProgram(path, title, x, y, w, h)
|
||||
local pId = id
|
||||
id = id + 1
|
||||
local f = main:addFrame()
|
||||
:setMovable()
|
||||
:setSize(w or 30, h or 12)
|
||||
:setPosition(x or math.random(2, 12), y or math.random(2, 8))
|
||||
|
||||
f:addLabel()
|
||||
:setSize("parent.w", 1)
|
||||
:setBackground(colors.black)
|
||||
:setForeground(colors.lightGray)
|
||||
:setText(title or "New Program")
|
||||
|
||||
f:addProgram()
|
||||
:setSize("parent.w", "parent.h - 1")
|
||||
:setPosition(1, 2)
|
||||
:execute(path or "rom/programs/shell.lua")
|
||||
|
||||
f:addButton()
|
||||
:setSize(1, 1)
|
||||
:setText("X")
|
||||
:setBackground(colors.black)
|
||||
:setForeground(colors.red)
|
||||
:setPosition("parent.w", 1)
|
||||
:onClick(function()
|
||||
f:remove()
|
||||
processes[pId] = nil
|
||||
end)
|
||||
processes[pId] = f
|
||||
return f
|
||||
end
|
||||
|
||||
openProgram("rom/programs/fun/worm.lua")
|
||||
|
||||
main:addButton():setPosition("parent.w - 16", 2):setText("Open"):onClick(function()
|
||||
openProgram()
|
||||
end)
|
||||
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
<video width="600" controls autoplay loop muted>
|
||||
<source src="./_media/dynamic-frames.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
|
||||
### Resizable frames
|
||||
|
||||
If you want to make your frames resizeable, there is no way offered by basalt - so you would have to do it yourself. However such a implementation is very simple as you can see here.
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local main = basalt.createFrame():setTheme({FrameBG = colors.black, FrameFG = colors.lightGray})
|
||||
|
||||
local sub = main:addFrame():setSize(25, 12):setPosition(3, 3)
|
||||
|
||||
local function makeResizeable(frame, minW, minH, maxW, maxH)
|
||||
minW = minW or 4
|
||||
minH = minH or 4
|
||||
maxW = maxW or 99
|
||||
maxH = maxH or 99
|
||||
local btn = frame:addButton()
|
||||
:setPosition("parent.w", "parent.h")
|
||||
:setSize(1, 1)
|
||||
:setText("/")
|
||||
:setForeground(colors.blue)
|
||||
:setBackground(colors.black)
|
||||
:onDrag(function(self, event, btn, xOffset, yOffset)
|
||||
local w, h = frame:getSize()
|
||||
local wOff, hOff = w, h
|
||||
if(w+xOffset-1>=minW)and(w+xOffset-1<=maxW)then
|
||||
wOff = w+xOffset-1
|
||||
end
|
||||
if(h+yOffset-1>=minH)and(h+yOffset-1<=maxH)then
|
||||
hOff = h+yOffset-1
|
||||
end
|
||||
frame:setSize(wOff, hOff)
|
||||
end)
|
||||
end
|
||||
|
||||
makeResizeable(sub, 8, 4)
|
||||
|
||||
sub:addLabel():setText("Hello World")
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
<video width="600" controls autoplay loop muted>
|
||||
<source src="./_media/resizable-frames.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
### Scrollable frames
|
||||
|
||||
Another important feature of frames is the possibility to make them scrollable. Basalt only provides vertical scrolling for frames. If you want to make horizontal scrolling possible, you need to do it yourself. Also, if you're using :setScrollable() the amount to scroll is based on the object's y-position + height - you can change this by using :setScrollAmount(amount). Only count's for the basalt implementation of scrollable frames.
|
||||
|
||||
<details>
|
||||
<summary>Click here to show code</summary>
|
||||
|
||||
|
||||
```lua
|
||||
local basalt = require("basalt")
|
||||
|
||||
local main = basalt.createFrame():setTheme({FrameBG = colors.black, FrameFG = colors.lightGray})
|
||||
|
||||
-- Vertical scrolling is pretty simple, as you can tell:
|
||||
local sub1 = main:addFrame():setScrollable():setSize(20, 15):setPosition(2, 2)
|
||||
|
||||
sub1:addLabel():setPosition(3, 2):setText("Scrollable")
|
||||
sub1:addLabel():setPosition(3, 12):setText("Inside")
|
||||
sub1:addLabel():setPosition(3, 20):setText("Outside")
|
||||
|
||||
-- Here we create a custom scroll event as you can see we dont add a :setScrollable() method to our frame, instead we add a custom scroll event
|
||||
local objects = {}
|
||||
|
||||
local sub2 = main:addFrame():setPosition(23, 2):setSize(25, 5):onScroll(function(self, event, dir)
|
||||
local maxScroll = 0
|
||||
for k,v in pairs(objects)do -- here we iterate trough every object and get their x position + width this way we can find out what's the maximum allowed value to scroll
|
||||
local x = v:getX()
|
||||
local w = v:getWidth()
|
||||
maxScroll = x + w > maxScroll and x + w or maxScroll -- if you don't understand this line, http://lua-users.org/wiki/TernaryOperator
|
||||
end
|
||||
local xOffset = self:getOffset()
|
||||
if(xOffset+dir>=0 and xOffset+dir<=maxScroll-self:getWidth())then
|
||||
self:setOffset(xOffset+dir, 0)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Because we need to iterate the objects, we add them into a table.
|
||||
table.insert(objects, sub2:addButton():setPosition(2, 2):setText("Scrollable"))
|
||||
table.insert(objects, sub2:addButton():setPosition(16, 2):setText("Inside"))
|
||||
table.insert(objects, sub2:addButton():setPosition(30, 2):setText("Outside"))
|
||||
|
||||
basalt.autoUpdate()
|
||||
```
|
||||
|
||||
</details>
|
||||
<br>
|
||||
<video width="600" controls autoplay loop muted>
|
||||
<source src="./_media/scrollable-frames.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
@@ -12,7 +12,7 @@ Program objects are here for opening other executable programs in your main prog
|
||||
|[injectEvent](objects/Program/injectEvent.md)|Injects a event into the program
|
||||
|[injectEvents](objects/Program/injectEvents.md)|Injects a table of events
|
||||
|[getQueuedEvents](objects/Program/getQueuedEvents.md)|Returns currently queued events
|
||||
|[setEnviroment](objects/Program/setEnviroment.md)|CHanges the default enviroment to a custom one
|
||||
|[setEnviroment](objects/Program/setEnviroment.md)|Changes the default enviroment to a custom one
|
||||
|
||||
# Events
|
||||
|
||||
|
||||
Reference in New Issue
Block a user