require "base/internal/ui/reflexcore" -- we need to require this file, because there is some basic functionality -- like shouldShowHUD(), Color() and NVG_* constants --Materials Level local contentlistMaterialsLevel = { "internal/editor/textures/editor_clip", "internal/editor/textures/editor_fullclip", "internal/editor/textures/editor_jumppad", "internal/editor/textures/editor_meta", "internal/editor/textures/editor_teleport", "internal/effects/race/race_checkpoint", "internal/effects/race/race_finish", "internal/effects/race/race_start", "internal/editor/textures/editor_nolight" } --Materials with grids local contentlistMaterialsWithGrids = { "dev_aqua", "dev_aquadark", "dev_black", "dev_blue", "dev_bluedark", "dev_bluelight", "dev_green", "dev_greendark", "dev_greenlight", "dev_grey128", "dev_grey192", "dev_grey64", "dev_lime", "dev_magenta", "dev_magentadark", "dev_orange", "dev_orangedark", "dev_pink", "dev_pinkdark", "dev_purple", "dev_purpledark", "dev_red", "dev_reddark", "dev_white", "dev_yellow", "dev_yellowdark" } --Materials without grids local contentlistMaterialsWithoutGrids = { "dev_nogrid_aqua", "dev_nogrid_aquadark", "dev_nogrid_black", "dev_nogrid_bluedark", "dev_nogrid_bluelight", "dev_nogrid_green", "dev_nogrid_greendark", "dev_nogrid_greenlight", "dev_nogrid_grey128", "dev_nogrid_grey192", "dev_nogrid_grey64", "dev_nogrid_lime", "dev_nogrid_limedark", "dev_nogrid_magenta", "dev_nogrid_magentadark", "dev_nogrid_orange", "dev_nogrid_orangedark", "dev_nogrid_pink", "dev_nogrid_pinkdark", "dev_nogrid_purple", "dev_nogrid_purpledark", "dev_nogrid_red", "dev_nogrid_reddark", "dev_nogrid_white", "dev_nogrid_yellow", "dev_nogrid_yellowdark" } --Materials trims local contentlistMaterialsTrims = { "dev_bluelight_trim", "dev_blue_trim", "dev_greenlight_trim", "dev_green_trim", "dev_grey192_trim", "dev_orange_trim", "dev_purple_trim", "dev_red_trim", "dev_yellow_trim" } --Materials liquids local contentlistMaterialsLiquids = { "lava/lava", "slime/slime", "water/water" } --Materials light local contentlistMaterialsLight = { "dev_light_blue", "dev_light_green", "dev_light_magenta", "dev_light_orange", "dev_light_pink", "dev_light_purple", "dev_light_red", "dev_light_white", "dev_light_yellow" } --Materials Industrial local contentlistMaterialsIndustrial = { "brick/brick_small", "brick/cinderblock_01", "brick/cinderblock_01_painted_black", "brick/cinderblock_01_painted_blue", "brick/cinderblock_01_painted_green", "brick/cinderblock_01_painted_grey", "brick/cinderblock_01_painted_orange", "brick/cinderblock_01_painted_red", "brick/cinderblock_01_painted_teal", "brick/cinderblock_01_painted_white", "brick/cinderblock_01_painted_yellow", "concrete/concrete_01", "concrete/concrete_02", "concrete/concrete_bunker_01", "concrete/concrete_bunker_02", "concrete/concrete_polished", "fence/chainlink", "metal/corrugated_plated_01", "metal/corrugated_sheet_iron", "tiles/tiles", "trims/metal_01", "trims/metal_02", "wood/planks" } local function checkDefaults(defaults, target) for k, v in pairs(defaults) do if(type(v) == 'table') then checkDefaults(v, target); CheckSetDefaultValue(target, k, type(v), v); end end end MaterialsWidget ={ userData = {}; defaultData = { offset = { x = 20.000000, y = 40.000000 }; anchor = { x = -1, y = -1 }; }; lists = { [1] = { position = 1; list = contentlistMaterialsWithGrids; label = "Grid"; value = "dev_aqua"; data = {}; basePath = "structural/dev/"; }; [2] = { position = 2; list = contentlistMaterialsWithoutGrids; label = "NoGrid"; value = "dev_nogrid_aqua"; data = {}; basePath = "structural/dev/"; }; [3] = { position = 3; list = contentlistMaterialsTrims; label = "Trim"; value = "dev_bluelight_trim"; data = {}; basePath = "structural/dev/"; }; [4] = { position = 4; list = contentlistMaterialsLiquids; label = "Liquid"; value = "lava/lava" ; data = {}; basePath = "environment/liquids/"; }; [5] = { position = 5; list = contentlistMaterialsLight; label = "Light"; value = "dev_light_blue"; data = {}; basePath = "structural/dev/"; }; [6] = { position = 6; list = contentlistMaterialsIndustrial; label = "Industrial"; value = "brick/brick_small"; data = {}; basePath = "structural/industrial/materials/"; }; [7] = { position = 7; list = contentlistMaterialsLevel; label = "Level"; value = "internal/editor/textures/editor_nolight"; data = {}; basePath = ""; }; }; }; registerWidget("MaterialsWidget"); function MaterialsWidget:initialize() local user = loadUserData(); if user == nil or not user.init then consolePerformCommand("ui_set_widget_anchor MaterialsWidget -1 -1") consolePerformCommand("ui_set_widget_offset MaterialsWidget 20 40") self.userData.init = true; saveUserData(self.userData); end; end function MaterialsWidget:draw() table.sort(self.lists, function(a,b) return a.position > b.position end); if shouldShowHUD() then return end; if getPlayer().state ~= PLAYER_STATE_EDITOR then return end; local comboWidth = 340 local rowHeight = 60; local rows = 0; local textWidth = 0; for k,v in pairs(self.lists) do rows = rows + 1; nvgFontSize(35); local lWidth = nvgTextWidth(v.label); textWidth = textWidth < lWidth and lWidth or textWidth; -- get the largest width based on labels. end; local x = self.userData.x or 0; local y = self.userData.y or 0; local fWidth = 600; local fHeight = self.minimize and 50 or (50 + rows * rowHeight); nvgBeginPath(); nvgRect(x,y,fWidth, fHeight); nvgStrokeColor(Color(20,20,20,128)); nvgStrokeWidth(3); nvgStroke(); nvgBeginPath(); nvgRect(x,y,fWidth, fHeight); nvgFillColor(Color(20,20,20,128)); nvgFill(); nvgFontSize(45); nvgFillColor(Color(255,255,255)); nvgTextAlign(NVG_ALIGN_LEFT, NVG_ALIGN_TOP); nvgText(x +120, y +5, "Materials"); -- drawing rows. if not minimized. if not self.minimize then nvgFontSize(35); nvgTextAlign(NVG_ALIGN_RIGHT, NVG_ALIGN_TOP); local function drawRow(x, y, data, optionalId) nvgText(x, y, data.label); local selection = uiComboBox(data.list, data.value, x + 15, y, comboWidth, data.data, y, optionalId); if selection ~= nil then data.value = selection; end; if uiButton("Set", nil, x + comboWidth + 25, y, 100, 35, UI_COLOR_RED, y, optionalId) then consolePerformCommand("me_activematerial " .. data.basePath .. selection); end end local contentHeight = (rows) * rowHeight; y = y + contentHeight; for k,v in ipairs(self.lists) do drawRow(x + textWidth + 5 , y, v, k); y = y - rowHeight; end end; -- control window position from title bar. local titlebar_m = mouseRegion(x, y, fWidth - 30, 50, optionalId); if(titlebar_m.leftDown) then self.grab = { x = titlebar_m.mousex; y = titlebar_m.mousey}; self.offset = {x = x; y = y}; end; if(titlebar_m.leftHeld and titlebar_m.mouseInside) then self.userData.x = self.offset.x + (titlebar_m.mousex - self.grab.x); self.userData.y = self.offset.y + (titlebar_m.mousey - self.grab.y); end -- minimize button. if not self.minimize then self.minimize = uiButton("_", nil, x + comboWidth + 230, y, 30, 30, Color(20,20,20,128), optionalId, enabled); else local restore = uiButton("[]", nil, x + comboWidth + 230, y, 30, 30, Color(20,20,20,128), optionalId, enabled); if restore then self.minimize = false; end; end; end