-- player_toolbar - Player UI, commands, and logic for graphical Chat Toolbar
-- (optional component of Chat System)
-- Template attachment: player (dynamic)
-- Created by: Patrick Ferland
-- Created on: 05/27/2008
-- Revision History
-- 05/27/2008 P.Ferland - New script
-- 05/30/2008 P.Ferland - Initial release
-- 06/02/2008 P.Ferland - Cleanup and documentation
-- 06/09/2008 P.Ferland - Separated toolbar from core skin and cleaned up
-- 06/10/2008 P.Ferland - Added tooltips
-- 06/27/2008 P.Ferland - Winstyle cleanup
-- 07/01/2008 P.Ferland - Modified to use stylesheet winstyles
-- 07/17/2008 P.Ferland - Changed channel selection to use player channel aliases
-- 07/29/2008 P.Ferland - Moved pause highlight to be glow behind button instead of bar on top
-- 07/30/2008 P.Ferland - Fixed spammy pause highlight visibility
-- 08/01/2008 P.Ferland - Modified to use standard UI for tooltips and popup
-- Constants
TOOLBAR_X_SPACING = 5
BUTTONS =
{
SELECTED = '11304:306'
}
-- Support for force-publish, where events sequence differently
DEFAULT_TEXTFIELD_DATA =
{
winstyle = '11302:61',
icon =
{ sprite = '11302:499', w = 15, h = 11, x = 3, y = 23 },
x = 10, y = 4,
w = 388, h = 16,
winheight = 25,
win_y = 2,
fc = { r = 64, g = 64, b = 64 },
bc = { r = 255, g = 255, b = 255, a = 0.0 },
visible = 1
}
-- Script Properties
Define Properties()
-- Window style
chat_system_toolbar_ws = ''
-- UI handle for toolbar
chat_system_toolbar = 0
-- X position to draw next toolbar element
chat_system_toolbar_next_x = 5
-- Y position for all elements
chat_system_toolbar_y = 0
-- UI handles for toolbar elements
chat_system_toolbar_pause_button = 0
chat_system_toolbar_pause_highlight = 0
chat_system_toolbar_channel_display = 0
chat_system_toolbar_channel_select = 0
chat_system_toolbar_skin_select = 0
chat_system_toolbar_size_buttons =
{
min = 0,
normal = 0,
max = 0
}
chat_system_toolbar_tooltips =
{
pause = 0,
channel_select = 0,
skin_select = 0,
min = 0,
normal = 0,
max = 0
}
chat_system_toolbar_popup = 0
chat_system_old_pause = 0
-- Internal data for current channel display
chat_system_toolbar_current_channel = 'UNKNOWN'
chat_system_toolbar_new_channel = 'Chat'
-- Trigger list to prevent multiple callbacks
chat_system_toolbar_active_triggers = {}
IncludeScript('11302:12') -- chat_utility
IncludeScript('13197:21') -- ui_library
end
-- Commands
Define Commands()
MakeCommand('chat_system_toolbar_channel_select', 'Chat Toolbar: Select a Channel')
MakeCommand('chat_system_toolbar_channel_picked', 'Chat Toolbar: Change to Selected Channel', 'channel:string')
MakeCommand('chat_system_toolbar_skin_select', 'Chat Toolbar: Select a Skin')
MakeCommand('chat_system_toolbar_skin_picked', 'Chat Toolbar: Change to Selected Skin', 'skin:string')
MakeCommand('chat_system_toolbar_popup_close', 'Chat Toolbar: Close Popup')
MakeCommand('chat_system_toolbar_pause', 'Chat Toolbar: Pause Chat')
end
-- Close toolbar popup
Command chat_system_toolbar_popup_close()
chat_system_toolbar_clear_popup(self)
end
-- Toggle the user's pause status
Command chat_system_toolbar_pause(skin)
chat_system_toolbar_clear_popup(self)
DoCommand(self, 'chat_system_player_chat', '/pause')
end
-- Open channel selection popup
Command chat_system_toolbar_channel_select()
local w = GetWorld()
if (w.chat_system.chat_system_toolbar_channel_select ~= 1) then
return
end
chat_system_toolbar_draw_popup(self, 'Select Channel')
local channel_listbox = UiListBox(self.chat_system_toolbar_popup, 'chat_system_toolbar_channel_select',
20, 40, 160, 120, 'chat_system_toolbar_channel_picked')
local channel = ''
for channel, _ in pairs(self.chat_system_channel_aliases) do
UiListItem(channel_listbox, channel, channel)
end
end
-- Select a new channel
Command chat_system_toolbar_channel_picked(channel)
local w = GetWorld()
if (w.chat_system.chat_system_toolbar_channel_select ~= 1) then
return
end
--local new_channel = chat_system_selectable_channel_decode(w.chat_system, self, channel)
local new_channel = self.chat_system_channel_aliases[channel]
if (new_channel ~= '') then
self.chat_system_current_channel = new_channel
end
chat_system_toolbar_clear_popup(self)
end
-- Open skin selection popup
Command chat_system_toolbar_skin_select()
local w = GetWorld()
if (w.chat_system.chat_system_skins_player_change ~= 1) then
return
end
if (w.chat_system.chat_system_toolbar_skin_select ~= 1) then
return
end
chat_system_toolbar_draw_popup(self, 'Select Skin')
local channel_listbox = UiListBox(self.chat_system_toolbar_popup, 'chat_system_toolbar_channel_select',
20, 40, 160, 120, 'chat_system_toolbar_skin_picked')
local channel = ''
for channel, _ in pairs(w.chat_system.chat_system_skins) do
UiListItem(channel_listbox, channel, channel)
end
end
-- Select a new skin
Command chat_system_toolbar_skin_picked(skin)
local w = GetWorld()
if (w.chat_system.chat_system_skins_player_change ~= 1) then
return
end
if (w.chat_system.chat_system_toolbar_skin_select ~= 1) then
return
end
chat_system_toolbar_clear_popup(self)
DoCommand(self, 'chat_system_player_chat', '/chatskin ' .. skin .. ' ' .. self.chat_system_skin_size)
end
-- Triggers
-- System trigger: Fired when script is attached (dynamic)
Trigger attach()
SendTo(self, 'chat_system_toolbar_init', 250)
end
-- System trigger: Fired when script is detached (cleanup remnants of toolbar)
Trigger detach()
chat_system_clear_toolbar(self)
end
-- Chat System trigger: Draw toolbar (slightly later than chat window itself is rendered)
Trigger chat_system_initialize()
SendTo(self, 'chat_system_toolbar_init', 250)
end
-- Draw toolbar, including selected "standard" toolbar components
Trigger chat_system_toolbar_init()
local w = GetWorld()
if (w.chat_system == nil) then
return
end
if ( (self.chat_system_window== 0) or (self.chat_system_window== nil) ) then
--chat_system_debug('Chat Window not present; delaying toolbar')
SendTo(self, 'chat_system_toolbar_init', 250)
end
chat_system_clear_toolbar(self)
-- TODO: separate UI draw into a function or trigger of its own
if (w.chat_system.chat_system_toolbar_enabled ~= 1) then
return
end
local chat_skin_data = {}
if (w.chat_system.chat_system_skins_player_change == 1) then
-- Load player skin
chat_skin_data = w.chat_system.chat_system_skins[self.chat_system_skin]
else
chat_skin_data = w.chat_system.chat_system_skins[w.chat_system.chat_system_skin]
end
if (chat_skin_data == nil) then -- ACK! Try to acquire default
chat_skin_data = w.chat_system.chat_system_skins[DEFAULT_SKIN]
end
if (chat_skin_data == nil) then -- ABORT
return
end
local chat_skin = {}
if (w.chat_system.chat_system_skins_player_change == 1) then
-- Load player skin
chat_skin= chat_skin_data[self.chat_system_skin_size]
else
chat_skin= chat_skin_data[w.chat_system.chat_system_skin_size]
end
self.chat_system_toolbar_ws = chat_skin.toolbar.ws
self.chat_system_toolbar_y = chat_skin.toolbar.item_y
-- optional init_x parameter of toolbar skin
if (chat_skin.toolbar.init_x ~= nil) then
self.chat_system_toolbar_next_x = chat_skin.toolbar.init_x
end
-- Force upgrade patch!
if (chat_skin.textfield.win_y == nil) then
chat_skin.textfield = table.deepcopy(DEFAULT_TEXTFIELD_DATA)
end
local chat_toolbar_mod_y = chat_skin.toolbar.y + chat_skin.textfield.winheight
self.chat_system_toolbar = UiWindow(self.chat_system_window, 'chat_system_toolbar',
chat_skin.toolbar.x, chat_toolbar_mod_y, chat_skin.toolbar.w, chat_skin.toolbar.h,
self.chat_system_toolbar_ws)
UiVisible(self.chat_system_toolbar, chat_skin.toolbar.visible)
-- Core toolbar elements
if (w.chat_system.chat_system_toolbar_pause_display == 1) then
chat_system_toolbar_draw_pause_button(self, chat_skin.toolbar)
end
if (w.chat_system.chat_system_toolbar_channel_display == 1) then
chat_system_toolbar_draw_channel_display(self)
end
if (w.chat_system.chat_system_toolbar_channel_select == 1) then
chat_system_toolbar_draw_channel_select(self, chat_skin.toolbar)
end
if (w.chat_system.chat_system_toolbar_skin_select == 1) then
chat_system_toolbar_draw_skin_select(self, chat_skin.toolbar)
end
if (w.chat_system.chat_system_toolbar_size_buttons == 1) then
chat_system_toolbar_draw_size_buttons(self, chat_skin.toolbar)
end
end
-- Synchronize displayed channel with user's current channel
Trigger chat_system_toolbar_channel_display_update()
if ( (self.chat_system_toolbar_channel_display == 0) or (self.chat_system_toolbar == 0) ) then
return
end
local alias = ''
local channel = ''
for alias, channel in pairs(self.chat_system_channel_aliases) do
if (channel == self.chat_system_current_channel) then
self.chat_system_toolbar_new_channel = alias
end
end
if (self.chat_system_toolbar_new_channel ~= self.chat_system_toolbar_current_channel) then
UiText(self.chat_system_toolbar_channel_display, '' .. self.chat_system_toolbar_new_channel .. '')
end
self.chat_system_toolbar_current_channel = self.chat_system_toolbar_new_channel
local w = GetWorld()
if (w.chat_system ~= nil) then
if (w.chat_system.chat_system_toolbar_channel_display == 1) then
self.chat_system_toolbar_active_triggers['chat_system_toolbar_channel_display_update'] = nil
chat_system_toolbar_safe_trigger(self, 'chat_system_toolbar_channel_display_update', 5000)
end
end
end
-- Synchronize pause-button "highlight" with user's current pause status
Trigger chat_system_toolbar_pause_highlight_update()
if ( (self.chat_system_toolbar_pause_button == 0) or (self.chat_system_toolbar == 0) ) then
return
end
if (self.chat_system_toolbar_pause_highlight ~= 0) then
if (self.chat_system_pause ~= self.chat_system_old_pause) then
if (self.chat_system_pause == 0) then
-- hide highlight
-- It's possible that the parent was deleted, so search for the toolbar before deleting
if (UiFindWindow(self.chat_system_window, 'chat_system_toolbar') ~= 0) then
UiVisible(self.chat_system_toolbar_pause_highlight, 0)
end
elseif (self.chat_system_pause == 1) then
-- show highlight
UiVisible(self.chat_system_toolbar_pause_highlight, 1)
end
end
self.chat_system_old_pause = self.chat_system_pause
end
self.chat_system_toolbar_active_triggers['chat_system_toolbar_pause_highlight_update'] = nil
chat_system_toolbar_safe_trigger(self, 'chat_system_toolbar_pause_highlight_update', 1000)
end
-- Local functions
-- Draw channel display label on toolbar
function chat_system_toolbar_draw_channel_display(self)
if (self.chat_system_toolbar_channel_display ~= 0) then
UiDelete(self.chat_system_toolbar_channel_display)
end
self.chat_system_toolbar_channel_display = UiMultiLabel(self.chat_system_toolbar, 'toolbar_channel_display',
self.chat_system_toolbar_next_x - 4, self.chat_system_toolbar_y - 4, 60, 24,
0, 0, 0, 255, 255, 255, 0,
0, 0, 0)
UiColor(self.chat_system_toolbar_channel_display, 0, 0, 0, 1)
UiVisible(self.chat_system_toolbar_channel_display, 1)
chat_system_toolbar_element_added(self, 60)
self.chat_system_toolbar_active_triggers['chat_system_toolbar_channel_display_update'] = nil
chat_system_toolbar_safe_trigger(self, 'chat_system_toolbar_channel_display_update', 0)
end
-- Draw channel selection button on toolbar
function chat_system_toolbar_draw_channel_select(self, style)
if (self.chat_system_toolbar_channel_select ~= 0) then
UiDelete(self.chat_system_toolbar_channel_select)
end
self.chat_system_toolbar_channel_select = UiImageButton(self.chat_system_toolbar, 'toolbar_channel_select',
self.chat_system_toolbar_next_x, self.chat_system_toolbar_y, 16, 16,
style.BUTTONS.CHANNELS.bn, style.BUTTONS.CHANNELS.bh, style.BUTTONS.CHANNELS.bp,
'chat_system_toolbar_channel_select')
chat_system_toolbar_element_added(self, 16)
self.chat_system_toolbar_tooltips.channel_select =
chat_system_toolbar_tooltip(self, 'Select Channel', self.chat_system_toolbar_channel_select)
end
-- Draw skin selection button on toolbar
function chat_system_toolbar_draw_skin_select(self, style)
if (self.chat_system_toolbar_skin_select ~= 0) then
UiDelete(self.chat_system_toolbar_skin_select)
end
local w = GetWorld()
if (w.chat_system.chat_system_skins_player_change == 1) then
self.chat_system_toolbar_skin_select = UiImageButton(self.chat_system_toolbar, 'toolbar_channel_select',
self.chat_system_toolbar_next_x, self.chat_system_toolbar_y, 16, 16,
style.BUTTONS.SKINS.bn, style.BUTTONS.SKINS.bh, style.BUTTONS.SKINS.bp, 'chat_system_toolbar_skin_select')
chat_system_toolbar_element_added(self, 16)
self.chat_system_toolbar_tooltips.skin_select =
chat_system_toolbar_tooltip(self, 'Select Skin', self.chat_system_toolbar_skin_select)
end
end
-- Draw pause button on toolbar
function chat_system_toolbar_draw_pause_button(self, style)
self.chat_system_toolbar_pause_highlight = UiImage(self.chat_system_toolbar, 'chat_system_toolbar_pause_highlight',
self.chat_system_toolbar_next_x - 4, self.chat_system_toolbar_y - 4, 24, 24,
BUTTONS.SELECTED)
UiVisible(self.chat_system_toolbar_pause_highlight, 0)
self.chat_system_toolbar_pause_button = UiImageButton(self.chat_system_toolbar, 'chat_system_toolbar_pause_button',
self.chat_system_toolbar_next_x, self.chat_system_toolbar_y, 16, 16,
style.BUTTONS.PAUSE.bn, style.BUTTONS.PAUSE.bh, style.BUTTONS.PAUSE.bp,
'chat_system_toolbar_pause')
chat_system_toolbar_element_added(self, 16)
self.chat_system_toolbar_tooltips.pause =
chat_system_toolbar_tooltip(self, 'Pause/Unpause Chat', self.chat_system_toolbar_pause_button)
self.chat_system_toolbar_active_triggers['chat_system_toolbar_pause_highlight_update'] = nil
chat_system_toolbar_safe_trigger(self, 'chat_system_toolbar_pause_highlight_update', 0)
end
-- Draw min/normal/max buttons on toolbar
function chat_system_toolbar_draw_size_buttons(self, style)
local buttons = self.chat_system_toolbar_size_buttons
if (buttons.min ~= 0) then
UiDelete(buttons.min)
end
if (buttons.normal ~= 0) then
UiDelete(buttons.normal)
end
if (buttons.max ~= 0) then
UiDelete(buttons.max)
end
local w = GetWorld()
if (w.chat_system.chat_system_skins_player_change == 1) then
if (w.chat_system.chat_system_skins_minimized_enabled == 1) then
buttons.min = UiImageButton(self.chat_system_toolbar, 'toolbar_chat_system_toolbar_size_button_min',
self.chat_system_toolbar_next_x, self.chat_system_toolbar_y, 16, 16,
style.BUTTONS.MIN.bn, style.BUTTONS.MIN.bh, style.BUTTONS.MIN.bp,
'chat_system_player_chat /chatskin ' .. self.chat_system_skin .. ' min')
chat_system_toolbar_element_added(self, 16)
self.chat_system_toolbar_tooltips.min =
chat_system_toolbar_tooltip(self, 'Minimize Chat', buttons.min)
end
if (w.chat_system.chat_system_skins_normal_enabled == 1) then
buttons.normal = UiImageButton(self.chat_system_toolbar, 'toolbar_chat_system_toolbar_size_button_normal',
self.chat_system_toolbar_next_x, self.chat_system_toolbar_y, 16, 16,
style.BUTTONS.NORMAL.bn, style.BUTTONS.NORMAL.bh, style.BUTTONS.NORMAL.bp,
'chat_system_player_chat /chatskin ' .. self.chat_system_skin .. ' normal')
chat_system_toolbar_element_added(self, 16)
self.chat_system_toolbar_tooltips.normal =
chat_system_toolbar_tooltip(self, 'Normal-size Chat', buttons.normal)
end
if (w.chat_system.chat_system_skins_maximized_enabled == 1) then
buttons.max = UiImageButton(self.chat_system_toolbar, 'toolbar_chat_system_toolbar_size_button_max',
self.chat_system_toolbar_next_x, self.chat_system_toolbar_y, 16, 16,
style.BUTTONS.MAX.bn, style.BUTTONS.MAX.bh, style.BUTTONS.MAX.bp,
'chat_system_player_chat /chatskin ' .. self.chat_system_skin .. ' max')
chat_system_toolbar_element_added(self, 16)
self.chat_system_toolbar_tooltips.max =
chat_system_toolbar_tooltip(self, 'Maximize Chat', buttons.max)
end
end
end
-- Safely delete toolbar
function chat_system_clear_toolbar(self)
if ( (self.chat_system_toolbar ~= 0) and (self.chat_system_toolbar ~= nil) ) then
-- It's possible that the parent was deleted, so search for the toolbar before deleting
if (UiFindWindow(self.chat_system_window, 'chat_system_toolbar') ~= 0) then
UiDelete(self.chat_system_toolbar)
end
self.chat_system_toolbar_pause_button = 0
self.chat_system_toolbar_pause_highlight = 0
self.chat_system_toolbar = 0
self.chat_system_toolbar_next_x = 5
self.chat_system_toolbar_channel_display = 0
self.chat_system_toolbar_current_channel = 'UNKNOWN'
self.chat_system_toolbar_new_channel = 'Chat'
self.chat_system_toolbar_channel_select = 0
self.chat_system_toolbar_skin_select = 0
self.chat_system_toolbar_size_buttons.min = 0
self.chat_system_toolbar_size_buttons.normal = 0
self.chat_system_toolbar_size_buttons.max = 0
table.clear(self.chat_system_toolbar_active_triggers)
local key = ''
local window = 0
for key, window in pairs(self.chat_system_toolbar_tooltips) do
if (window ~= 0) then
UiDelete(window)
self.chat_system_toolbar_tooltips[key] = 0
end
end
end
if ( self.chat_system_toolbar_popup ~= nil ) then
chat_system_toolbar_clear_popup(self)
end
end
-- Increment "next X" position for toolbar
function chat_system_toolbar_element_added(self, width)
self.chat_system_toolbar_next_x = self.chat_system_toolbar_next_x + width + TOOLBAR_X_SPACING
end
-- Safely delete toolbar popup window
function chat_system_toolbar_clear_popup(self)
if (self.chat_system_toolbar_popup ~= 0) then
local popup = UiFindWindow(self.chat_system_toolbar_popup, 'chat_system_toolbar_popup')
if (popup ~= 0) then
UiDelete(self.chat_system_toolbar_popup)
end
self.chat_system_toolbar_popup = 0
end
end
-- Draw popup window
function chat_system_toolbar_draw_popup(self, title, x, y, w, h)
local xx = 0
local yy = 0
local ww = 200
local hh = 200
if (x ~= nil) then
xx = x
end
if (y ~= nil) then
yy = y
end
if (w ~= nil) then
ww = w
end
if (h ~= nil) then
hh = h
end
chat_system_toolbar_clear_popup(self)
local w = GetWorld()
local chat_skin_data = {}
if (w.chat_system.chat_system_skins_player_change == 1) then
-- Load player skin
chat_skin_data = w.chat_system.chat_system_skins[self.chat_system_skin]
else
chat_skin_data = w.chat_system.chat_system_skins[w.chat_system.chat_system_skin]
end
if (chat_skin_data == nil) then -- ACK! Try to acquire default
chat_skin_data = w.chat_system.chat_system_skins[DEFAULT_SKIN]
end
if (chat_skin_data == nil) then -- ABORT
return
end
local chat_skin = {}
if (w.chat_system.chat_system_skins_player_change == 1) then
-- Load player skin
chat_skin = chat_skin_data[self.chat_system_skin_size]
else
chat_skin = chat_skin_data[w.chat_system.chat_system_skin_size]
end
local ws = chat_skin.popup_winstyle
if (ws == nil) then -- ABORT
return
end
local color = chat_skin.popup_title_color
if (color == nil) then -- DEFAULT
color = { r = 0, g = 0, b = 0 }
end
local button = chat_skin.close_button
if (button == nil) then -- DEFAULT
button =
{ bn = '11304:133', bh = '11304:132', bp = '11304:131', x = -20, y = 1, w = 16, h = 16 }
end
local popup_win_style = ws
-- self.chat_system_toolbar_popup = UiWindow(0, 'chat_system_toolbar_popup', xx, yy, ww, hh, popup_win_style)
self.chat_system_toolbar_popup = ui_default_window(0, 'chat_system_toolbar_popup',
xx, yy, ww, hh)
local label_title = UiMultiLabel(self.chat_system_toolbar_popup, 'chat_system_toolbar_popup_title',
0, 0, ww - 25, 24,
0, 0, 0, 255, 255, 255, 0,
0, 0, 0)
UiText(label_title, '' .. title .. '')
-- local button_close = UiImageButton(self.chat_system_toolbar_popup, 'chat_system_toolbar_popup_close_button',
-- ww + button.x, button.y, button.w, button.h, button.bn, button.bh, button.bp, 'chat_system_toolbar_popup_close')
UiAlign(self.chat_system_toolbar_popup, 0, 0, 'center', 'scale_none')
UiAttachUser(self, self.chat_system_toolbar_popup)
UiVisible(self.chat_system_toolbar_popup, 1)
end
-- Safely call a trigger (prevent multiple stacked calls)
function chat_system_toolbar_safe_trigger(self, name, interval, ...)
if (self.chat_system_toolbar_active_triggers[name] == nil) then
self.chat_system_toolbar_active_triggers[name] = name
SendTo(self, name, interval, unpack(arg) )
end
end
-- Render a tooltip for a UI element
function chat_system_toolbar_tooltip(self, text, item)
local tooltip_id = ui_tooltip(item, text, 500, 'above', self)
return tooltip_id
end