diff --git a/Northstar.Client/mod.json b/Northstar.Client/mod.json index 0d0cfc169..eb96e79ab 100644 --- a/Northstar.Client/mod.json +++ b/Northstar.Client/mod.json @@ -130,6 +130,13 @@ "Path": "ui/ns_slider.nut", "RunOn": "UI" }, + { + "Path": "ui/menu_ns_color_picker.nut", + "RunOn": "UI", + "UICallback": { + "After": "AddColorPickerMenu" + } + }, { "Path": "ui/menu_mod_settings.nut", "RunOn": "UI", diff --git a/Northstar.Client/mod/resource/ui/menus/colorsliders.menu b/Northstar.Client/mod/resource/ui/menus/colorsliders.menu new file mode 100644 index 000000000..59c076333 --- /dev/null +++ b/Northstar.Client/mod/resource/ui/menus/colorsliders.menu @@ -0,0 +1,616 @@ +resource/ui/menus/colorsliders.menu +{ + + menu + { + ControlName Frame + xpos 0 + ypos 0 + zpos 3 + wide f0 + tall f0 + autoResize 0 + pinCorner 0 + visible 1 + enabled 1 + tabPosition 0 + PaintBackgroundType 0 + infocus_bgcolor_override "0 0 0 0" + outoffocus_bgcolor_override "0 0 0 0" + modal 1 + + DarkenBackground + { + ControlName RuiButton + rui "ui/basic_image.rpak" + + wide %100 + tall %100 + bgcolor_override "0 0 0 255" + fgcolor_override "0 0 0 255" + visible 1 + scaleImage 1 + + } + + + DialogFrameButton + { + ControlName Label + wide 600 + tall 400 + // rui "ui/basic_image.rpak" + visible 1 + + pin_to_sibling DarkenBackground + pin_corner_to_sibling CENTER + pin_to_sibling_corner CENTER + } + + DialogFrame + { + ControlName RuiPanel + wide 600 + tall 400 + rui "ui/basic_image.rpak" + visible 1 + + pin_to_sibling DarkenBackground + pin_corner_to_sibling CENTER + pin_to_sibling_corner CENTER + } + + + + DialogHeader + { + ControlName Label + xpos 130 + ypos -50 + labelText "#COLOR_MODE" + + wide 764 + tall 41 + visible 1 + labelText "" + font DefaultBold_41 + allcaps 1 + fgcolor_override "255 255 255 255" + + pin_to_sibling DialogFrame + pin_corner_to_sibling CENTER + pin_to_sibling_corner TOP + } + + Color + { + "ControlName" "ImagePanel" + "image" "vgui/white" + "scaleImage" "1" + "drawColor" "180 180 180 255" // vanilla label color + "visible" "1" + "wide" "600" + "tall" "20" + "enabled" "0" + + + "pin_to_sibling" DialogFrame + "pin_corner_to_sibling" TOP + "pin_to_sibling_corner" TOP + } + + DialogMessage + { + ControlName Label + classname DialogMessageClass + ypos 0 + wide 736 + auto_tall_tocontents 1 + visible 1 + labelText "" + font Default_28 + textAlignment north-west + wrap 1 + + pin_to_sibling DialogHeader + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + } + + LabelR // A label that is placed in the middle of the screen + { + Classname LabelClass + + ControlName Label + xpos -15 + ypos 35 + labelText "R" + "scriptID" "0" + + auto_wide_tocontents 1 // Set width automatically relative to the label content + + pin_to_sibling DialogMessage + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + } + + SliderR + { + Classname SliderClass + xpos 15 + "ControlName" "SliderControl" + "scriptID" "0" + + minValue 0 + maxValue 255 + stepSize 1 + drawColor "255 0 0 255" + + pin_to_sibling LabelR + pin_corner_to_sibling LEFT + pin_to_sibling_corner RIGHT + + //"navRight" "ResetModToDefault" + //"navLeft" "TextEntrySetting" + + BtnDropButton + { + ControlName RuiButton + + style SliderButton + wide "320" + tall "45" + "labelText" "" + "auto_wide_tocontents" "0" + } + + "wide" "320" + "tall" "45" + } + + TextEntrySettingR + { + "ControlName" "TextEntry" + Classname TextEntrySettingClass + + "xpos" 20 + "ypos" "-5" + "zpos" "100" // This works around input weirdness when the control is constructed by code instead of VGUI blackbox. + "wide" 50 + "tall" "30" + "scriptID" "0" + "textHidden" "0" + "editable" "1" + NumericInputOnly 1 + "font" "Default_21" + "allowRightClickMenu" "0" + "allowSpecialCharacters" "1" + "unicode" "0" + "scriptID" "0" + + pin_to_sibling SliderR + pin_corner_to_sibling LEFT + pin_to_sibling_corner RIGHT + } + + + ResetModToDefaultR + { + Classname ResetModToDefaultClass + "ControlName" "RuiButton" + "InheritProperties" "RuiSmallButton" + "labelText" "" + "zpos" "0" + "xpos" "10" + "wide" "75" + "tall" "45" + "scriptID" "0" + "pin_to_sibling" TextEntrySettingR + "pin_corner_to_sibling" "LEFT" + "pin_to_sibling_corner" "RIGHT" + + "navLeft" "TextEntrySettingR" + "navRight" "SliderG" + "enabled" "1" + + } + ResetModImageR + { + "ControlName" "ImagePanel" + "image" "vgui/reset" + "scaleImage" "1" + "drawColor" "180 180 180 255" // vanilla label color + "visible" "1" + "wide" "30" + "tall" "30" + "enabled" "0" + + "pin_to_sibling" ResetModToDefaultR + "pin_corner_to_sibling" "CENTER" + "pin_to_sibling_corner" "CENTER" + } + + + + + + + + + + + + + + + + LabelG // A label that is placed in the middle of the screen + { + Classname LabelClass + + ControlName Label + "scriptID" "1" + + ypos 25 + labelText "G" + + auto_wide_tocontents 1 // Set width automatically relative to the label content + + pin_to_sibling LabelR + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + } + + SliderG + { + Classname SliderClass + + xpos 15 + "ControlName" "SliderControl" + "scriptID" "1" + + minValue 0 + maxValue 255 + stepSize 1 + drawColor "255 0 0 255" + + pin_to_sibling LabelG + pin_corner_to_sibling LEFT + pin_to_sibling_corner RIGHT + + //"navRight" "ResetModToDefault" + //"navLeft" "TextEntrySetting" + + BtnDropButton + { + ControlName RuiButton + + style SliderButton + wide "320" + tall "45" + "labelText" "" + "auto_wide_tocontents" "0" + } + + "wide" "320" + "tall" "45" + } + + + TextEntrySettingG + { + "ControlName" "TextEntry" + Classname TextEntrySettingClass + + "xpos" 20 + "ypos" "-5" + "zpos" "100" // This works around input weirdness when the control is constructed by code instead of VGUI blackbox. + "wide" 50 + "tall" "30" + "scriptID" "1" + + "textHidden" "0" + "editable" "1" + NumericInputOnly 1 + "font" "Default_21" + "allowRightClickMenu" "0" + "allowSpecialCharacters" "1" + "unicode" "0" + + pin_to_sibling SliderG + pin_corner_to_sibling LEFT + pin_to_sibling_corner RIGHT + } + + ResetModToDefaultG + { + Classname ResetModToDefaultClass + + "enabled" "1" + + "ControlName" "RuiButton" + "InheritProperties" "RuiSmallButton" + "labelText" "" + "zpos" "0" + "xpos" "10" + "wide" "75" + "tall" "45" + "scriptID" "1" + + "pin_to_sibling" TextEntrySettingG + "pin_corner_to_sibling" "LEFT" + "pin_to_sibling_corner" "RIGHT" + + "navLeft" "TextEntrySettingG" + "navRight" "SliderB" + "enabled" "1" + } + ResetModImageG + { + "ControlName" "ImagePanel" + "image" "vgui/reset" + "scaleImage" "1" + "drawColor" "180 180 180 255" // vanilla label color + "visible" "1" + "wide" "30" + "tall" "30" + "enabled" "1" + + "pin_to_sibling" ResetModToDefaultG + "pin_corner_to_sibling" "CENTER" + "pin_to_sibling_corner" "CENTER" + } + + + + + + + LabelB // A label that is placed in the middle of the screen + { + Classname LabelClass + + + ControlName Label + "scriptID" "2" + + ypos 25 + labelText "B" + + auto_wide_tocontents 1 // Set width automatically relative to the label content + + pin_to_sibling LabelG + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + } + + SliderB + { + Classname SliderClass + + xpos 15 + "ControlName" "SliderControl" + "scriptID" "2" + + minValue 0 + maxValue 255 + stepSize 1 + drawColor "255 0 0 255" + + pin_to_sibling LabelB + pin_corner_to_sibling LEFT + pin_to_sibling_corner RIGHT + + //"navRight" "ResetModToDefault" + //"navLeft" "TextEntrySetting" + + BtnDropButton + { + ControlName RuiButton + + style SliderButton + wide "320" + tall "45" + "labelText" "" + "auto_wide_tocontents" "0" + } + + "wide" "320" + "tall" "45" + } + + TextEntrySettingB + { + Classname TextEntrySettingClass + + "ControlName" "TextEntry" + "xpos" 20 + "ypos" "-5" + "zpos" "100" // This works around input weirdness when the control is constructed by code instead of VGUI blackbox. + "wide" 50 + "tall" "30" + "scriptID" "2" + + "textHidden" "0" + "editable" "1" + NumericInputOnly 1 + "font" "Default_21" + "allowRightClickMenu" "0" + "allowSpecialCharacters" "1" + "unicode" "0" + + pin_to_sibling SliderB + pin_corner_to_sibling LEFT + pin_to_sibling_corner RIGHT + } + ResetModToDefaultB + { + Classname ResetModToDefaultClass + + "enabled" "1" + + "ControlName" "RuiButton" + "InheritProperties" "RuiSmallButton" + "labelText" "" + "zpos" "0" + "xpos" "10" + "wide" "75" + "tall" "45" + "scriptID" "2" + + "pin_to_sibling" TextEntrySettingB + "pin_corner_to_sibling" "LEFT" + "pin_to_sibling_corner" "RIGHT" + + "navLeft" "TextEntrySettingB" + "navRight" "SliderA" + "enabled" "1" + } + ResetModImageB + { + "ControlName" "ImagePanel" + "image" "vgui/reset" + "scaleImage" "1" + "drawColor" "180 180 180 255" // vanilla label color + "visible" "1" + "wide" "30" + "tall" "30" + "enabled" "0" + + "pin_to_sibling" ResetModToDefaultB + "pin_corner_to_sibling" "CENTER" + "pin_to_sibling_corner" "CENTER" + } + + + + LabelA // A label that is placed in the middle of the screen + { + Classname LabelClass + + + ControlName Label + "scriptID" "3" + + ypos 25 + labelText "A" + + auto_wide_tocontents 1 // Set width automatically relative to the label content + + pin_to_sibling LabelB + pin_corner_to_sibling TOP_LEFT + pin_to_sibling_corner BOTTOM_LEFT + } + + SliderA + { + Classname SliderClass + + xpos 15 + "ControlName" "SliderControl" + "scriptID" "3" + + minValue 0 + maxValue 255 + stepSize 1 + drawColor "255 0 0 255" + + pin_to_sibling LabelA + pin_corner_to_sibling LEFT + pin_to_sibling_corner RIGHT + + //"navRight" "ResetModToDefault" + //"navLeft" "TextEntrySetting" + + BtnDropButton + { + ControlName RuiButton + + style SliderButton + wide "320" + tall "45" + "labelText" "" + "auto_wide_tocontents" "0" + } + + "wide" "320" + "tall" "45" + } + + TextEntrySettingA + { + Classname TextEntrySettingClass + + "ControlName" "TextEntry" + "xpos" 20 + "ypos" "-5" + "zpos" "100" // This works around input weirdness when the control is constructed by code instead of VGUI blackbox. + "wide" 50 + "tall" "30" + "scriptID" "3" + + "textHidden" "0" + "editable" "1" + NumericInputOnly 1 + "font" "Default_21" + "allowRightClickMenu" "0" + "allowSpecialCharacters" "1" + "unicode" "0" + + pin_to_sibling SliderA + pin_corner_to_sibling LEFT + pin_to_sibling_corner RIGHT + } + ResetModToDefaultA + { + Classname ResetModToDefaultClass + + "enabled" "1" + + "ControlName" "RuiButton" + "InheritProperties" "RuiSmallButton" + "labelText" "" + "zpos" "0" + "xpos" "10" + "wide" "75" + "tall" "45" + "scriptID" "3" + + "pin_to_sibling" TextEntrySettingA + "pin_corner_to_sibling" "LEFT" + "pin_to_sibling_corner" "RIGHT" + + "navLeft" "TextEntrySettingA" + "enabled" "1" + } + ResetModImageA + { + "ControlName" "ImagePanel" + "image" "vgui/reset" + "scaleImage" "1" + "drawColor" "180 180 180 255" // vanilla label color + "visible" "1" + "wide" "30" + "tall" "30" + "enabled" "0" + + "pin_to_sibling" ResetModToDefaultA + "pin_corner_to_sibling" "CENTER" + "pin_to_sibling_corner" "CENTER" + } + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + } + +} \ No newline at end of file diff --git a/Northstar.Client/mod/resource/ui/menus/panels/mod_setting.res b/Northstar.Client/mod/resource/ui/menus/panels/mod_setting.res index 92dce922d..b862caec5 100644 --- a/Northstar.Client/mod/resource/ui/menus/panels/mod_setting.res +++ b/Northstar.Client/mod/resource/ui/menus/panels/mod_setting.res @@ -94,6 +94,47 @@ "navLeft" "ResetModToDefault" "navRight" "TextEntrySetting" } + "ColorPickerButton" + { + "ControlName" "RuiButton" + "InheritProperties" "RuiSmallButton" + "labelText" "#EDIT" + "zpos" "0" + "xpos" "10" + // ypos -10 + "wide" "320" + "tall" "45" + "scriptID" "0" + "pin_to_sibling" "BtnMod" + "pin_corner_to_sibling" "TOP_LEFT" + "pin_to_sibling_corner" "TOP_RIGHT" + + "navRight" "ResetModToDefault" + "navLeft" "TextEntrySetting" + + "visible" "0" + FocusColor "0 0 0 0" + textAlignment center + font Default_23 + wrap 0 + } + "ColorPickerImage" + { + "ControlName" "ImagePanel" + "image" "vgui/white" + "scaleImage" "1" + "drawColor" "255 255 255 255" // vanilla label color + "visible" "0" + "wide" "320" + "tall" "45" + "enabled" "0" + + ypos 0 + + "pin_to_sibling" "ColorPickerButton" + "pin_corner_to_sibling" RIGHT + "pin_to_sibling_corner" LEFT + } "ResetModToDefault" { "ControlName" "RuiButton" @@ -109,6 +150,8 @@ "pin_to_sibling_corner" "LEFT" "navLeft" "Slider" "navRight" "TextEntrySetting" + "navLeft" "ColorPickerButton" + } "ResetModImage" { diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_mod_settings.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_mod_settings.nut index 8c13955cc..f81c5ee66 100644 --- a/Northstar.Client/mod/scripts/vscripts/ui/menu_mod_settings.nut +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_mod_settings.nut @@ -8,6 +8,10 @@ global function ModSettings_AddModTitle global function ModSettings_AddModCategory global function PureModulo +global function ModSettings_AddColorSetting +global function ModSettings_AddAlphaSetting +global function TryUpdateModSettingLists + // Legacy functions for backwards compatability. These will be removed eventually global function AddConVarSetting global function AddConVarSettingEnum @@ -79,6 +83,14 @@ struct { int deltaY = 0 } mouseDeltaBuffer +struct Color +{ + int r + int g + int b + int a +} + void function AddModSettingsMenu() { AddMenu( "ModSettings", $"resource/ui/menus/mod_settings.menu", InitModMenu ) @@ -154,6 +166,13 @@ void function InitModMenu() Hud_AddEventHandler( child, UIE_CLICK, ResetConVar ) file.resetModButtons.append(child) + // color nav + child = Hud_GetChild( panel, "ColorPickerButton" ) + Hud_AddEventHandler( child, UIE_CLICK, ColorButtonPressed ) + child.SetNavUp( Hud_GetChild( file.modPanels[ int( PureModulo( i - 1, len ) ) ], "ColorPickerButton" ) ) + child.SetNavDown( Hud_GetChild( file.modPanels[ int( PureModulo( i + 1, len ) ) ], "ColorPickerButton" ) ) + + // text field nav child = Hud_GetChild( panel, "TextEntrySetting" ) @@ -520,9 +539,17 @@ void function SetModMenuNameText( var button ) var modTitle = Hud_GetChild( panel, "ModTitle" ) var customMenuButton = Hud_GetChild( panel, "OpenCustomMenu") var slider = Hud_GetChild( panel, "Slider" ) + + var colorButton = Hud_GetChild( panel, "ColorPickerButton" ) + var colorVGUI = Hud_GetChild( panel, "ColorPickerImage" ) + + Hud_SetVisible( slider, false ) Hud_SetEnabled( slider, true ) - + Hud_SetVisible( colorButton, false ) + Hud_SetVisible( colorVGUI, false ) + Hud_SetEnabled( colorButton, false ) + Hud_SetEnabled( colorVGUI, false ) if ( conVar.isEmptySpace ) { @@ -631,6 +658,54 @@ void function SetModMenuNameText( var button ) Hud_SetVisible( textField, true ) Hud_SetVisible( resetButton, true ) Hud_SetVisible( resetVGUI, true ) + + // color + if (conVar.type == "color") + { + try { + Color color = StringToColors( GetConVarString(conVar.conVar) ) + Hud_SetVisible( colorButton, true ) + Hud_SetVisible( colorVGUI, true ) + Hud_SetEnabled( colorButton, true ) + Hud_SetEnabled( colorVGUI, true ) + Hud_SetSize( label, int(scaleX * (375 + 85)), int(scaleY * 40) ) + Hud_SetSize( colorVGUI, int( scaleX * ( 50 ) ), int( scaleY * 20 ) ) + Hud_SetSize( colorButton, int( scaleX * ( 300 ) ), int( scaleY * 35 ) ) + + Hud_SetColor(colorVGUI, color.r, color.g, color.b, color.a) + // Hud_ColorOverTime(colorVGUI, color.r, color.g, color.b, color.a, 1, 1) + } + catch ( ex ) + { + printt(ex) + ThrowInvalidValue("This setting is a color, and only accepts a four of numbers(each number should be a integer between 0 and 255) - you put something we could not parse!\n\n( Input like \"255 255 255 255\", not \"" + conVar.conVar + "\". )\n Press reset button or change the default value in mod.json. Or inform the mod author.") + + Hud_SetSize( colorVGUI, 0, int( 45 * scaleY ) ) + Hud_SetSize( colorButton, 0, int( 45 * scaleY ) ) + Hud_SetEnabled( colorButton, false ) + Hud_SetEnabled( colorVGUI, false ) + Hud_SetColor(colorVGUI, 0, 0, 0, 0) + } + } + else if (conVar.type == "alpha") { + Hud_SetVisible( colorVGUI, true ) + Hud_SetEnabled( colorVGUI, true ) + Hud_SetSize( colorVGUI, int( scaleX * ( 20 ) ), int( scaleY * 20 ) ) + + float alpha = GetConVarFloat(conVar.conVar) + Hud_SetColor(colorVGUI, 124, 252, 0, 255) + Hud_SetAlpha(colorVGUI, int(alpha * 255)) + + } + else + { + Hud_SetSize( colorVGUI, 0, int( 45 * scaleY ) ) + Hud_SetSize( colorButton, 0, int( 45 * scaleY ) ) + Hud_SetEnabled( colorButton, false ) + Hud_SetEnabled( colorVGUI, false ) + Hud_SetColor(colorVGUI, 0, 0, 0, 0) + + } } } @@ -641,6 +716,19 @@ void function CustomButtonPressed( var button ) c.onPress() } +void function ColorButtonPressed( var button ) +{ + var panel = Hud_GetParent( button ) + ConVarData c = file.filteredList[ int( Hud_GetScriptID( panel ) ) + file.scrollOffset ] + // c.onPress() + // printt(c.displayName, c.type, c.conVar) + + thread OpenColorPickerMenu(c.conVar, c.displayName) + + + // UpdateList() +} + void function OnScrollDown( var button ) { if ( file.filteredList.len() <= BUTTONS_PER_PAGE ) return @@ -782,7 +870,7 @@ void function ModSettings_AddModCategory( string catName, int stackPos = 2 ) { if ( !( getstackinfos( stackPos )[ "func" ] in file.setFuncs ) ) throw getstackinfos( stackPos )[ "src" ] + " #" + getstackinfos( stackPos )[ "line" ] + "\nCannot add a category before a mod title!" - + ConVarData space space.isEmptySpace = true space.modName = file.currentMod @@ -848,6 +936,45 @@ void function AddConVarSetting( string conVar, string displayName, string type = ModSettings_AddSetting( conVar, displayName, type, stackPos + 1 ) } +void function ModSettings_AddColorSetting(string conVar, string buttonLabel, void functionref() onPress = null, int stackPos = 2) +{ + if ( !( getstackinfos( stackPos )[ "func" ] in file.setFuncs ) || !file.setFuncs[ expect string( getstackinfos( stackPos )[ "func" ] ) ] ) + throw getstackinfos( stackPos )[ "src" ] + " #" + getstackinfos( stackPos )[ "line" ] + "\nCannot add a button before a category and mod title!" + + ConVarData data + + + data.conVar = conVar + data.type = "color" + data.displayName = buttonLabel + data.modName = file.currentMod + data.catName = file.currentCat + data.onPress = onPress + + file.conVarList.append( data ) +} + +void function ModSettings_AddAlphaSetting(string conVar, string displayName, int stackPos = 2) +{ + if ( !( getstackinfos( stackPos )[ "func" ] in file.setFuncs ) || !file.setFuncs[ expect string( getstackinfos( stackPos )[ "func" ] ) ] ) + throw getstackinfos( stackPos )[ "src" ] + " #" + getstackinfos( stackPos )[ "line" ] + "\nCannot add a button before a category and mod title!" + + ConVarData data + + data.catName = file.currentCat + data.conVar = conVar + data.modName = file.currentMod + data.displayName = displayName + data.type = "alpha" + data.sliderEnabled = true + data.forceClamp = false + data.min = 0 + data.max = 1 + data.stepSize = 0.05 + + file.conVarList.append( data ) +} + void function ModSettings_AddSliderSetting( string conVar, string displayName, float min = 0.0, float max = 1.0, float stepSize = 0.1, bool forceClamp = false, int stackPos = 2 ) { if ( !( getstackinfos( stackPos )[ "func" ] in file.setFuncs ) || !file.setFuncs[ expect string( getstackinfos( stackPos )[ "func" ] ) ] ) @@ -926,11 +1053,22 @@ void function OnSliderChange( var button ) MS_Slider_SetValue( file.sliders[ int( Hud_GetScriptID( Hud_GetParent( textPanel ) ) ) ], val ) Hud_SetText( textPanel, string( GetConVarFloat( c.conVar ) ) ) + + if (c.type == "alpha") { + var colorVGUI = Hud_GetChild( Hud_GetParent( textPanel ), "ColorPickerImage" ) + + float alpha = GetConVarFloat(c.conVar) + Hud_SetAlpha(colorVGUI, int(alpha * 255)) + // Hud_SetColor(colorVGUI, 255, 255, 255, 255) + } } void function SendTextPanelChanges( var textPanel ) { ConVarData c = file.filteredList[ int( Hud_GetScriptID( Hud_GetParent( textPanel ) ) ) + file.scrollOffset ] + var colorButton = Hud_GetChild( Hud_GetParent( textPanel ), "ColorPickerButton" ) + var colorVGUI = Hud_GetChild( Hud_GetParent( textPanel ), "ColorPickerImage" ) + if ( c.conVar == "" ) return // enums don't need to do this if ( !c.isEnumSetting ) @@ -1022,6 +1160,74 @@ void function SendTextPanelChanges( var textPanel ) Hud_SetText( textPanel, GetConVarString( c.conVar ) ) } break + case "color": + try { + array split = split( newSetting, " " ) + if ( split.len() < 3 || split.len() > 4) + { + throw "" + } + + array color + string clampedNewSetting = "" + foreach (string val in split) { + int c = int(clamp(val.tointeger(), 0 ,255)) + color.append(c) + + clampedNewSetting += c + " " + } + + if (split.len() == 3) + { + color.append(255) + clampedNewSetting += " 255" + } + + Hud_SetColor(colorVGUI, color[0], color[1], color[2], color[3]) + Hud_SetText( textPanel, clampedNewSetting ) + SetConVarString( c.conVar, clampedNewSetting ) + + // Color color = StringToColors( newSetting ) + // Hud_SetColor(colorVGUI, color.r, color.g, color.b, color.a) + // Hud_SetText( textPanel, newSetting ) + // SetConVarString( c.conVar, newSetting ) + } + catch ( ex ) + { + Color color = StringToColors( GetConVarString( c.conVar ) ) + Hud_SetText( textPanel, GetConVarString( c.conVar ) ) + Hud_SetColor(colorVGUI, color.r, color.g, color.b, color.a) + + printt("Failed to send textField change, because:" + ex) + ThrowInvalidValue("This setting is a color, and only accepts a four of numbers(each number should be a integer between 0 and 255) - you put something we could not parse!\n\n( Input like \"255 255 255 255\", not \"" + newSetting + "\". )") + } + break + case "alpha": + try + { + float alpha = clamp(newSetting.tofloat(), 0, 1.0) + + // if ( alpha < 0 || alpha > 1) { + // Hud_SetText( textPanel, GetConVarString( c.conVar ) ) + // throw "Alpha should be a float bewteen 0..1." + // } + Hud_SetAlpha(colorVGUI, int(alpha * 255)) + SetConVarFloat( c.conVar, alpha ) + } + catch ( ex ) + { + printt( ex ) + ThrowInvalidValue( "This setting is a alpha(float), and only accepts a number - we could not parse this!\n\n( Use \".\" for the floating point, not \",\". )" ) + } + + if ( c.sliderEnabled ) + { + var panel = Hud_GetParent( textPanel ) + MS_Slider s = file.sliders[ int ( Hud_GetScriptID( panel ) ) ] + + MS_Slider_SetValue( s, GetConVarFloat( c.conVar ) ) + } + break default: SetConVarString( c.conVar, newSetting ) break; @@ -1104,3 +1310,28 @@ string function SanitizeDisplayName( string displayName ) } return result } + +Color function StringToColors( string colorString, string delimiter = " " ) +{ + Color color + array tokens = split( colorString, " " ) + if ( tokens.len() < 3 || tokens.len() > 4) + { + throw "The length of tokens should be 3 or 4, but it is " + tokens.len() + } + + color.r = int(clamp(int(tokens[0]), 0, 255)) + color.g = int(clamp(int(tokens[1]), 0, 255)) + color.b = int(clamp(int(tokens[2]), 0, 255)) + + if ( tokens.len() == 4 ) + color.a = int(clamp(int(tokens[3]), 0, 255)) + else + color.a = 255 + + return color +} + +void function TryUpdateModSettingLists() { + UpdateList() +} \ No newline at end of file diff --git a/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_color_picker.nut b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_color_picker.nut new file mode 100644 index 000000000..8fbf93130 --- /dev/null +++ b/Northstar.Client/mod/scripts/vscripts/ui/menu_ns_color_picker.nut @@ -0,0 +1,290 @@ +untyped +global function AddColorPickerMenu +global function OpenColorPickerMenu + + + +struct { + var subTitle + + + array sliders + array labels + array textFields + array resets + + array color + + var colorPicker + var colorImage + + string conVar + string displayName +} file + +void function AddColorPickerMenu() +{ + AddSubmenu( "ColorPicker", $"resource/ui/menus/colorsliders.menu" ) + + + file.colorPicker = GetMenu( "ColorPicker" ) + file.colorImage = Hud_GetChild( file.colorPicker, "Color" ) + file.subTitle = Hud_GetChild( file.colorPicker, "DialogMessage" ) + + var frameElem = Hud_GetChild( file.colorPicker, "DialogFrame" ) + RuiSetImage( Hud_GetRui( frameElem ), "basicImage", $"rui/menu/common/dialog_gradient" ) + RuiSetFloat3( Hud_GetRui( frameElem ), "basicImageColor", < 1, 1, 1 > ) + + // AddMenuFooterOption( file.colorPicker, BUTTON_B, "#B_BUTTON_BACK", "#BACK" ) + + // RuiButton here due to close action + var screen = Hud_GetChild( file.colorPicker, "DarkenBackground" ) + Hud_AddEventHandler( screen, UIE_CLICK, void function( var _button ) + { + CloseSubmenu() + printt("Close ColorPicker By Clicking Outside The ColorPicker Menu") + } ) + RuiSetFloat( Hud_GetRui( screen ), "basicImageAlpha", 0.0 ) + + + AddMenuEventHandler( file.colorPicker, eUIEvent.MENU_OPEN, OnColorPickerOpen ) + AddMenuEventHandler( file.colorPicker, eUIEvent.MENU_CLOSE, OnColorPickerClose ) + // AddMenuEventHandler( file.colorPicker, eUIEvent.MENU_NAVIGATE_BACK, OnColorPickerClose ) + + file.labels = GetElementsByClassname( file.colorPicker, "LabelClass" ) + + file.sliders = [] + foreach (child in GetElementsByClassname( file.colorPicker, "SliderClass" )) { + + MS_Slider slider = MS_Slider_Setup( child ) + MS_Slider_SetMin( slider, 0 ) + MS_Slider_SetMax( slider, 255 ) + MS_Slider_SetStepSize( slider, 1 ) + + file.sliders.append(slider) + Hud_AddEventHandler( child, UIE_CHANGE, OnSliderChange ) + } + + + file.textFields = GetElementsByClassname( file.colorPicker, "TextEntrySettingClass" ) + foreach (value in file.textFields) { + Hud_AddEventHandler( value, UIE_LOSE_FOCUS, SendTextPanelChanges ) + } + + file.resets = GetElementsByClassname( file.colorPicker, "ResetModToDefaultClass" ) + foreach (value in file.resets) { + Hud_AddEventHandler( value, UIE_CLICK, void function (var _button) { + int index = int(Hud_GetScriptID(_button)) + ResetColor(index) + printt("Try to reset color", index) + } ) + } + +} + + +void function OnColorPickerOpen() { + string conVar = file.conVar + string displayName = file.displayName + + if (conVar == "") + { + CloseSubmenu() + return + } + + Hud_SetText(file.subTitle, displayName) + array < int > c = ColorsFromConvar(conVar) + if (c.len() >= 3) { + + for (int i = 0; i < c.len(); i++) { + MS_Slider slider = file.sliders[i] + var textPanel = file.textFields[i] + + + int val = int(clamp(c[i], 0, 255)) + MS_Slider_SetValue(slider, val.tofloat()) + Hud_SetText( textPanel, string(val) ) + } + + int alpha = int(clamp(c.len() == 4 ? c[3] : 255, 0, 255)) + Hud_SetColor(file.colorImage, c[0], c[1], c[2], alpha) + file.color = c + printt("ColorPicker Read ConVar", conVar, "With Value:", + GetConVarString(conVar), ",Parsed To:", + c[0], c[1], c[2], alpha) + + } +} + +void function OnColorPickerClose() { + printt("Trying to close Color Picker") + + ColorsToConvar() + + file.color = [] + file.conVar = "" + file.displayName = "" + + Hud_SetText(file.subTitle, "") + TryUpdateModSettingLists() +} + +void function SendTextPanelChanges( var textPanel ) +{ + int newSetting = int(Hud_GetUTF8Text( textPanel )) + int index = int(Hud_GetScriptID(textPanel)) + try + { + newSetting = int(clamp(newSetting, 0, 255)) + + MS_Slider slider = file.sliders[index] + MS_Slider_SetValue(slider, newSetting.tofloat()) + + UpdateColor() + } + catch ( ex ) + { + // ThrowInvalidValue( "This part of color is an integer, and only accepts whole numbers(0..1..255)." ) + ResetColor(index) + + } +} + +void function OnSliderChange( var button ) +{ + int index = int(Hud_GetScriptID(button)) + int val = int(Hud_SliderControl_GetCurrentValue( button )) + + var textPanel = file.textFields[index] + Hud_SetText( textPanel, string( val ) ) + UpdateColor() +} + +// write to convar +void function UpdateColor() +{ + string conVar = file.conVar + + try { + if (conVar == "") { + throw "Oops We dont have ConVar for color" + } + ColorsToConvar(conVar) + + array < int > c = ColorsFromConvar(conVar) + int alpha = c.len() == 4 ? c[3] : 255 + + Hud_SetColor(file.colorImage, c[0], c[1], c[2], alpha) + } + catch ( ex ) + { + printt("Failed to UpdateColor", ex) + // ThrowInvalidValue("This setting is a color, and only accepts a trio of numbers - you put something we could not parse!\n\n( Use \".\" for the int like \"255 255 255\", not \",\". )") + } +} +void function ResetColors() { + for (int i = 0; i < 4; i++) { + ResetColor(i) + } +} + +void function ResetColor(int index) +{ + array < int > c = file.color + if (c.len() >= 3) { + var textPanel = file.textFields[index] + MS_Slider slider = file.sliders[index] + + Hud_SetText( textPanel, string(c[index]) ) + MS_Slider_SetValue(slider, c[index].tofloat()) + + int alpha = c.len() == 4 ? c[3] : 255 + Hud_SetColor(file.colorImage, c[0], c[1], c[2], alpha) + + UpdateColor() + + } +} + + + + +array function ColorsFromConvar(string conVar = "") +{ + array c + try { + if (conVar == "") { + throw "Oops. We dont have ConVar for color here" + } + array tokens = split( GetConVarString(conVar), " " ) + + // Assert(tokens.len() == 3) + if (tokens.len() < 3) { + throw "Convar " + conVar + ": " + GetConVarString(conVar) + "is not a trio/four of numbers" + // printt("Failed to ColorsFromConvar. With Convar", conVar, ":",GetConVarString(conVar)) + + } + + for (int i = 0; i < tokens.len(); i++) { + c.append(int(clamp(tokens[i].tointeger(), 0, 255))) + } + + if (tokens.len() == 3) { + c.append(255) + } + + } + catch ( ex ) + { + printt("Failed to ColorsFromConvar. With Convar", conVar, ":",GetConVarString(conVar) , ex) + // ThrowInvalidValue("This setting is a color, and only accepts a trio of numbers - you put something we could not parse!\n\n( Use \".\" for the int like \"255 255 255\", not \",\". )") + } + + return c +} + +void function ColorsToConvar(string conVar = "") +{ + try { + if (conVar == "") { + throw "Oops. We dont have ConVar for color here" + } + string str = "" + for (int i = 0; i < 4; i++) { + str += "" + int(Hud_GetUTF8Text( file.textFields[i] )) + if (i != 3) { + str += " " + } + } + + SetConVarString(conVar, str) + // printt("ColorPicker write ConVar", conVar , "With " + str) + + } + catch ( ex ) + { + printt("Failed to ColorsToConvar. With Convar", conVar, ":",GetConVarString(conVar) , ex) + // ThrowInvalidValue("This setting is a color, and only accepts a four of numbers - you put something we could not parse!\n\n( Use \".\" for the int like \"255 255 255\", not \",\". )") + } +} + + +void function ThrowInvalidValue( string desc ) +{ + DialogData dialogData + dialogData.header = "Invalid Value" + dialogData.image = $"ui/menu/common/dialog_error" + dialogData.message = desc + AddDialogButton( dialogData, "#OK" ) + OpenDialog( dialogData ) +} + +void +function OpenColorPickerMenu(string conVar, string displayName) +{ + file.conVar = conVar + file.displayName = displayName + + OpenSubmenu(GetMenu("ColorPicker"), false) +} \ No newline at end of file