-- 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