-
Notifications
You must be signed in to change notification settings - Fork 0
/
messages.lua
192 lines (159 loc) · 5.51 KB
/
messages.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
-----------------------------------------------------------------------------------------
--
-- messages.lua
--
-- The act for the Messages tab in the Mars App game
-----------------------------------------------------------------------------------------
-- Get local reference to the game globals
local game = globalGame
-- Corona modules needed
local widget = require( "widget" )
-- Game modules needed
local msgText = require( "msgText" )
-- Create the act object
local act = game.newAct()
------------------------- Start of Activity --------------------------------
-- Data for the act
local dxyMargin = 10 -- margin around messages list
local dxyMarginText = 5 -- margin between boxes and text
local msgs = {} -- array of message ids that have been displayed (in send order)
local newMsgs = {} -- array of message ids sent but not yet displayed
local scrollView -- scrollView widget for the list
local yNextMsg -- y position for next text message in the scrollView
local newMsgTimer -- timer for checking for new messages
local badge -- tab bar badge for new message indicator
local newMarksGroup -- display group for individual new message indicators
-- Load the new text sound
local textSound = audio.loadSound( "media/game/TextTone.wav" )
-- Send the message with the given id and optional delay in ms
function game.sendMessage( id, delay )
-- Re-send later if a delay is requested
if type(delay) == "number" then
timer.performWithDelay( delay,
function ()
game.sendMessage( id )
end )
return
end
-- Append message to newMsgs list
newMsgs[#newMsgs + 1] = id
-- Create new message badge if necessary, and show it
if not badge then
badge = game.createBadge( act.xMin + act.width * 0.66, act.yMax + 10 )
end
game.showBadge( badge )
game.playSound( textSound )
-- Show message preview window if not in the messages view
if game.currentActName() ~= "messages" then
game.showMessagePreview( msgText[id] )
end
end
-- Send all the messages ids given by variable parameter list
function game.sendMessages( ... )
for i, v in ipairs{ ... } do
game.sendMessage( v )
end
end
-- Init the act
function act:init()
-- Background and title bar for the view
act:whiteBackground()
act:makeTitleBar( "Messages" )
-- Make a scroll view that covers the rest of the act area
yNextMsg = dxyMargin -- position for the first message
scrollView = widget.newScrollView{
left = act.xMin,
top = act.yMin + act.dyTitleBar,
width = act.width,
height = act.height - act.dyTitleBar,
scrollWidth = act.width,
scrollHeight = yNextMsg,
horizontalScrollDisabled = true,
backgroundColor = { 1, 1, 1 }, -- white
hideScrollBar = false,
}
act.group:insert( scrollView )
-- TODO: Add previously sent messages from saved state (and save them there)
end
-- Display the next new message if there is one waiting
local function checkNewMsg()
-- Nothing to do if no message waiting. Also ignore stray timer triggers.
if #newMsgs <= 0 or not newMarksGroup then
return
end
-- Move the next new message id to the end of the displayed messages list
local id = table.remove( newMsgs, 1 )
msgs[#msgs + 1] = id
local str = msgText[id]
-- Create a multi-line wrapped text object for the message string
local x = dxyMargin
local textWidth = act.width - dxyMargin * 2 - dxyMarginText * 2
local text = display.newText{
text = str,
x = x + dxyMarginText,
y = yNextMsg + dxyMarginText,
width = textWidth,
height = 0, -- auto-size the height
font = native.systemFont,
fontSize = 14,
align = "left",
}
text:setFillColor( 1 ) -- white
text.anchorX = 0
text.anchorY = 0
-- Make a rounded rect for the message box with height sized for the text
local rr = display.newRoundedRect( scrollView, x, yNextMsg,
textWidth + dxyMarginText * 2,
text.height + dxyMarginText * 2, 5 )
rr.anchorX = 0
rr.anchorY = 0
rr:setFillColor( 0.3 ) -- dark gray
-- Make the new message indicator in the upper right of the rounded rect
local c = display.newCircle( newMarksGroup, rr.x + rr.width - 3, rr.y + 3, 6 )
c:setFillColor( 1, 1, 0 ) -- yellow fill
c:setStrokeColor( 0 ) -- black frame
c.strokeWidth = 1
-- Put the items into the scrollView in the right stacking order
scrollView:insert( rr )
scrollView:insert( text )
scrollView:insert( newMarksGroup ) -- keep indicators on top
-- Calculate position for the next message and scroll to make sure that
-- the last message is fully visible.
yNextMsg = yNextMsg + rr.height + dxyMargin
scrollView:setScrollHeight( yNextMsg )
local yScroll = scrollView.height - yNextMsg
if yScroll > 0 then
yScroll = 0
end
scrollView:scrollToPosition( { y = yScroll, time = 200 } )
-- Hide the badge if this was the last message waiting
if #newMsgs <= 0 then
game.hideBadge( badge )
end
end
-- Prepare the act
function act:prepare()
game.hideMessagePreview()
newMarksGroup = act:newGroup( scrollView )
end
-- Prepare the act to show
function act:start()
-- Start a repeating timer to check for messages after a brief interval each
newMsgTimer = timer.performWithDelay( 250, checkNewMsg, 0 )
end
-- Stop the act
function act:stop()
-- Cancel the new message check timer
if newMsgTimer then
timer.cancel( newMsgTimer )
newMsgTimer = nil
end
-- Remove the individual new message indicators
if newMarksGroup then
newMarksGroup:removeSelf()
newMarksGroup = nil
end
end
------------------------- End of Activity --------------------------------
-- Corona needs the scene object returned from the act file
return act.scene