@ -0,0 +1,10 @@
|
||||
glyph-height: 14
|
||||
glyph-spacing: [1, 1]
|
||||
top-margin: 2
|
||||
image: helvetica-11px-bold.png
|
||||
image-glyph-size: [16, 16]
|
||||
|
||||
glyph-widths:
|
||||
32: 4
|
||||
65: 8
|
||||
|
After Width: | Height: | Size: 8.3 KiB |
@ -0,0 +1,9 @@
|
||||
glyph-height: 14
|
||||
glyph-spacing: [1, 1]
|
||||
top-margin: 1
|
||||
image: helvetica-11px.png
|
||||
image-glyph-size: [16, 16]
|
||||
|
||||
glyph-widths:
|
||||
32: 4
|
||||
|
After Width: | Height: | Size: 8.1 KiB |
@ -0,0 +1,10 @@
|
||||
glyph-height: 16
|
||||
glyph-spacing: [1, 1]
|
||||
top-margin: 2
|
||||
image: helvetica-12px-bold.png
|
||||
image-glyph-size: [18, 18]
|
||||
|
||||
glyph-widths:
|
||||
32: 4
|
||||
65: 9
|
||||
|
After Width: | Height: | Size: 9.8 KiB |
@ -0,0 +1,9 @@
|
||||
glyph-height: 15
|
||||
glyph-spacing: [1, 1]
|
||||
top-margin: 1
|
||||
image: helvetica-12px.png
|
||||
image-glyph-size: [16, 16]
|
||||
|
||||
glyph-widths:
|
||||
32: 4
|
||||
65: 8
|
After Width: | Height: | Size: 9.0 KiB |
@ -0,0 +1,10 @@
|
||||
glyph-height: 16
|
||||
glyph-spacing: [1, 1]
|
||||
top-margin: 2
|
||||
image: helvetica-14px-bold.png
|
||||
image-glyph-size: [20, 20]
|
||||
|
||||
glyph-widths:
|
||||
32: 4
|
||||
65: 9
|
||||
|
After Width: | Height: | Size: 12 KiB |
@ -1,8 +0,0 @@
|
||||
glyph height: 14
|
||||
glyph spacing: [0, 1]
|
||||
top margin: 0
|
||||
image: sans-11px-bold.png
|
||||
image glyph size: [16, 16]
|
||||
|
||||
glyph widths:
|
||||
32: 4
|
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB |
@ -1,8 +0,0 @@
|
||||
glyph height: 14
|
||||
glyph spacing: [0, 1]
|
||||
top margin: 0
|
||||
image: sans-11px.png
|
||||
image glyph size: [16, 16]
|
||||
|
||||
glyph widths:
|
||||
32: 4
|
@ -1,8 +0,0 @@
|
||||
glyph height: 14
|
||||
glyph spacing: [0, 1]
|
||||
top margin: 0
|
||||
image: sans-12px-bold.png
|
||||
image glyph size: [20, 16]
|
||||
|
||||
glyph widths:
|
||||
32: 4
|
Before Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 13 KiB |
@ -1,8 +0,0 @@
|
||||
glyph height: 16
|
||||
glyph spacing: [0, 1]
|
||||
top margin: 0
|
||||
image: sans-12px.png
|
||||
image glyph size: [20, 16]
|
||||
|
||||
glyph widths:
|
||||
32: 4
|
@ -1,9 +0,0 @@
|
||||
glyph height: 10
|
||||
glyph spacing: [1, 4]
|
||||
top margin: 3
|
||||
image: tibia-10px-antialised.png
|
||||
image glyph size: [8, 16]
|
||||
first glyph: 32
|
||||
|
||||
glyph widths:
|
||||
32: 2
|
Before Width: | Height: | Size: 14 KiB |
@ -1,9 +0,0 @@
|
||||
glyph height: 10
|
||||
glyph spacing: [1, 1]
|
||||
top margin: 3
|
||||
image: tibia-10px-monochrome.png
|
||||
image glyph size: [8, 16]
|
||||
first glyph: 32
|
||||
|
||||
glyph widths:
|
||||
32: 2
|
Before Width: | Height: | Size: 3.1 KiB |
@ -1,232 +0,0 @@
|
||||
glyph height: 12
|
||||
glyph spacing: [0, 1]
|
||||
top margin: 3
|
||||
image: tibia-12px-rounded.png
|
||||
image glyph size: [16, 16]
|
||||
first glyph: 32
|
||||
|
||||
glyph widths:
|
||||
32: 4
|
||||
33: 4
|
||||
34: 7
|
||||
35: 9
|
||||
36: 8
|
||||
37: 10
|
||||
38: 10
|
||||
39: 4
|
||||
40: 6
|
||||
41: 6
|
||||
42: 8
|
||||
43: 9
|
||||
44: 4
|
||||
45: 7
|
||||
46: 4
|
||||
47: 8
|
||||
48: 8
|
||||
49: 6
|
||||
50: 8
|
||||
51: 8
|
||||
52: 8
|
||||
53: 8
|
||||
54: 8
|
||||
55: 8
|
||||
56: 8
|
||||
57: 8
|
||||
58: 5
|
||||
59: 5
|
||||
60: 10
|
||||
61: 10
|
||||
62: 10
|
||||
63: 7
|
||||
64: 10
|
||||
65: 9
|
||||
66: 8
|
||||
67: 8
|
||||
68: 9
|
||||
69: 8
|
||||
70: 8
|
||||
71: 9
|
||||
72: 9
|
||||
73: 6
|
||||
74: 7
|
||||
75: 8
|
||||
76: 8
|
||||
77: 10
|
||||
78: 9
|
||||
79: 9
|
||||
80: 8
|
||||
81: 9
|
||||
82: 9
|
||||
83: 8
|
||||
84: 10
|
||||
85: 9
|
||||
86: 8
|
||||
87: 10
|
||||
88: 8
|
||||
89: 8
|
||||
90: 8
|
||||
91: 6
|
||||
92: 8
|
||||
93: 6
|
||||
94: 11
|
||||
95: 9
|
||||
96: 7
|
||||
97: 8
|
||||
98: 8
|
||||
99: 7
|
||||
100: 8
|
||||
101: 8
|
||||
102: 7
|
||||
103: 8
|
||||
104: 8
|
||||
105: 4
|
||||
106: 6
|
||||
107: 8
|
||||
108: 4
|
||||
109: 10
|
||||
110: 8
|
||||
111: 8
|
||||
112: 8
|
||||
113: 8
|
||||
114: 7
|
||||
115: 7
|
||||
116: 7
|
||||
117: 8
|
||||
118: 8
|
||||
119: 10
|
||||
120: 8
|
||||
121: 8
|
||||
122: 7
|
||||
123: 8
|
||||
124: 5
|
||||
125: 8
|
||||
126: 9
|
||||
127: 13
|
||||
128: 8
|
||||
129: 13
|
||||
130: 4
|
||||
131: 8
|
||||
132: 6
|
||||
133: 13
|
||||
134: 8
|
||||
135: 8
|
||||
136: 7
|
||||
137: 20
|
||||
138: 8
|
||||
139: 6
|
||||
140: 13
|
||||
141: 13
|
||||
142: 7
|
||||
143: 13
|
||||
144: 13
|
||||
145: 4
|
||||
146: 4
|
||||
147: 6
|
||||
148: 6
|
||||
149: 8
|
||||
150: 8
|
||||
151: 12
|
||||
152: 7
|
||||
153: 11
|
||||
154: 7
|
||||
155: 6
|
||||
156: 13
|
||||
157: 13
|
||||
158: 7
|
||||
159: 9
|
||||
160: 4
|
||||
161: 5
|
||||
162: 8
|
||||
163: 8
|
||||
164: 8
|
||||
165: 8
|
||||
166: 7
|
||||
167: 8
|
||||
168: 7
|
||||
169: 12
|
||||
170: 7
|
||||
171: 9
|
||||
172: 11
|
||||
173: 6
|
||||
174: 12
|
||||
175: 8
|
||||
176: 7
|
||||
177: 11
|
||||
178: 7
|
||||
179: 7
|
||||
180: 7
|
||||
181: 8
|
||||
182: 8
|
||||
183: 5
|
||||
184: 7
|
||||
185: 7
|
||||
186: 7
|
||||
187: 9
|
||||
188: 15
|
||||
189: 15
|
||||
190: 15
|
||||
191: 7
|
||||
192: 10
|
||||
193: 10
|
||||
194: 10
|
||||
195: 10
|
||||
196: 10
|
||||
197: 10
|
||||
198: 13
|
||||
199: 8
|
||||
200: 7
|
||||
201: 7
|
||||
202: 7
|
||||
203: 7
|
||||
204: 5
|
||||
205: 5
|
||||
206: 5
|
||||
207: 5
|
||||
208: 10
|
||||
209: 8
|
||||
210: 9
|
||||
211: 9
|
||||
212: 9
|
||||
213: 9
|
||||
214: 9
|
||||
215: 11
|
||||
216: 9
|
||||
217: 8
|
||||
218: 8
|
||||
219: 8
|
||||
220: 8
|
||||
221: 9
|
||||
222: 9
|
||||
223: 8
|
||||
224: 8
|
||||
225: 8
|
||||
226: 8
|
||||
227: 8
|
||||
228: 8
|
||||
229: 8
|
||||
230: 12
|
||||
231: 6
|
||||
232: 8
|
||||
233: 8
|
||||
234: 8
|
||||
235: 8
|
||||
236: 5
|
||||
237: 5
|
||||
238: 3
|
||||
239: 3
|
||||
240: 8
|
||||
241: 8
|
||||
242: 8
|
||||
243: 8
|
||||
244: 8
|
||||
245: 8
|
||||
246: 8
|
||||
247: 11
|
||||
248: 8
|
||||
249: 8
|
||||
250: 8
|
||||
251: 8
|
||||
252: 8
|
||||
253: 8
|
||||
254: 8
|
||||
255: 8
|
Before Width: | Height: | Size: 5.8 KiB |
@ -1,9 +0,0 @@
|
||||
glyph height: 8
|
||||
glyph spacing: [0, 1]
|
||||
top margin: 1
|
||||
image: tibia-8px-antialised.png
|
||||
image glyph size: [8, 8]
|
||||
first glyph: 32
|
||||
|
||||
glyph widths:
|
||||
32: 2
|
Before Width: | Height: | Size: 14 KiB |
@ -1,4 +0,0 @@
|
||||
-- some aliases
|
||||
loadUI = UI.load
|
||||
rootUI = UI.getRootContainer()
|
||||
|
@ -1,4 +1,3 @@
|
||||
require 'aliases'
|
||||
require 'enums'
|
||||
require 'constants'
|
||||
require 'util'
|
||||
|
||||
require 'messagebox'
|
@ -1,8 +0,0 @@
|
||||
title: Core
|
||||
notes: Core utilities used by other modules
|
||||
author: edubart
|
||||
version: 1
|
||||
website: https://github.com/edubart/otclient
|
||||
enabled: true
|
||||
script: core.lua
|
||||
|
@ -1,16 +1,16 @@
|
||||
require 'entergame'
|
||||
|
||||
function initializeApplication()
|
||||
mainMenu = loadUI("ui/mainmenu")
|
||||
mainMenu = loadUI("ui/mainmenu", rootUI)
|
||||
end
|
||||
|
||||
function terminateApplication()
|
||||
App.exit()
|
||||
exit()
|
||||
end
|
||||
|
||||
-- here is where everything starts
|
||||
if not initialized then
|
||||
initializeApplication()
|
||||
App.onClose = terminateApplication
|
||||
onClose = terminateApplication
|
||||
initialized = true
|
||||
end
|
||||
|
@ -1,10 +0,0 @@
|
||||
title: Main menu
|
||||
notes: Used to create the main menu
|
||||
enabled: true
|
||||
#dependencies
|
||||
interface: 020
|
||||
author: edubart
|
||||
version: 0.2
|
||||
scripts:
|
||||
- menustate.lua
|
||||
- mainmenu.lua
|
@ -1,67 +1,54 @@
|
||||
%window#enterGameWindow
|
||||
title: Enter Game
|
||||
size: [236, 178]
|
||||
size: [236, 160]
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
onLoad: self:setLocked()
|
||||
|
||||
%label#accountNameLabel
|
||||
skin: large
|
||||
text: Account name
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
margin.left: 18
|
||||
margin.top: 33
|
||||
margin.top: 28
|
||||
|
||||
%label#passwordLabel
|
||||
text: "Password:"
|
||||
%textEdit#accountNameTextEdit
|
||||
text: tibialua0
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.top: prev.bottom
|
||||
margin.left: 18
|
||||
margin.top: 62
|
||||
margin.right: 18
|
||||
|
||||
%label#createAccountLabel
|
||||
text: |
|
||||
If you don't have
|
||||
an account yet
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
margin.left: 18
|
||||
margin.top: 87
|
||||
%label#passwordLabel
|
||||
skin: large
|
||||
text: Password
|
||||
anchors.left: prev.left
|
||||
anchors.top: prev.bottom
|
||||
margin.top: 8
|
||||
|
||||
%button#createAccountButton
|
||||
text: Create Account
|
||||
%textEdit#passwordTextEdit
|
||||
text: lua123456
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
margin.top: 94
|
||||
margin.left: 132
|
||||
onClick: displayErrorBox("Error", "Not implemented yet")
|
||||
anchors.right: parent.right
|
||||
anchors.top: prev.bottom
|
||||
margin.left: 18
|
||||
margin.right: 18
|
||||
|
||||
%button#okButton
|
||||
text: Ok
|
||||
size: [43, 20]
|
||||
anchors.right: parent.right
|
||||
width: 64
|
||||
anchors.right: next.left
|
||||
anchors.bottom: parent.bottom
|
||||
margin.bottom: 10
|
||||
margin.right: 66
|
||||
margin.bottom: 16
|
||||
margin.right: 16
|
||||
onClick: EnterGame_connectToLoginServer()
|
||||
|
||||
%button#cancelButton
|
||||
text: Cancel
|
||||
size: [43, 20]
|
||||
width: 64
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
margin.bottom: 10
|
||||
margin.right: 13
|
||||
onClick: self.parent:destroy()
|
||||
|
||||
%textEdit#accountNameTextEdit
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
margin.top: 32
|
||||
margin.right: 18
|
||||
|
||||
%textEdit#passwordTextEdit
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
margin.top: 61
|
||||
margin.right: 18
|
||||
margin.bottom: 16
|
||||
margin.right: 16
|
||||
onClick: function(self) rootUI:getChild("enterGameWindow"):destroy() end
|
||||
|
@ -1,8 +0,0 @@
|
||||
title: Message box
|
||||
notes: Functions for creating message boxes
|
||||
author: edubart
|
||||
version: 1
|
||||
website: https://github.com/edubart/otclient
|
||||
enabled: true
|
||||
script: messagebox.lua
|
||||
|
Before Width: | Height: | Size: 1.9 MiB After Width: | Height: | Size: 1.9 MiB |
After Width: | Height: | Size: 825 B |
After Width: | Height: | Size: 833 B |
After Width: | Height: | Size: 859 B |
After Width: | Height: | Size: 34 KiB |
@ -0,0 +1,80 @@
|
||||
default font: helvetica-12px
|
||||
default font color: [210, 210, 210, 255]
|
||||
|
||||
buttons:
|
||||
default:
|
||||
font: helvetica-11px-bold
|
||||
font color: [240, 173, 77, 255]
|
||||
default size: [106, 24]
|
||||
|
||||
bordered image:
|
||||
source: button.png
|
||||
border: 5
|
||||
|
||||
hover state:
|
||||
bordered image:
|
||||
source: button_hover.png
|
||||
border: 5
|
||||
|
||||
down state:
|
||||
text translate: [1, 1]
|
||||
bordered image:
|
||||
source: button_down.png
|
||||
border: 5
|
||||
panels:
|
||||
default:
|
||||
# the default panel is empty
|
||||
|
||||
mainMenuBackground:
|
||||
image: background.png
|
||||
antialised: true
|
||||
|
||||
roundedGridPanel:
|
||||
bordered image:
|
||||
source: panel_rounded.png
|
||||
border: 4
|
||||
|
||||
flatPanel:
|
||||
bordered image:
|
||||
source: panel_flat.png
|
||||
border: 1
|
||||
|
||||
labels:
|
||||
default:
|
||||
|
||||
large:
|
||||
font: helvetica-12px-bold
|
||||
|
||||
windows:
|
||||
default:
|
||||
font: helvetica-11px-bold
|
||||
font color: [240, 173, 77, 255]
|
||||
head:
|
||||
height: 20
|
||||
bordered image:
|
||||
source: window.png
|
||||
size: [256, 19]
|
||||
border: 4
|
||||
bottom: 3
|
||||
|
||||
body:
|
||||
bordered image:
|
||||
source: window.png
|
||||
size: [256, 237]
|
||||
offset: [0, 19]
|
||||
border: 4
|
||||
top: 0
|
||||
|
||||
text edits:
|
||||
default:
|
||||
default size: [86, 20]
|
||||
text margin: 3
|
||||
bordered image:
|
||||
source: panel_flat.png
|
||||
border: 1
|
||||
|
||||
line decorations:
|
||||
default:
|
||||
bordered image:
|
||||
source: horizontal_separator.png
|
||||
top: 2
|
After Width: | Height: | Size: 151 B |
After Width: | Height: | Size: 152 B |
@ -1,137 +0,0 @@
|
||||
default font: sans-11px-bold
|
||||
default font color: [51, 51, 51, 255]
|
||||
|
||||
buttons:
|
||||
default:
|
||||
default size: [96, 22]
|
||||
font color: [0, 115, 234, 255]
|
||||
|
||||
bordered image:
|
||||
source: lightness/button-up.png
|
||||
left border: [0,2,2,6]
|
||||
right border: [22,2,2,6]
|
||||
top border: [2,0,20,2]
|
||||
bottom border: [2,8,20,2]
|
||||
top left corner: [0,0,2,2]
|
||||
top right corner: [22,0,2,2]
|
||||
bottom left corner: [0,8,2,2]
|
||||
bottom right corner: [22,8,2,2]
|
||||
center: [2,2,20,6]
|
||||
|
||||
hover state:
|
||||
font color: [255, 255, 255, 255]
|
||||
bordered image:
|
||||
source: lightness/button-hover.png
|
||||
left border: [0,2,2,6]
|
||||
right border: [22,2,2,6]
|
||||
top border: [2,0,20,2]
|
||||
bottom border: [2,8,20,2]
|
||||
top left corner: [0,0,2,2]
|
||||
top right corner: [22,0,2,2]
|
||||
bottom left corner: [0,8,2,2]
|
||||
bottom right corner: [22,8,2,2]
|
||||
center: [2,2,20,6]
|
||||
|
||||
down state:
|
||||
font color: [255, 0, 132, 255]
|
||||
bordered image:
|
||||
source: lightness/button-down.png
|
||||
left border: [0,2,2,6]
|
||||
right border: [22,2,2,6]
|
||||
top border: [2,0,20,2]
|
||||
bottom border: [2,8,20,2]
|
||||
top left corner: [0,0,2,2]
|
||||
top right corner: [22,0,2,2]
|
||||
bottom left corner: [0,8,2,2]
|
||||
bottom right corner: [22,8,2,2]
|
||||
center: [2,2,20,6]
|
||||
panels:
|
||||
default:
|
||||
# the default panel is empty
|
||||
|
||||
mainMenuBackground:
|
||||
image: lightness/background.png
|
||||
antialised: true
|
||||
|
||||
roundedGridPanel:
|
||||
bordered image:
|
||||
source: lightness/menupanel.png
|
||||
left border: [0,2,2,6]
|
||||
right border: [22,2,2,6]
|
||||
top border: [2,0,20,2]
|
||||
bottom border: [2,8,20,2]
|
||||
top left corner: [0,0,2,2]
|
||||
top right corner: [22,0,2,2]
|
||||
bottom left corner: [0,8,2,2]
|
||||
bottom right corner: [22,8,2,2]
|
||||
center: [2,2,20,6]
|
||||
|
||||
flatPanel:
|
||||
bordered image:
|
||||
source: lightness/panel.png
|
||||
left border: [0,2,2,6]
|
||||
right border: [22,2,2,6]
|
||||
top border: [2,0,20,2]
|
||||
bottom border: [2,8,20,2]
|
||||
top left corner: [0,0,2,2]
|
||||
top right corner: [22,0,2,2]
|
||||
bottom left corner: [0,8,2,2]
|
||||
bottom right corner: [22,8,2,2]
|
||||
center: [2,2,20,6]
|
||||
|
||||
labels:
|
||||
default:
|
||||
font: sans-12px
|
||||
|
||||
windows:
|
||||
default:
|
||||
font: sans-12px-bold
|
||||
font color: [80, 80, 80, 255]
|
||||
head:
|
||||
text align: left
|
||||
margin: 8
|
||||
height: 26
|
||||
bordered image:
|
||||
source: lightness/window.png
|
||||
left border: [0,5,5,22]
|
||||
right border: [251,5,5,22]
|
||||
top border: [5,0,246,5]
|
||||
bottom border: [5,27,246,5]
|
||||
top left corner: [0,0,5,5]
|
||||
top right corner: [251,0,5,5]
|
||||
bottom left corner: [0,27,5,5]
|
||||
bottom right corner: [251,27,5,5]
|
||||
center: [5,5,246,22]
|
||||
body:
|
||||
bordered image:
|
||||
source: lightness/window.png
|
||||
left border: [0,32,2,222]
|
||||
right border: [254,32,2,222]
|
||||
bottom border: [2,254,252,2]
|
||||
bottom left corner: [0,254,2,2]
|
||||
bottom right corner: [254,254,2,2]
|
||||
center: [2, 32, 92, 92]
|
||||
|
||||
text edits:
|
||||
default:
|
||||
default size: [86, 20]
|
||||
font color: [80, 80, 80, 255]
|
||||
text margin: 3
|
||||
bordered image:
|
||||
source: lightness/button-down.png
|
||||
left border: [0,2,2,6]
|
||||
right border: [22,2,2,6]
|
||||
top border: [2,0,20,2]
|
||||
bottom border: [2,8,20,2]
|
||||
top left corner: [0,0,2,2]
|
||||
top right corner: [22,0,2,2]
|
||||
bottom left corner: [0,8,2,2]
|
||||
bottom right corner: [22,8,2,2]
|
||||
center: [2,2,20,6]
|
||||
|
||||
line decorations:
|
||||
default:
|
||||
bordered image:
|
||||
source: lightness/window.png
|
||||
top border: [2,254,252,2]
|
||||
|
Before Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 235 B |
Before Width: | Height: | Size: 283 B |
Before Width: | Height: | Size: 234 B |
Before Width: | Height: | Size: 968 KiB |
Before Width: | Height: | Size: 232 B |
Before Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 252 B |
Before Width: | Height: | Size: 880 B |
After Width: | Height: | Size: 179 B |
After Width: | Height: | Size: 35 KiB |
@ -1,111 +0,0 @@
|
||||
default font: tibia-10px-antialised
|
||||
default font color: [191, 191, 191, 255]
|
||||
default texture: tibiaskin/skin.png
|
||||
|
||||
buttons:
|
||||
default:
|
||||
font: tibia-8px-antialised
|
||||
font color: [238, 238, 238, 255]
|
||||
default size: [86, 20]
|
||||
|
||||
bordered image:
|
||||
left border: [45,139,1,18]
|
||||
right border: [130,139,1,18]
|
||||
top border: [46,138,84,1]
|
||||
bottom border: [46,157,84,1]
|
||||
top left corner: [45,138,1,1]
|
||||
top right corner: [130,138,1,1]
|
||||
bottom left corner: [45,157,1,1]
|
||||
bottom right corner: [130,157,1,1]
|
||||
center: [46,139,84,18]
|
||||
|
||||
down state:
|
||||
text translate: [1, 1]
|
||||
bordered image:
|
||||
left border: [45,159,1,18]
|
||||
right border: [130,159,1,18]
|
||||
top border: [46,158,84,1]
|
||||
bottom border: [46,177,84,1]
|
||||
top left corner: [45,158,1,1]
|
||||
top right corner: [130,158,1,1]
|
||||
bottom left corner: [45,177,1,1]
|
||||
bottom right corner: [130,177,1,1]
|
||||
center: [46,159,84,18]
|
||||
panels:
|
||||
default:
|
||||
# the default panel is empty
|
||||
|
||||
mainMenuBackground:
|
||||
image: tibiaskin/background.png
|
||||
antialised: true
|
||||
|
||||
roundedGridPanel:
|
||||
bordered image:
|
||||
left border: [0,214,5,32]
|
||||
right border: [6,214,5,32]
|
||||
top border: [43,214,32,5]
|
||||
bottom border: [43,220,32,5]
|
||||
top left corner: [43,225,5,5]
|
||||
top right corner: [49,225,5,5]
|
||||
bottom left corner: [43,230,5,5]
|
||||
bottom right corner: [48,231,5,5]
|
||||
center: [11,214,32,32]
|
||||
|
||||
flatPanel:
|
||||
bordered image:
|
||||
left border: [275,0,1,96]
|
||||
right border: [276,0,1,96]
|
||||
top border: [2,210,91,1]
|
||||
bottom border: [2,211,91,1]
|
||||
top left corner: [275,0,1,1]
|
||||
top right corner: [276,0,1,1]
|
||||
bottom left corner: [2,210,1,1]
|
||||
bottom right corner: [276,95,1,1]
|
||||
center: [0, 0, 96, 96]
|
||||
|
||||
labels:
|
||||
default:
|
||||
|
||||
windows:
|
||||
default:
|
||||
font color: [143, 143, 143, 255]
|
||||
head:
|
||||
height: 17
|
||||
bordered image:
|
||||
left border: [106,187,4,9]
|
||||
right border: [110,187,4,9]
|
||||
top border: [114,183,92,4]
|
||||
bottom border: [114,196,92,4]
|
||||
top left corner: [106,183,4,4]
|
||||
top right corner: [110,183,4,4]
|
||||
bottom left corner: [106,196,4,4]
|
||||
bottom right corner: [110,196,4,4]
|
||||
center: [114,187,96,9]
|
||||
body:
|
||||
bordered image:
|
||||
left border: [98,180,4,12]
|
||||
right border: [99,180,4,12]
|
||||
bottom border: [2,193,96,4]
|
||||
bottom left corner: [98,193,4,4]
|
||||
bottom right corner: [102,193,4,4]
|
||||
center: [0, 0, 96, 96]
|
||||
|
||||
text edits:
|
||||
default:
|
||||
default size: [86, 16]
|
||||
text margin: 3
|
||||
bordered image:
|
||||
left border: [308,97,1,1]
|
||||
right border: [319,97,1,10]
|
||||
top border: [309,96,10,1]
|
||||
bottom border: [309,107,10,1]
|
||||
top left corner: [308,96,1,1]
|
||||
top right corner: [319,96,1,1]
|
||||
bottom left corner: [308,107,1,1]
|
||||
bottom right corner: [319,107,1,1]
|
||||
center: [309,97,10,10]
|
||||
|
||||
line decorations:
|
||||
default:
|
||||
bordered image:
|
||||
top border: [2,210,96,2]
|
Before Width: | Height: | Size: 110 KiB |
After Width: | Height: | Size: 35 KiB |
@ -1,37 +1,63 @@
|
||||
%panel#mainBackground
|
||||
image: { source: background.png; antialised: true }
|
||||
@import "additional_elements"
|
||||
|
||||
Panel
|
||||
id: "mainBackground"
|
||||
image:
|
||||
source: "background.png"
|
||||
antialised: true
|
||||
anchor.fill: parent
|
||||
|
||||
%panel#mainMenuPanel.flat
|
||||
size: 117 171
|
||||
|
||||
lista:
|
||||
- valor1
|
||||
- valor2
|
||||
- valor3
|
||||
|
||||
FlatPanel
|
||||
id: mainMenuPanel
|
||||
size: {117, 171}
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
margin: 70 60
|
||||
margin: {70, 60}
|
||||
|
||||
button
|
||||
anchors.top: prev.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
margin.top: 6
|
||||
|
||||
%button.first
|
||||
// enter game button
|
||||
Button
|
||||
text: "Enter Game"
|
||||
anchors.top: parent.top
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
margin.top: 16
|
||||
text: Enter Game
|
||||
onClick: loadUI("entergamewindow")
|
||||
onClick: |
|
||||
function(self)
|
||||
if not mainMenu:getChild("enterGameWindow") then
|
||||
local enterGame = loadUI("entergamewindow")
|
||||
enterGame:setLocked(true)
|
||||
end
|
||||
end
|
||||
|
||||
%button.notImplemented
|
||||
text: Access Account
|
||||
Button
|
||||
text: "Access Account"
|
||||
anchors.top: prev.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
margin.top: 6
|
||||
onClick: loadUI("entergamewindow")
|
||||
|
||||
%button
|
||||
text: Options
|
||||
Button
|
||||
text: "Options"
|
||||
anchors.top: prev.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
margin.top: 6
|
||||
onClick: loadUI("optionswindow")
|
||||
|
||||
%button
|
||||
text: Info
|
||||
Button
|
||||
text: "Info"
|
||||
anchors.top: prev.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
margin.top: 6
|
||||
onClick: loadUI("infowindow")
|
||||
|
||||
%button
|
||||
text: Exit
|
||||
Button
|
||||
text: "Exit"
|
||||
anchors.top: prev.bottom
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
margin.top: 6
|
||||
onClick: terminateApplication()
|
||||
|
||||
|
@ -1,2 +0,0 @@
|
||||
#include "modules.h"
|
||||
|
@ -1,8 +0,0 @@
|
||||
#ifndef MODULES_H
|
||||
#define MODULES_H
|
||||
|
||||
class Modules
|
||||
{
|
||||
};
|
||||
|
||||
#endif // MODULES_H
|
@ -0,0 +1,29 @@
|
||||
#include "packages.h"
|
||||
|
||||
#include <core/resources.h>
|
||||
#include <script/luainterface.h>
|
||||
|
||||
Packages g_packages;
|
||||
|
||||
void Packages::loadPackages()
|
||||
{
|
||||
std::list<std::string> packages = g_resources.listDirectoryFiles("modules");
|
||||
foreach(const std::string& package, packages) {
|
||||
std::string dir = make_string("modules/", package);
|
||||
g_resources.pushCurrentPath(dir);
|
||||
|
||||
std::list<std::string> packagesFiles = g_resources.listDirectoryFiles();
|
||||
foreach(const std::string& packageFile, packagesFiles) {
|
||||
if(boost::ends_with(packageFile, ".lua")) {
|
||||
g_lua.runScript(packageFile);
|
||||
}
|
||||
}
|
||||
|
||||
g_resources.popCurrentPath();
|
||||
}
|
||||
}
|
||||
|
||||
void Packages::terminate()
|
||||
{
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
#ifndef PACKAGES_H
|
||||
#define PACKAGES_H
|
||||
|
||||
#include <global.h>
|
||||
|
||||
class Packages
|
||||
{
|
||||
public:
|
||||
void loadPackages();
|
||||
void terminate();
|
||||
};
|
||||
|
||||
extern Packages g_packages;
|
||||
|
||||
#endif // MODULES_H
|
@ -0,0 +1,191 @@
|
||||
#ifndef LUABINDER_H
|
||||
#define LUABINDER_H
|
||||
|
||||
#include "luavalue.h"
|
||||
#include "luastate.h"
|
||||
|
||||
namespace luabinder
|
||||
{
|
||||
// transform const T& -> T
|
||||
template<typename T>
|
||||
struct remove_const_ref {
|
||||
typedef typename std::remove_const<typename std::remove_reference<T>::type>::type type;
|
||||
};
|
||||
|
||||
// pack an value into tuple recursively
|
||||
template<int N>
|
||||
struct pack_values_into_tuple {
|
||||
template<typename Tuple>
|
||||
static void call(Tuple& tuple, LuaState* lua) {
|
||||
typedef typename std::tuple_element<N-1, Tuple>::type ValueType;
|
||||
std::get<N-1>(tuple) = safe_luavalue_cast<ValueType>(lua->popValue());
|
||||
pack_values_into_tuple<N-1>::call(tuple, lua);
|
||||
}
|
||||
};
|
||||
template<>
|
||||
struct pack_values_into_tuple<0> {
|
||||
template<typename Tuple>
|
||||
static void call(Tuple &tuple, LuaState* lua) { }
|
||||
};
|
||||
|
||||
// call function
|
||||
template<typename Ret, typename F, typename... Args>
|
||||
typename std::enable_if<!std::is_void<Ret>::value, int>::type
|
||||
call_fun_and_push_result(const F& f, LuaState* lua, Args... args) {
|
||||
Ret ret = f(args...);
|
||||
lua->pushValue(safe_to_luavalue(ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// call function with no return
|
||||
template<typename Ret, typename F, typename... Args>
|
||||
typename std::enable_if<std::is_void<Ret>::value, int>::type
|
||||
call_fun_and_push_result(const F& f, LuaState* lua, Args... args) {
|
||||
f(args...);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// expand function arguments for calling
|
||||
template<int N, typename Ret>
|
||||
struct expand_fun_arguments {
|
||||
template<typename Tuple, typename F, typename... Args>
|
||||
static int call(const Tuple& tuple, const F& f, LuaState* lua, Args... args) {
|
||||
return expand_fun_arguments<N-1,Ret>::call(tuple, f, lua, std::cref(std::get<N-1>(tuple)), args...);
|
||||
}
|
||||
};
|
||||
template<typename Ret>
|
||||
struct expand_fun_arguments<0,Ret> {
|
||||
template<typename Tuple, typename F, typename... Args>
|
||||
static int call(const Tuple& tuple, const F& f, LuaState* lua, Args... args) {
|
||||
return call_fun_and_push_result<Ret>(f, lua, args...);
|
||||
}
|
||||
};
|
||||
|
||||
// bind different types of functions
|
||||
template<typename Ret, typename F, typename Tuple>
|
||||
LuaCppFunction bind_fun_specializer(const F& f) {
|
||||
enum { N = std::tuple_size<Tuple>::value };
|
||||
return [=](LuaState* lua) {
|
||||
if(lua->stackSize() != N)
|
||||
throw LuaBadNumberOfArgumentsException(N, lua->stackSize());
|
||||
Tuple tuple;
|
||||
pack_values_into_tuple<N>::call(tuple, lua);
|
||||
return expand_fun_arguments<N,Ret>::call(tuple, f, lua);
|
||||
};
|
||||
}
|
||||
|
||||
// bind a std::function
|
||||
template<typename Ret, typename... Args>
|
||||
LuaCppFunction bind_fun(const std::function<Ret(Args...)>& f) {
|
||||
typedef typename std::tuple<typename remove_const_ref<Args>::type...> Tuple;
|
||||
return bind_fun_specializer<typename remove_const_ref<Ret>::type,
|
||||
decltype(f),
|
||||
Tuple>(f);
|
||||
}
|
||||
|
||||
// bind a custumized function
|
||||
inline
|
||||
LuaCppFunction bind_fun(const std::function<int(LuaState*)>& f) {
|
||||
return f;
|
||||
}
|
||||
|
||||
// convert to std::function then bind
|
||||
template<typename Ret, typename... Args>
|
||||
LuaCppFunction bind_fun(Ret (*f)(Args...)) {
|
||||
return bind_fun(std::function<Ret(Args...)>(f));
|
||||
}
|
||||
|
||||
// a tuple_element that works with the next algorithm
|
||||
template<std::size_t __i, typename _Tp>
|
||||
struct tuple_element;
|
||||
template<std::size_t __i, typename _Head, typename... _Tail>
|
||||
struct tuple_element<__i, std::tuple<_Head, _Tail...> >
|
||||
: tuple_element<__i - 1, std::tuple<_Tail...> > { };
|
||||
template<typename _Head, typename... _Tail>
|
||||
struct tuple_element<0, std::tuple<_Head, _Tail...> > { typedef _Head type; };
|
||||
template<typename _Head>
|
||||
struct tuple_element<-1,std::tuple<_Head>> { typedef void type; };
|
||||
template<std::size_t __i>
|
||||
struct tuple_element<__i,std::tuple<>> { typedef void type; };
|
||||
|
||||
// rebind functions already binded by std::bind that have placeholders
|
||||
template<typename Enable, int N, typename ArgsTuple, typename HoldersTuple, typename... Args>
|
||||
struct get_holded_tuple;
|
||||
|
||||
template<int N, typename ArgsTuple, typename HoldersTuple, typename... Args>
|
||||
struct get_holded_tuple<typename std::enable_if<(N > 0 && std::is_placeholder<typename tuple_element<N-1, HoldersTuple>::type>::value > 0), void>::type, N, ArgsTuple, HoldersTuple, Args...> {
|
||||
typedef typename std::tuple_element<N-1, HoldersTuple>::type holder_type;
|
||||
typedef typename tuple_element<std::is_placeholder<holder_type>::value-1, ArgsTuple>::type _arg_type;
|
||||
typedef typename remove_const_ref<_arg_type>::type arg_type;
|
||||
typedef typename get_holded_tuple<void, N-1, ArgsTuple, HoldersTuple, arg_type, Args...>::type type;
|
||||
};
|
||||
template<int N, typename ArgsTuple, typename HoldersTuple, typename... Args>
|
||||
struct get_holded_tuple<typename std::enable_if<(N > 0 && std::is_placeholder<typename tuple_element<N-1, HoldersTuple>::type>::value == 0), void>::type, N, ArgsTuple, HoldersTuple, Args...> {
|
||||
typedef typename get_holded_tuple<void, N-1, ArgsTuple, HoldersTuple, Args...>::type type;
|
||||
};
|
||||
template<typename ArgsTuple, typename HoldersTuple, typename... Args>
|
||||
struct get_holded_tuple<void, 0, ArgsTuple, HoldersTuple, Args...> {
|
||||
typedef typename std::tuple<Args...> type;
|
||||
};
|
||||
|
||||
template<typename Ret, typename... Args, typename... Holders>
|
||||
LuaCppFunction bind_fun(const std::_Bind<Ret (*(Holders...))(Args...)>& f) {
|
||||
typedef typename std::tuple<Args...> ArgsTuple;
|
||||
typedef typename std::tuple<Holders...> HoldersTuple;
|
||||
typedef typename get_holded_tuple<void, sizeof...(Holders), ArgsTuple, HoldersTuple>::type Tuple;
|
||||
return bind_fun_specializer<typename remove_const_ref<Ret>::type,
|
||||
decltype(f),
|
||||
Tuple>(f);
|
||||
}
|
||||
|
||||
template<typename Obj, typename Ret, typename... Args, typename... Holders>
|
||||
LuaCppFunction bind_fun(const std::_Bind<std::_Mem_fn<Ret (Obj::*)(Args...)>(Obj*, Holders...)>& f) {
|
||||
typedef typename std::tuple<Args...> ArgsTuple;
|
||||
typedef typename std::tuple<Holders...> HoldersTuple;
|
||||
typedef typename get_holded_tuple<void, sizeof...(Holders), ArgsTuple, HoldersTuple>::type Tuple;
|
||||
return bind_fun_specializer<typename remove_const_ref<Ret>::type,
|
||||
decltype(f),
|
||||
Tuple>(f);
|
||||
}
|
||||
|
||||
// custumized functions already binded by std::bind doesn't need to be bind again
|
||||
template<typename Obj>
|
||||
LuaCppFunction bind_fun(const std::_Bind<std::_Mem_fn<int (Obj::*)(LuaState*)>(Obj*, std::_Placeholder<1>)>& f) {
|
||||
return f;
|
||||
}
|
||||
inline
|
||||
LuaCppFunction bind_fun(const std::_Bind<int (*(std::_Placeholder<1>))(LuaState*)>& f) {
|
||||
return f;
|
||||
}
|
||||
|
||||
// bind member function
|
||||
template<typename Ret, typename Obj, typename... Args>
|
||||
LuaCppFunction bind_mem_fun(Ret (Obj::*f)(Args...)) {
|
||||
auto mf = std::mem_fn(f);
|
||||
typedef typename std::tuple<Obj*, typename remove_const_ref<Args>::type...> Tuple;
|
||||
return bind_fun_specializer<typename remove_const_ref<Ret>::type,
|
||||
decltype(mf),
|
||||
Tuple>(mf);
|
||||
}
|
||||
template<typename Ret, typename Obj, typename... Args>
|
||||
LuaCppFunction bind_mem_fun(Ret (Obj::*f)(Args...) const) {
|
||||
auto mf = std::mem_fn(f);
|
||||
typedef typename std::tuple<Obj*, typename remove_const_ref<Args>::type...> Tuple;
|
||||
return bind_fun_specializer<typename remove_const_ref<Ret>::type,
|
||||
decltype(mf),
|
||||
Tuple>(mf);
|
||||
}
|
||||
|
||||
// bind custumized member function
|
||||
template<typename Obj>
|
||||
LuaCppFunction bind_mem_fun(int (Obj::*f)(LuaState*)) {
|
||||
auto mf = std::mem_fn(f);
|
||||
return [=](LuaState* lua) {
|
||||
lua->insert(1);
|
||||
auto obj = safe_luavalue_cast<Obj*>(lua->popValue());
|
||||
return mf(obj, lua);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // LUABINDER_H
|
@ -0,0 +1,19 @@
|
||||
#ifndef LUADECLARATIONS_H
|
||||
#define LUADECLARATIONS_H
|
||||
|
||||
#include <global.h>
|
||||
|
||||
class LuaInterface;
|
||||
class LuaState;
|
||||
class LuaValue;
|
||||
class LuaObject;
|
||||
|
||||
typedef std::function<int(LuaState*)> LuaCppFunction;
|
||||
|
||||
typedef std::shared_ptr<LuaCppFunction> LuaCppFunctionPtr;
|
||||
typedef std::shared_ptr<LuaValue> LuaValuePtr;
|
||||
typedef std::shared_ptr<LuaObject> LuaObjectPtr;
|
||||
|
||||
typedef std::vector<LuaValuePtr> LuaValueList;
|
||||
|
||||
#endif // LUADECLARATIONS_H
|
@ -0,0 +1,39 @@
|
||||
#include "luaexception.h"
|
||||
#include "luainterface.h"
|
||||
|
||||
LuaException::LuaException(const std::string& error, int traceLevel)
|
||||
{
|
||||
generateLuaErrorMessage(error, traceLevel);
|
||||
}
|
||||
|
||||
void LuaException::generateLuaErrorMessage(const std::string& error, int traceLevel)
|
||||
{
|
||||
// clear stack, to prevent further errors
|
||||
g_lua.clearStack();
|
||||
|
||||
// append trace level to error message
|
||||
if(traceLevel >= 0)
|
||||
m_what = make_string("LUA ERROR: ", g_lua.getTraceback(error, traceLevel));
|
||||
else
|
||||
m_what = make_string("LUA ERROR: ", error);
|
||||
}
|
||||
|
||||
LuaBadNumberOfArgumentsException::LuaBadNumberOfArgumentsException(int expected, int got)
|
||||
{
|
||||
std::string error = "attempt to call a function with wrong number of arguments";
|
||||
if(expected >= 0 && got >= 0)
|
||||
error = make_string(error, " (expected ", expected, ", but got ", got, ")");
|
||||
generateLuaErrorMessage(error, 1);
|
||||
}
|
||||
|
||||
LuaBadTypeConversinException::LuaBadTypeConversinException(const std::string& typeName)
|
||||
{
|
||||
std::string error = make_string("attempt to convert ", typeName, " to a lua value");
|
||||
generateLuaErrorMessage(error, 0);
|
||||
}
|
||||
|
||||
LuaBadValueCastException::LuaBadValueCastException(const LuaValuePtr& value, const std::string& typeName)
|
||||
{
|
||||
std::string error = make_string("attempt to cast a ", value->getTypeName(), " lua value to ", typeName);
|
||||
generateLuaErrorMessage(error, 0);
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
#ifndef LUAEXCEPTION_H
|
||||
#define LUAEXCEPTION_H
|
||||
|
||||
#include "luadeclarations.h"
|
||||
|
||||
/// LuaException, all lua errors are throwed by it
|
||||
class LuaException : public std::exception
|
||||
{
|
||||
public:
|
||||
LuaException(const std::string& error, int traceLevel = -1);
|
||||
virtual ~LuaException() throw() { };
|
||||
|
||||
void generateLuaErrorMessage(const std::string& error, int traceLevel);
|
||||
|
||||
virtual const char* what() const throw() { return m_what.c_str(); }
|
||||
|
||||
protected:
|
||||
LuaException() { }
|
||||
|
||||
std::string m_what;
|
||||
};
|
||||
|
||||
class LuaBadNumberOfArgumentsException : public LuaException {
|
||||
public:
|
||||
LuaBadNumberOfArgumentsException(int expected = -1, int got = -1);
|
||||
};
|
||||
|
||||
class LuaBadTypeConversinException : public LuaException {
|
||||
public:
|
||||
LuaBadTypeConversinException(const std::string& typeName = "an incompatible lua type");
|
||||
};
|
||||
|
||||
class LuaBadValueCastException : public LuaException {
|
||||
public:
|
||||
LuaBadValueCastException(const LuaValuePtr& value, const std::string& typeName = "an incompatible lua type");
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,54 @@
|
||||
#include "luainterface.h"
|
||||
#include <core/engine.h>
|
||||
#include <ui/ui.h>
|
||||
#include "../../protocollogin.h"
|
||||
|
||||
void LuaInterface::registerFunctions()
|
||||
{
|
||||
g_lua.bindGlobalFunction("exit", std::bind(&Engine::stop, &g_engine));
|
||||
g_lua.bindGlobalFunction("loadUI", std::bind(&UILoader::loadFromFile, &g_uiLoader, std::placeholders::_1, std::placeholders::_2));
|
||||
g_lua.setGlobal("rootUI", safe_to_luavalue(UIContainer::getRoot()));
|
||||
|
||||
g_lua.registerClass("UIElement");
|
||||
g_lua.bindClassStaticFunction("UIElement", "new", &UIElement::create);
|
||||
g_lua.bindClassMemberField("UIElement", "id", &UIElement::getId, &UIElement::setId);
|
||||
g_lua.bindClassMemberField("UIElement", "enabled", &UIElement::isEnabled, &UIElement::setEnabled);
|
||||
g_lua.bindClassMemberField("UIElement", "visible", &UIElement::isVisible, &UIElement::setVisible);
|
||||
g_lua.bindClassMemberField("UIElement", "focused", &UIElement::isFocused, &UIElement::setFocused);
|
||||
g_lua.bindClassMemberField("UIElement", "width", &UIElement::getWidth, &UIElement::setWidth);
|
||||
g_lua.bindClassMemberField("UIElement", "height", &UIElement::getHeight, &UIElement::setHeight);
|
||||
g_lua.bindClassMemberField("UIElement", "parent", &UIElement::getParent, &UIElement::setParent);
|
||||
g_lua.bindClassMemberFunction("UIElement", "setLocked", &UIElement::setLocked);
|
||||
//g_lua.bindClassMemberFunction("UIElement", "setMargin", &UIElement::luaSetMargin);
|
||||
g_lua.bindClassMemberFunction("UIElement", "destroy", &UIElement::destroyLater);
|
||||
g_lua.bindClassMemberFunction("UIElement", "centerIn", &UIElement::centerIn);
|
||||
g_lua.bindClassMemberFunction("UIElement", "addAnchor", &UIElement::addAnchor);
|
||||
|
||||
g_lua.registerClass("UIContainer", "UIElement");
|
||||
g_lua.bindClassStaticFunction("UIContainer", "create", &UIContainer::create);
|
||||
g_lua.bindClassMemberFunction("UIContainer", "getChild", &UIContainer::getChildById);
|
||||
//g_lua.bindClassMemberFunction("UIContainer", "children", &UIContainer::getChildren);
|
||||
g_lua.bindClassMemberFunction("UIContainer", "addChild", &UIContainer::addChild);
|
||||
|
||||
g_lua.registerClass("UILabel", "UIElement");
|
||||
g_lua.bindClassStaticFunction("UILabel", "create", &UILabel::create);
|
||||
g_lua.bindClassMemberField("UILabel", "text", &UILabel::getText, &UILabel::setText);
|
||||
|
||||
g_lua.registerClass("UIButton", "UIElement");
|
||||
g_lua.bindClassStaticFunction("UIButton", "create", &UIButton::create);
|
||||
g_lua.bindClassMemberField("UIButton", "text", &UIButton::getText, &UIButton::setText);
|
||||
|
||||
g_lua.registerClass("UITextEdit", "UIElement");
|
||||
g_lua.bindClassStaticFunction("UITextEdit", "create", &UITextEdit::create);
|
||||
g_lua.bindClassMemberField("UITextEdit", "text", &UITextEdit::getText, &UITextEdit::setText);
|
||||
|
||||
g_lua.registerClass("UIWindow", "UIContainer");
|
||||
g_lua.bindClassStaticFunction("UIWindow", "create", &UIWindow::create);
|
||||
g_lua.bindClassMemberField("UIWindow", "title", &UIWindow::getTitle, &UIWindow::setTitle);
|
||||
|
||||
g_lua.registerClass("Protocol");
|
||||
g_lua.registerClass("ProtocolLogin", "Protocol");
|
||||
g_lua.bindClassStaticFunction("ProtocolLogin", "create", &ProtocolLogin::create);
|
||||
g_lua.bindClassMemberFunction("ProtocolLogin", "login", &ProtocolLogin::login);
|
||||
g_lua.bindClassMemberFunction("ProtocolLogin", "cancel", &ProtocolLogin::cancel);
|
||||
}
|
@ -0,0 +1,235 @@
|
||||
#include "luainterface.h"
|
||||
|
||||
LuaInterface g_lua;
|
||||
|
||||
void LuaInterface::init()
|
||||
{
|
||||
// installs a custom loader that will load scripts correctlyfrom lua require keyword
|
||||
auto loaders = getGlobal("package")->getField("loaders");
|
||||
loaders->setTable(loaders->getTableSize() + 1, createCppFunction(&LuaInterface::luaScriptLoader));
|
||||
|
||||
// register LuaObject, the class that all other classes will derive from
|
||||
registerClass("LuaObject");
|
||||
bindClassMemberGetField("LuaObject", "use_count", &LuaObject::getUseCount);
|
||||
|
||||
// register other custom classes and functions
|
||||
registerFunctions();
|
||||
}
|
||||
|
||||
void LuaInterface::terminate()
|
||||
{
|
||||
collectGarbage();
|
||||
}
|
||||
|
||||
LuaValuePtr LuaInterface::loadFunction(const std::string& buffer, const std::string& source)
|
||||
{
|
||||
LuaValuePtr func;
|
||||
// get the function contained the buffer
|
||||
if(boost::starts_with(buffer, "function")) {
|
||||
runBuffer(make_string("__func = ", buffer), source);
|
||||
func = getGlobal("__func");
|
||||
setGlobal("__func", createNil());
|
||||
// use the buffer as a function
|
||||
} else
|
||||
func = loadBuffer(buffer, source);
|
||||
return func;
|
||||
}
|
||||
|
||||
LuaValuePtr LuaInterface::evaluateExpression(const std::string& expression, const std::string& source)
|
||||
{
|
||||
// run the expression
|
||||
std::string buffer = make_string("__exp = (", expression, ")");
|
||||
runBuffer(buffer, source);
|
||||
|
||||
// get the expression result
|
||||
LuaValuePtr res = getGlobal("__exp");
|
||||
setGlobal("__exp", createNil());
|
||||
return res;
|
||||
}
|
||||
|
||||
LuaValuePtr LuaInterface::createEnvironment()
|
||||
{
|
||||
// creates a new environment table and
|
||||
// redirect the new environment to the current thread global environment (aka _G)
|
||||
// this allows to access global variables from _G in the new environment
|
||||
// and prevents new variables on the new environment to be set on the global environment
|
||||
auto env = createTable();
|
||||
auto mt = createTable();
|
||||
mt->setField("__index", getGlobalEnvironment());
|
||||
env->setMetatable(mt);
|
||||
return env;
|
||||
}
|
||||
|
||||
void LuaInterface::registerClass(const std::string& className, const std::string& baseClass)
|
||||
{
|
||||
// create the class table (that it is also the class methods table)
|
||||
auto klass = createTable(className);
|
||||
// create the class metatable
|
||||
auto klass_mt = createTable(className + "_mt");
|
||||
// create the class fieldmethods table
|
||||
auto klass_fieldmethods = createTable(className + "_fieldmethods");
|
||||
|
||||
// set metatable metamethods
|
||||
klass_mt->setField("__index", &LuaInterface::luaObjectGetEvent);
|
||||
klass_mt->setField("__newindex", &LuaInterface::luaObjectSetEvent);
|
||||
klass_mt->setField("__eq", &LuaInterface::luaObjectEqualEvent);
|
||||
klass_mt->setField("__gc", &LuaInterface::luaObjectCollectEvent);
|
||||
klass_mt->setField("methods", klass);
|
||||
klass_mt->setField("fieldmethods", klass_fieldmethods);
|
||||
|
||||
// redirect methods and fieldmethods to the base class ones
|
||||
if(!className.empty() && className != "LuaObject") {
|
||||
/* the following code what create classes hierarchy for lua, by reproducing the following:
|
||||
* DerivedClass = { __index = BaseClass }
|
||||
* DerivedClass_fieldmethods = { __index = BaseClass_methods }
|
||||
*/
|
||||
|
||||
// redirect the class methods to the base methods
|
||||
auto redirect = createTable();
|
||||
auto tmp = getGlobal(baseClass);
|
||||
redirect->setField("__index", tmp);
|
||||
klass->setMetatable(redirect);
|
||||
|
||||
// redirect the class fieldmethods to the base fieldmethods
|
||||
redirect = createTable();
|
||||
tmp = getGlobal(baseClass + "_fieldmethods");
|
||||
redirect->setField("__index", tmp);
|
||||
klass_fieldmethods->setMetatable(redirect);
|
||||
}
|
||||
}
|
||||
|
||||
void LuaInterface::registerClassStaticFunction(const std::string& className, const std::string& functionName, const LuaCppFunction& function)
|
||||
{
|
||||
registerClassMemberFunction(className, functionName, function);
|
||||
}
|
||||
|
||||
void LuaInterface::registerClassMemberFunction(const std::string& className, const std::string& functionName, const LuaCppFunction& function)
|
||||
{
|
||||
auto table = getGlobal(className);
|
||||
table->setField(functionName, function);
|
||||
}
|
||||
|
||||
void LuaInterface::registerClassMemberField(const std::string& className, const std::string& field, const LuaCppFunction& getFunction, const LuaCppFunction& setFunction)
|
||||
{
|
||||
auto fieldmethods = getGlobal(className + "_fieldmethods");
|
||||
auto methods = getGlobal(className);
|
||||
auto capitalized = field;
|
||||
capitalized[0] = std::toupper(field[0]);
|
||||
|
||||
if(getFunction) {
|
||||
auto func = createCppFunction(getFunction);
|
||||
fieldmethods->setField(make_string("get_", field), func);
|
||||
methods->setField(make_string("get", capitalized), func);
|
||||
}
|
||||
|
||||
if(setFunction) {
|
||||
auto func = createCppFunction(setFunction);
|
||||
fieldmethods->setField(make_string("set_", field), func);
|
||||
methods->setField(make_string("set", capitalized), func);
|
||||
}
|
||||
}
|
||||
|
||||
void LuaInterface::registerGlobalFunction(const std::string& functionName, const LuaCppFunction& function)
|
||||
{
|
||||
setGlobal(functionName, createCppFunction(function));
|
||||
}
|
||||
|
||||
int LuaInterface::luaScriptLoader(LuaState* lua)
|
||||
{
|
||||
// load the script as a function
|
||||
auto fileName = make_string(lua->popValue()->toString(), + ".lua");
|
||||
auto scriptMain = lua->loadScript(fileName);
|
||||
lua->pushValue(scriptMain);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LuaInterface::luaObjectGetEvent(LuaState* lua)
|
||||
{
|
||||
// metamethod that will retrive fields values (that include functions) from the object
|
||||
|
||||
auto key = lua->popValue()->toString();
|
||||
auto objRef = lua->popValue();
|
||||
auto obj = safe_luavalue_cast<LuaObjectPtr>(objRef);
|
||||
|
||||
// if a get method for this key exists, calls it
|
||||
auto get_method = objRef->getMetatable()->getField("fieldmethods")->getField("get_" + key);
|
||||
if(!get_method->isNil()) {
|
||||
LuaValueList rets = get_method->call(make_string(obj->getLuaTypeName(), " obj.", key), objRef);
|
||||
assert(rets.size() == 1);
|
||||
lua->pushValues(rets);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// if the field for this key exists, returns it
|
||||
auto field = obj->getField(key);
|
||||
if(!field->isNil()) {
|
||||
lua->pushValue(field);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// if a method for this key exists, returns it
|
||||
auto method = objRef->getMetatable()->getField("methods")->getField(key);
|
||||
lua->pushValue(method);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LuaInterface::luaObjectSetEvent(LuaState* lua)
|
||||
{
|
||||
// this metamethod is called when setting a field of the object by using the keyword '='
|
||||
|
||||
auto value = lua->popValue();
|
||||
auto key = lua->popValue()->toString();
|
||||
auto objRef = lua->popValue();
|
||||
auto obj = safe_luavalue_cast<LuaObjectPtr>(objRef);
|
||||
|
||||
// check if a set method for this field exists and call it
|
||||
auto set_method = objRef->getMetatable()->getField("fieldmethods")->getField("set_" + key);
|
||||
if(!set_method->isNil()) {
|
||||
set_method->call(make_string(obj->getLuaTypeName(), " obj.", key, "="), objRef, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// no set method exists, then sets the object table
|
||||
obj->setField(key, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaInterface::luaObjectEqualEvent(LuaState* lua)
|
||||
{
|
||||
// metamethod that will check equality of objects
|
||||
|
||||
auto objRef2 = lua->popValue();
|
||||
auto objRef1 = lua->popValue();
|
||||
bool ret = false;
|
||||
|
||||
// check if obj1 == obj2
|
||||
if(objRef1->isUserdata() && objRef2->isUserdata()) {
|
||||
LuaObjectPtr* objPtr1 = static_cast<LuaObjectPtr*>(objRef1->toUserdata());
|
||||
LuaObjectPtr* objPtr2 = static_cast<LuaObjectPtr*>(objRef2->toUserdata());
|
||||
assert(objPtr1 && objPtr2);
|
||||
if(*objPtr1 == *objPtr2)
|
||||
ret = true;
|
||||
}
|
||||
|
||||
lua->pushBoolean(ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LuaInterface::luaObjectCollectEvent(LuaState* lua)
|
||||
{
|
||||
/* this metamethod is called every two lua garbage collections
|
||||
* for any LuaObject that have no references left in lua environment
|
||||
* anymore, thus this creates the possibility of holding an object
|
||||
* existence by lua
|
||||
*/
|
||||
|
||||
// get object pointer
|
||||
auto objRef = lua->popValue();
|
||||
auto objPtr = static_cast<LuaObjectPtr*>(objRef->toUserdata());
|
||||
assert(objPtr);
|
||||
|
||||
// reset pointer to decrease object use count
|
||||
objPtr->reset();
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,73 @@
|
||||
#ifndef LUAINTERFACE_H
|
||||
#define LUAINTERFACE_H
|
||||
|
||||
#include "luabinder.h"
|
||||
#include "luaobject.h"
|
||||
|
||||
class LuaInterface : public LuaState
|
||||
{
|
||||
public:
|
||||
void init();
|
||||
void terminate();
|
||||
|
||||
/// Load a function from buffef into a LuaValue
|
||||
LuaValuePtr loadFunction(const std::string& buffer, const std::string& source = "lua function buffer");
|
||||
|
||||
/// Evaluate a lua expression to a LuaValue
|
||||
LuaValuePtr evaluateExpression(const std::string& expression, const std::string& source = "lua expression");
|
||||
|
||||
LuaValuePtr createEnvironment();
|
||||
|
||||
/// Register core script functions
|
||||
void registerFunctions();
|
||||
|
||||
// methods for registring classes and functions
|
||||
void registerClass(const std::string& className, const std::string& baseClass = "LuaObject");
|
||||
void registerClassStaticFunction(const std::string& className, const std::string& functionName, const LuaCppFunction& function);
|
||||
void registerClassMemberFunction(const std::string& className, const std::string& functionName, const LuaCppFunction& function);
|
||||
void registerClassMemberField(const std::string& className, const std::string& field, const LuaCppFunction& getFunction, const LuaCppFunction& setFunction);
|
||||
void registerGlobalFunction(const std::string& functionName, const LuaCppFunction& function);
|
||||
|
||||
// methods for binding functions
|
||||
template<typename F>
|
||||
void bindClassStaticFunction(const std::string& className, const std::string& functionName, const F& function) {
|
||||
registerClassStaticFunction(className, functionName, luabinder::bind_fun(function));
|
||||
}
|
||||
|
||||
template<class C, typename F>
|
||||
void bindClassMemberFunction(const std::string& className, const std::string& functionName, F C::*function) {
|
||||
registerClassMemberFunction(className, functionName, luabinder::bind_mem_fun(function));
|
||||
}
|
||||
|
||||
template<class C, typename F1, typename F2>
|
||||
void bindClassMemberField(const std::string& className, const std::string& fieldName, F1 C::*getFunction, F2 C::*setFunction) {
|
||||
registerClassMemberField(className, fieldName, luabinder::bind_mem_fun(getFunction), luabinder::bind_mem_fun(setFunction));
|
||||
}
|
||||
|
||||
template<class C, typename F>
|
||||
void bindClassMemberGetField(const std::string& className, const std::string& fieldName, F C::*getFunction) {
|
||||
registerClassMemberField(className, fieldName, luabinder::bind_mem_fun(getFunction), LuaCppFunction());
|
||||
}
|
||||
|
||||
template<class C, typename F>
|
||||
void bindClassMemberSetField(const std::string& className, const std::string& fieldName, F C::*setFunction) {
|
||||
registerClassMemberField(className, fieldName, LuaCppFunction(), luabinder::bind_mem_fun(setFunction));
|
||||
}
|
||||
|
||||
template<typename F>
|
||||
void bindGlobalFunction(const std::string& functionName, const F& function) {
|
||||
registerGlobalFunction(functionName, luabinder::bind_fun(function));
|
||||
}
|
||||
|
||||
private:
|
||||
// installed lua callbacks by this interface
|
||||
static int luaScriptLoader(LuaState* lua);
|
||||
static int luaObjectGetEvent(LuaState* lua);
|
||||
static int luaObjectSetEvent(LuaState* lua);
|
||||
static int luaObjectEqualEvent(LuaState* lua);
|
||||
static int luaObjectCollectEvent(LuaState* lua);
|
||||
};
|
||||
|
||||
extern LuaInterface g_lua;
|
||||
|
||||
#endif // LUAINTERFACE_H
|
@ -0,0 +1,24 @@
|
||||
#include "luaobject.h"
|
||||
#include "luainterface.h"
|
||||
|
||||
LuaObject::LuaObject()
|
||||
{
|
||||
// creates own table
|
||||
m_luaTable = g_lua.createTable();
|
||||
}
|
||||
|
||||
LuaObject::~LuaObject()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
LuaValuePtr LuaObject::toLuaValue()
|
||||
{
|
||||
// fills a new userdata with a new LuaObject pointer
|
||||
new(g_lua.newUserdata(sizeof(LuaObjectPtr))) LuaObjectPtr(shared_from_this());
|
||||
|
||||
// set the metatable for the userdata
|
||||
g_lua.setMetatable(make_string(getLuaTypeName(), "_mt"));
|
||||
|
||||
return g_lua.popValue();
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
#ifndef LUAOBJECT_H
|
||||
#define LUAOBJECT_H
|
||||
|
||||
#include "luavalue.h"
|
||||
|
||||
/// LuaObject, all bound classes must be derived from it
|
||||
class LuaObject : public std::enable_shared_from_this<LuaObject>
|
||||
{
|
||||
public:
|
||||
LuaObject();
|
||||
virtual ~LuaObject();
|
||||
|
||||
/// Call a field of this lua object
|
||||
template<typename... T>
|
||||
LuaValueList callField(const std::string& field, const T&... args) {
|
||||
// note that we must retrive the field from or lua value (to use the __index metamethod)
|
||||
// so we cannot use our getField here
|
||||
auto fieldFunc = toLuaValue()->getField(field);
|
||||
auto funcName = make_string(getLuaTypeName(), ":", field);
|
||||
return fieldFunc->call(funcName, shared_from_this(), args...);
|
||||
}
|
||||
|
||||
/// Set a field of this lua object
|
||||
template<typename T>
|
||||
void setField(const std::string& key, const T& value) {
|
||||
m_luaTable->setField(key, value);
|
||||
}
|
||||
|
||||
/// Get a field of this lua object
|
||||
LuaValuePtr getField(const std::string& key) {
|
||||
return m_luaTable->getField(key);
|
||||
}
|
||||
|
||||
/// Returns current use count by the shared_ptr
|
||||
int getUseCount() { return shared_from_this().use_count() - 1; }
|
||||
|
||||
/// Class name used in lua, must be overridden by derived classes
|
||||
virtual const char* getLuaTypeName() const = 0;
|
||||
|
||||
/** Convert to a lua value for pushing this object into lua stack.
|
||||
* Each call to this will create a new pointer, thus increasing the use count.*/
|
||||
LuaValuePtr toLuaValue();
|
||||
|
||||
LuaObjectPtr asLuaObject() { return shared_from_this(); }
|
||||
|
||||
private:
|
||||
LuaValuePtr m_luaTable;
|
||||
};
|
||||
|
||||
#endif // LUAOBJECT_H
|