diff --git a/Themes/_fallback/BGAnimations/ScreenOptionsCustomizeProfile overlay.lua b/Themes/_fallback/BGAnimations/ScreenOptionsCustomizeProfile overlay.lua new file mode 100644 index 0000000000..828b565dfd --- /dev/null +++ b/Themes/_fallback/BGAnimations/ScreenOptionsCustomizeProfile overlay.lua @@ -0,0 +1,172 @@ +-- Pester Kyzentun for an explanation if you need to customize this screen. +-- Also, this might be rewritten to us a proper customizable lua menu system +-- in the future. + +local profile= GAMESTATE:GetEditLocalProfile() + +local number_entry= new_numpad_entry{ + Name= "number_entry", + InitCommand= cmd(diffusealpha, 0; xy, _screen.cx*1.5, _screen.cy), + value_color= PlayerColor(PLAYER_1), + cursor_draw= "first", + cursor_color= PlayerDarkColor(PLAYER_1), +} + +local function item_value_to_text(item, value) + if item.item_type == "bool" then + if value then + value= THEME:GetString("ScreenOptionsCustomizeProfile", item.true_text) + else + value= THEME:GetString("ScreenOptionsCustomizeProfile", item.false_text) + end + end + return value +end + +local menu_items= { + {name= "weight", get= "GetWeightPounds", set= "SetWeightPounds", + item_type= "number", auto_done= 100}, + {name= "voomax", get= "GetVoomax", set= "SetVoomax", item_type= "number", + auto_done= 10}, + {name= "birth_year", get= "GetBirthYear", set= "SetBirthYear", + item_type= "number", auto_done= 1000}, + {name= "calorie_calc", get= "GetIgnoreStepCountCalories", + set= "SetIgnoreStepCountCalories", item_type= "bool", + true_text= "use_heart", false_text= "use_steps"}, + {name= "gender", get= "GetIsMale", set= "SetIsMale", item_type= "bool", + true_text= "male", false_text= "female"}, + {name= "exit", item_type= "exit"} +} + +local menu_cursor +local menu_pos= 1 +local menu_start= 72 +local menu_x= 32 +local value_x= 300 +local fader +local cursor_on_menu= true +local menu_item_actors= {} +local menu_values= {} + +local function fade_actor_to(actor, alf) + actor:stoptweening() + actor:linear(.2) + actor:diffusealpha(alf) +end + +local function update_menu_cursor() + menu_cursor:stoptweening() + menu_cursor:linear(.1) + menu_cursor:y(menu_item_actors[menu_pos]:GetY()) + menu_cursor:SetWidth(menu_item_actors[menu_pos]:GetWidth() + 20) +end + +local function input(event) + local pn= event.PlayerNumber + if not pn then return false end + if event.type == "InputEventType_Release" then return false end + local button= event.GameButton + if cursor_on_menu then + if button == "Start" then + local item= menu_items[menu_pos] + if item.item_type == "bool" then + local value= not Profile[item.get](profile) + menu_values[menu_pos]:settext(item_value_to_text(item, value)) + Profile[item.set](profile, value) + elseif item.item_type == "number" then + fade_actor_to(fader, .8) + fade_actor_to(number_entry.container, 1) + number_entry.value= Profile[item.get](profile) + number_entry.value_actor:playcommand("Set", {number_entry.value}) + number_entry.auto_done_value= item.auto_done + number_entry.max_value= item.max + number_entry:update_cursor(number_entry.cursor_start) + number_entry.prompt_actor:playcommand( + "Set", {THEME:GetString("ScreenOptionsCustomizeProfile", item.name)}) + cursor_on_menu= false + elseif item.item_type == "exit" then + SCREENMAN:GetTopScreen():StartTransitioningScreen("SM_GoToNextScreen") + SOUND:PlayOnce(THEME:GetPathS("Common", "Start")) + end + else + if button == "MenuLeft" or button == "MenuUp" then + if menu_pos > 1 then menu_pos= menu_pos - 1 end + update_menu_cursor() + elseif button == "MenuRight" or button == "MenuDown" then + if menu_pos < #menu_items then menu_pos= menu_pos + 1 end + update_menu_cursor() + end + end + else + local done= number_entry:handle_input(button) + if done then + local item= menu_items[menu_pos] + Profile[item.set](profile, number_entry.value) + menu_values[menu_pos]:settext(item_value_to_text(item, number_entry.value)) + fade_actor_to(fader, 0) + fade_actor_to(number_entry.container, 0) + cursor_on_menu= true + end + end +end + +local args= { + Def.Actor{ + OnCommand= function(self) + update_menu_cursor() + SCREENMAN:GetTopScreen():AddInputCallback(input) + end + }, + Def.Quad{ + Name= "menu_cursor", InitCommand= function(self) + menu_cursor= self + self:horizalign(left) + self:setsize(0, 24) + self:diffuse(PlayerColor(PLAYER_1)) + self:xy(menu_x - 10, menu_start) + end, + }, +} + +for i, item in ipairs(menu_items) do + local item_y= menu_start + ((i-1) * 24) + args[#args+1]= Def.BitmapText{ + Name= "menu_" .. item.name, Font= "Common Normal", + Text= THEME:GetString("ScreenOptionsCustomizeProfile", item.name), + InitCommand= function(self) + menu_item_actors[i]= self + self:xy(menu_x, item_y) + self:diffuse(Color.White) + self:horizalign(left) + end + } + if item.get then + local value_text= item_value_to_text(item, Profile[item.get](profile)) + args[#args+1]= Def.BitmapText{ + Name= "value_" .. item.name, Font= "Common Normal", + Text= value_text, + InitCommand= function(self) + menu_values[i]= self + self:xy(value_x, menu_start + ((i-1) * 24)) + self:diffuse(Color.White) + self:horizalign(left) + end + } + end +end + +args[#args+1]= Def.Quad{ + Name= "fader", InitCommand= function(self) + fader= self + self:setsize(270, #menu_items * 24) + self:horizalign(left) + self:vertalign(top) + self:xy(menu_x-10, menu_start-12) + self:diffuse(Color.Black) + self:diffusealpha(0) + end +} + +args[#args+1]= number_entry:create_actors() + +return Def.ActorFrame(args) diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 1d3b381432..fa6dd33c83 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -1618,6 +1618,18 @@ Are you sure you want to delete the profile '%s'?=Are you sure you want to delet Enter a name for the profile.=Enter a name for the profile. NewProfileDefaultName=New +[ScreenOptionsCustomizeProfile] +weight=Weight (lbs) +voomax=VO2Max +birth_year=Birth Year +gender=Gender +calorie_calc=Calorie Calculation +exit=Exit +use_heart=Use Heart Rate +use_steps=Use Step Count +male=Male +female=Female + [ScreenOptionsMaster] Exit=Exit @@ -1664,6 +1676,9 @@ Cancel=CANCEL HeaderText=High Scores HeaderSubText=Who's the top dog? +[ScreenHeartEntry] +HeaderText=Check Your Pulse! + [ScreenContinue] HelpText=&START; Advance Timer diff --git a/Themes/_fallback/Scripts/04 NumPadEntry.lua b/Themes/_fallback/Scripts/04 NumPadEntry.lua index e232b9b154..c989280eb4 100644 --- a/Themes/_fallback/Scripts/04 NumPadEntry.lua +++ b/Themes/_fallback/Scripts/04 NumPadEntry.lua @@ -164,7 +164,7 @@ -- -- positions provided in button_positions. -- -- GainFocus, LoseFocus, and Press are optional commands for handling -- -- their respective events. --- button_actor= Def.BitmapText{ +-- button= Def.BitmapText{ -- InitCommand= cmd(diffuse, Color.White), -- -- SetCommand is executed after InitCommand to set the value for the -- -- button. param is a table containing a value from button_values. @@ -188,7 +188,7 @@ -- value_color= Color.White, -- -- Optional. The actor used for displaying the value the player has -- -- entered so far. Default is a simple BitmapText. --- value_actor= Def.BitmapText{ +-- value= Def.BitmapText{ -- Font= "Common Normal", -- -- InitCommand should set the position you want if you pass a custom -- -- actor. @@ -208,9 +208,17 @@ -- -- Optional. The text used by the default prompt actor. Default is "". -- prompt_text= "", -- -- Optional. The actor to use for displaying the prompt. Any actor you --- -- want. No commands are required, and it must position and initialize --- -- itself. --- prompt= Def.Actor{}, +-- -- want. It should support a Set command if the NumPadEntry is on a +-- -- screen where it will be reused for different numbers. +-- prompt= Def.BitmapText{ +-- Font= "Common Normal", +-- -- InitCommand should set the position you want if you pass a custom +-- -- actor. +-- InitCommand= cmd(xy, 0, -48), +-- -- SetCommand will be executed when a button is pressed and the value +-- -- is changed. param is a table containing the new value. +-- SetCommand= function(self, param) self:settext(param[1]) end +-- }, -- } local function noop() end @@ -258,7 +266,8 @@ local numpad_entry_mt= { end local default_start= cr_to_pos( {math.ceil(self.columns/2), math.ceil(self.rows/2)}, self.columns) - self.cursor_pos= params.cursor_start or default_start + self.cursor_start= params.cursor_start or default_start + self.cursor_pos= self.cursor_start self.done_text= params.done_text or "&start;" self.back_text= params.back_text or "←" self.button_values= params.button_values or @@ -363,7 +372,7 @@ local numpad_entry_mt= { end, SetCommand= function(subself, param) subself:settext(param[1]) end} local va_template= params.value or default_vat - if not va_template.SetCommand then va_template.SetCommand= noop end + add_default_commands_to_actor({"SetCommand"}, va_template) local vainit= va_template.InitCommand or noop va_template.InitCommand= function(subself) self.value_actor= subself @@ -377,8 +386,16 @@ local numpad_entry_mt= { Font= params.prompt_font or params.Font or "Common Normal", InitCommand= cmd(xy, prompt_pos[1], prompt_pos[2]; diffuse, params.prompt_color or Color.White), - Text= params.prompt_text or ""} - args[#args+1]= params.prompt or default_prompt + Text= params.prompt_text or "", + SetCommand= function(subself, param) subself:settext(param[1]) end} + local prompt_template= params.prompt or default_prompt + local prompt_init= prompt_template.InitCommand or noop + add_default_commands_to_actor({"SetCommand"}, prompt_template) + prompt_template.InitCommand= function(subself) + self.prompt_actor= subself + prompt_init(subself) + end + args[#args+1]= prompt_template if params.cursor_draw == "last" then args[#args+1]= cursor_template end diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index 088bde938a..c3c604abfb 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -3123,6 +3123,18 @@ TimerSeconds=-1 Class="ScreenOptionsEditProfile" PageOnCommand=visible,false +[ScreenOptionsCustomizeProfile] +Class="ScreenWithMenuElements" +Fallback="ScreenWithMenuElements" +PrevScreen="ScreenOptionsManageProfiles" +NextScreen="ScreenOptionsManageProfiles" +PlayMusic=false +ShowHeader=false +ShowFooter=false +ShowCreditDisplay=false +TimerSeconds=-1 +TimerOnCommand=visible,false + [ScreenReloadSongs] Class="ScreenReloadSongs" Fallback="Screen" diff --git a/Themes/default/BGAnimations/ScreenHeartEntry overlay.lua b/Themes/default/BGAnimations/ScreenHeartEntry overlay.lua index 73aef8e808..5229752fc3 100644 --- a/Themes/default/BGAnimations/ScreenHeartEntry overlay.lua +++ b/Themes/default/BGAnimations/ScreenHeartEntry overlay.lua @@ -13,8 +13,6 @@ for i, pn in ipairs(GAMESTATE:GetEnabledPlayers()) do heart_entries[pn]= new_numpad_entry{ Name= pn .. "_heart_entry", InitCommand= cmd(xy, heart_xs[pn], SCREEN_CENTER_Y+48), - value_pos = { 0, -64 }, - value_color= PlayerColor(pn), value = LoadFont("Common Large") .. { InitCommand=cmd(xy,0,-62), OnCommand=cmd(zoom,0.75;diffuse,PlayerColor(pn);strokecolor,ColorDarkTone(PlayerColor(pn))); @@ -66,7 +64,6 @@ for i, pn in ipairs(GAMESTATE:GetEnabledPlayers()) do } }, cursor_draw= "first", - cursor_color= PlayerDarkColor(pn), prompt = LoadFont("Common Bold") .. { Name="prompt", Text=THEME:GetString("ScreenHeartEntry", "Heart Rate"), @@ -84,7 +81,7 @@ local function input(event) if not pn then return end if event.type == "InputEventType_Release" then return end if not heart_entries[pn] then return end - local done= heart_entries[pn]:handle_input(event.button) + local done= heart_entries[pn]:handle_input(event.GameButton) if done then SOUND:PlayOnce(THEME:GetPathS("Common", "Start")) local all_done= true diff --git a/Themes/default/BGAnimations/ScreenOptionsCustomizeProfile overlay.lua b/Themes/default/BGAnimations/ScreenOptionsCustomizeProfile overlay.lua new file mode 100644 index 0000000000..3bcec8c3d0 --- /dev/null +++ b/Themes/default/BGAnimations/ScreenOptionsCustomizeProfile overlay.lua @@ -0,0 +1,260 @@ +-- Pester Kyzentun for an explanation if you need to customize this screen. +-- Also, this might be rewritten to us a proper customizable lua menu system +-- in the future. + +local profile= GAMESTATE:GetEditLocalProfile() + +local cursor_width_padding = 16 +local cursor_spacing_value = 30 + +local number_entry= new_numpad_entry{ + Name= "number_entry", + InitCommand= cmd(diffusealpha, 0; xy, _screen.cx*1.5, _screen.cy), + value = LoadFont("Common Large") .. { + InitCommand=cmd(xy,0,-62), + OnCommand=cmd(zoom,0.75;diffuse,PlayerColor(PLAYER_1);strokecolor,ColorDarkTone(PlayerColor(PLAYER_1))); + SetCommand=function(self, param) + self:settext(param[1]) + end, + }, + button = LoadFont("Common Normal") ..{ + InitCommand=cmd(shadowlength,1), + SetCommand=function(self, param) + self:settext(param[1]) + end, + OnCommand=cmd(diffuse,color("0.8,0.8,0.8,1");zoom,0.875), + GainFocusCommand=cmd(finishtweening;decelerate,0.125;zoom,1;diffuse,Color.White), + LoseFocusCommand=cmd(finishtweening;smooth,0.1;zoom,0.875;diffuse,color("0.8,0.8,0.8,1")) + }, + button_positions = {{-cursor_spacing_value, -cursor_spacing_value}, {0, -cursor_spacing_value}, {cursor_spacing_value, -cursor_spacing_value}, + {-cursor_spacing_value, 0}, {0, 0}, {cursor_spacing_value, 0}, + {-cursor_spacing_value, cursor_spacing_value}, {0, cursor_spacing_value}, {cursor_spacing_value, cursor_spacing_value}, + {-cursor_spacing_value, cursor_spacing_value*2}, {0, cursor_spacing_value*2}, {cursor_spacing_value, cursor_spacing_value*2}}, + cursor = Def.ActorFrame { + -- Move whole container + MoveCommand=function(self, param) + self:stoptweening() + self:decelerate(0.15) + self:xy(param[1], param[2]) + if param[3] then + self:z(param[3]) + end + end, + -- + LoadActor( THEME:GetPathG("_frame", "1D"), + { 2/18, 14/18, 2/18 }, + LoadActor(THEME:GetPathB("_frame", "cursors/rounded fill")) + ) .. { + OnCommand=cmd(diffuse,PlayerDarkColor(PLAYER_1)), + FitCommand=function(self, param) + self:playcommand("SetSize",{ Width=param:GetWidth()+cursor_width_padding, tween=cmd(decelerate,0.125)}) + end, + }, + LoadActor( THEME:GetPathG("_frame", "1D"), + { 2/18, 14/18, 2/18 }, + LoadActor(THEME:GetPathB("_frame", "cursors/rounded gloss")) + ) .. { + OnCommand=cmd(diffuse,PlayerColor(PLAYER_1)), + FitCommand=function(self, param) + self:playcommand("SetSize",{ Width=param:GetWidth()+cursor_width_padding, tween=cmd(decelerate,0.125)}) + end, + } + }, + cursor_draw= "first", + prompt = LoadFont("Common Bold") .. { + Name="prompt", + InitCommand=cmd(xy,0,-96); + OnCommand=cmd(shadowlength,1;skewx,-0.125;diffusebottomedge,color("#DDDDDD");strokecolor,Color.Outline); + SetCommand= function(self, params) + self:settext(params[1]) + end + }, + LoadActor(THEME:GetPathB("_frame","3x3"),"rounded black", 128, 192) .. { + InitCommand=cmd(xy, 0, -20) + } +} + +local function item_value_to_text(item, value) + if item.item_type == "bool" then + if value then + value= THEME:GetString("ScreenOptionsCustomizeProfile", item.true_text) + else + value= THEME:GetString("ScreenOptionsCustomizeProfile", item.false_text) + end + end + return value +end + +local menu_items= { + {name= "weight", get= "GetWeightPounds", set= "SetWeightPounds", + item_type= "number", auto_done= 100}, + {name= "voomax", get= "GetVoomax", set= "SetVoomax", item_type= "number", + auto_done= 10}, + {name= "birth_year", get= "GetBirthYear", set= "SetBirthYear", + item_type= "number", auto_done= 1000}, + {name= "calorie_calc", get= "GetIgnoreStepCountCalories", + set= "SetIgnoreStepCountCalories", item_type= "bool", + true_text= "use_heart", false_text= "use_steps"}, + {name= "gender", get= "GetIsMale", set= "SetIsMale", item_type= "bool", + true_text= "male", false_text= "female"}, + {name= "exit", item_type= "exit"} +} + +local menu_cursor +local menu_pos= 1 +local menu_start= 72 +local menu_x= 32 +local value_x= 300 +local fader +local cursor_on_menu= true +local menu_item_actors= {} +local menu_values= {} + +local function fade_actor_to(actor, alf) + actor:stoptweening() + actor:linear(.2) + actor:diffusealpha(alf) +end + +local function update_menu_cursor() + local item= menu_item_actors[menu_pos] + menu_cursor:playcommand("Move", {item:GetX(), item:GetY()}) + menu_cursor:playcommand("Fit", item) +end + +local function input(event) + local pn= event.PlayerNumber + if not pn then return false end + if event.type == "InputEventType_Release" then return false end + local button= event.GameButton + if cursor_on_menu then + if button == "Start" then + local item= menu_items[menu_pos] + if item.item_type == "bool" then + local value= not Profile[item.get](profile) + menu_values[menu_pos]:settext(item_value_to_text(item, value)) + Profile[item.set](profile, value) + elseif item.item_type == "number" then + fade_actor_to(fader, .8) + fade_actor_to(number_entry.container, 1) + number_entry.value= Profile[item.get](profile) + number_entry.value_actor:playcommand("Set", {number_entry.value}) + number_entry.auto_done_value= item.auto_done + number_entry.max_value= item.max + number_entry:update_cursor(number_entry.cursor_start) + number_entry.prompt_actor:playcommand( + "Set", {THEME:GetString("ScreenOptionsCustomizeProfile", item.name)}) + cursor_on_menu= false + elseif item.item_type == "exit" then + SCREENMAN:GetTopScreen():StartTransitioningScreen("SM_GoToNextScreen") + SOUND:PlayOnce(THEME:GetPathS("Common", "Start")) + end + else + if button == "MenuLeft" or button == "MenuUp" then + if menu_pos > 1 then menu_pos= menu_pos - 1 end + update_menu_cursor() + elseif button == "MenuRight" or button == "MenuDown" then + if menu_pos < #menu_items then menu_pos= menu_pos + 1 end + update_menu_cursor() + end + end + else + local done= number_entry:handle_input(button) + if done then + local item= menu_items[menu_pos] + Profile[item.set](profile, number_entry.value) + menu_values[menu_pos]:settext(item_value_to_text(item, number_entry.value)) + fade_actor_to(fader, 0) + fade_actor_to(number_entry.container, 0) + cursor_on_menu= true + end + end +end + +local args= { + Def.Actor{ + OnCommand= function(self) + update_menu_cursor() + SCREENMAN:GetTopScreen():AddInputCallback(input) + end + }, + Def.ActorFrame { + Name= "menu_cursor", InitCommand= function(self) + menu_cursor= self + end, + -- Move whole container + MoveCommand=function(self, param) + self:stoptweening() + self:decelerate(0.15) + self:xy(param[1], param[2]) + if param[3] then + self:z(param[3]) + end + end, + FitCommand= function(self, param) + self:addx(param:GetWidth()/2) + end, + -- + LoadActor( THEME:GetPathG("_frame", "1D"), + { 2/18, 14/18, 2/18 }, + LoadActor(THEME:GetPathB("_frame", "cursors/rounded fill")) + ) .. { + OnCommand=cmd(diffuse,PlayerDarkColor(PLAYER_1)), + FitCommand=function(self, param) + self:playcommand("SetSize",{ Width=param:GetWidth()+cursor_width_padding, tween=cmd(decelerate,0.125)}) + end, + }, + LoadActor( THEME:GetPathG("_frame", "1D"), + { 2/18, 14/18, 2/18 }, + LoadActor(THEME:GetPathB("_frame", "cursors/rounded gloss")) + ) .. { + OnCommand=cmd(diffuse,PlayerColor(PLAYER_1)), + FitCommand=function(self, param) + self:playcommand("SetSize",{ Width=param:GetWidth()+cursor_width_padding, tween=cmd(decelerate,0.125)}) + end, + } + }, +} + +for i, item in ipairs(menu_items) do + local item_y= menu_start + ((i-1) * 24) + args[#args+1]= Def.BitmapText{ + Name= "menu_" .. item.name, Font= "Common Normal", + Text= THEME:GetString("ScreenOptionsCustomizeProfile", item.name), + InitCommand= function(self) + menu_item_actors[i]= self + self:xy(menu_x, item_y) + self:diffuse(Color.White) + self:horizalign(left) + end + } + if item.get then + local value_text= item_value_to_text(item, Profile[item.get](profile)) + args[#args+1]= Def.BitmapText{ + Name= "value_" .. item.name, Font= "Common Normal", + Text= value_text, + InitCommand= function(self) + menu_values[i]= self + self:xy(value_x, menu_start + ((i-1) * 24)) + self:diffuse(Color.White) + self:horizalign(left) + end + } + end +end + +args[#args+1]= Def.Quad{ + Name= "fader", InitCommand= function(self) + fader= self + self:setsize(270, #menu_items * 24) + self:horizalign(left) + self:vertalign(top) + self:xy(menu_x-10, menu_start-12) + self:diffuse(Color.Black) + self:diffusealpha(0) + end +} + +args[#args+1]= number_entry:create_actors() + +return Def.ActorFrame(args) diff --git a/Themes/default/metrics.ini b/Themes/default/metrics.ini index aa132ac658..6a8f799528 100644 --- a/Themes/default/metrics.ini +++ b/Themes/default/metrics.ini @@ -1630,6 +1630,8 @@ ActiveAttackListP2OffCommand= [ScreenHeartEntry] HeartEntryEnabled=true +ShowHeader=true +ShowFooter=true [ScreenEvaluation] Class="ScreenEvaluation" diff --git a/src/ScreenOptionsManageProfiles.cpp b/src/ScreenOptionsManageProfiles.cpp index 7d312554c2..dae1d916e0 100644 --- a/src/ScreenOptionsManageProfiles.cpp +++ b/src/ScreenOptionsManageProfiles.cpp @@ -113,7 +113,7 @@ void ScreenOptionsManageProfiles::BeginScreen() Profile *pProfile = PROFILEMAN->GetLocalProfile( *s ); ASSERT( pProfile != NULL ); - RString sCommand = ssprintf( "gamecommand;screen,ScreenOptionsEditProfile;profileid,%s;name,dummy", s->c_str() ); + RString sCommand = ssprintf( "gamecommand;screen,ScreenOptionsCustomizeProfile;profileid,%s;name,dummy", s->c_str() ); OptionRowHandler *pHand = OptionRowHandlerUtil::Make( ParseCommands(sCommand) ); OptionRowDefinition &def = pHand->m_Def; def.m_layoutType = LAYOUT_SHOW_ALL_IN_ROW; @@ -380,7 +380,7 @@ void ScreenOptionsManageProfiles::ProcessMenuStart( const InputEventPlus & ) } else { - //ADD_ACTION( ProfileAction_Edit ); + ADD_ACTION( ProfileAction_Edit ); ADD_ACTION( ProfileAction_Rename ); ADD_ACTION( ProfileAction_Delete ); } diff --git a/src/ThemeManager.cpp b/src/ThemeManager.cpp index f7aade0692..fd3ba340e6 100644 --- a/src/ThemeManager.cpp +++ b/src/ThemeManager.cpp @@ -1056,6 +1056,7 @@ void ThemeManager::PushMetric( Lua *L, const RString &sMetricsGroup, const RStri if(sMetricsGroup == "" || sValueName == "") { LuaHelpers::ReportScriptError("PushMetric: Attempted to fetch metric with empty group name or empty value name."); + lua_pushnil(L); return; } RString sValue = GetMetricRaw( g_pLoadedThemeData->iniMetrics, sMetricsGroup, sValueName );