summaryrefslogtreecommitdiff
path: root/textures/base/pack/fast_btn.png
blob: 08cb189ea0e6e31756e6ef7f111e17b71593a307 (plain)
ofshex dumpascii
0000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 40 00 00 00 40 08 06 00 00 00 aa 69 71 .PNG........IHDR...@...@......iq
0020 de 00 00 03 32 49 44 41 54 78 da ed 98 51 88 95 55 10 80 bf d9 ee 6e 6a 4b 45 14 d5 16 95 56 85 ....2IDATx...Q..U.....njKE....V.
0040 04 11 bd 98 0a 16 04 18 28 05 91 40 4f 11 da 4b 10 25 15 90 18 50 40 48 f4 b4 0a 55 18 51 4f 26 ........(..@O..K.%...P@H...U.QO&
0060 d0 4b 89 44 49 11 09 11 59 09 24 0b 06 1b b0 91 22 c4 d6 b6 59 6b ee d7 cb 59 f8 f9 f9 f7 ef de .K.DI...Y.$....."...Yk...Y......
0080 7f 6f 75 ef de f3 c1 be cc 3f 33 7b e6 cc 9c b9 67 0e 64 32 99 4c 26 93 c9 64 32 99 4c 26 93 c9 .ou......?3{....g.d2.L&..d2.L&..
00a0 f4 30 ea a3 ea 57 ea 69 f5 53 75 d3 52 7d c6 bf b8 d8 21 60 3d b0 b2 81 f9 99 88 38 5e f2 f7 1c .0...W.i.Su.R}....!`=......8^...
00c0 f0 52 49 6f 1e d8 1c 11 1f f7 62 b6 36 da 9c 73 ea aa 82 af 51 f5 cf 45 74 4f f4 64 05 00 a8 d7 .RIo......b.6..s....Q..EtO.d....
00e0 01 ad 06 a6 b3 11 71 ba e0 67 1d f0 45 8d fe aa 88 38 bb 9c cf fe b5 35 d5 32 ad 36 4e 64 ab 87 ......q..g..E....8.....5.2.6Nd..
0100 82 bc 13 d8 00 5c 0d fc 0e 4c 02 9f 45 c4 54 44 4c a9 1f 02 9b 2b 4c c7 23 c2 e4 e3 42 60 3b 30 .....\...L..E.TDL....+L.#...B`;0
0120 02 bc 19 11 33 fd 90 dd ad ea 44 4d 86 bf 54 b7 a8 63 ea 91 82 7c 5e 7d 23 05 8d da 52 0f 15 be ....3.....DM..T..c...|^}#...R...
0140 7f d4 eb 81 8f a8 fb 3b 68 8c 9f ab eb d5 0d ea 36 75 6d c9 d7 db 25 fd ef bb da 04 d5 5d c0 1d .......;h.......6um...%......]..
0160 0d 62 3d 0f bc 1c 11 df 14 7c 0d 03 ef 2f 52 d2 b5 cb 00 0e 01 07 81 63 c0 5f c0 bd c0 93 c0 ad .b=......|.../R........c._......
0180 25 bd 87 23 e2 dd 6e f6 80 d1 86 c9 be 00 58 51 92 ed ad 08 fe 13 60 1c 98 00 ae 00 f6 a4 9e 50 %..#..n.......XQ......`........P
01a0 4e d8 d6 f4 57 c7 ee 76 82 ff bf 4a 7f 75 3a bf 45 9e 2a e9 8c a9 b3 0d ee 0f 73 ea 33 bd 7e f6 N...W..v...J.u:.E.*.......s.3.~.
01c0 2f 4d 57 d9 05 9e af d0 79 b5 41 f0 87 d5 db 7b ea 22 54 b3 09 37 00 0f 01 13 11 f1 41 e9 db 4d /MW.....y.A....{."T..7......A..M
01e0 c0 09 60 b8 c2 74 3a d9 dd 08 5c 93 64 27 81 a3 11 31 b9 5c 2e 3d 07 6b b2 bc 73 b9 4f 7b eb 2a ..`..t:...\.d'...1.\.=.k..s.O{.*
0200 fa c3 02 27 d5 91 6e ff cf d6 12 17 7c 71 ea f2 9d f2 5b 44 9c ab 90 bf 58 73 2c 77 47 c4 5c 2f ...'..n.....|q....[D....Xs,wG.\/
0220 65 eb 91 25 4c 7b 13 15 fe 36 d5 e8 1f 4b e3 35 bd 54 01 ef 01 3f 36 b4 3d 55 0a 7e 05 b0 af 46 e..%L{...6...K.5.T...?6.=U.~...F
0240 ff d9 88 98 5f ae e7 3e d4 b7 6a b2 ff 9d da ea e7 00 87 52 79 df 5c f1 ed 72 f5 40 1b 47 e6 5b ...._..>..j........Ry.\..r.@.G.[
0260 f5 ae 7e dd 80 c3 85 40 8e a8 3b d5 c7 d5 7d ea 2f 1d f4 8d f3 ea 2b 69 8e e8 9b e0 d7 74 d8 1c ..~....@..;...}./.....+i.....t..
0280 67 d5 7b d4 07 d5 a3 35 53 e1 58 bf 6c c0 88 3a d9 66 f0 93 e9 e9 ab 68 ff 40 fa fd af fa 55 58 g.{....5S.X.l..:.f.....h.@....UX
02a0 d9 2f 9b 70 a5 ba 57 3d bb 48 e0 53 ea 2e 75 74 11 fb 8b d4 d7 2a ec f6 74 63 7d d1 66 10 f7 03 ./.p..W=.H.S..ut.....*..tc}.f...
02c0 5b 3a f4 3d 03 bc b0 f0 2c a5 5e 02 6c 04 6e 03 86 80 33 c0 d7 c0 f1 88 10 e0 1f d6 b0 0d 38 90 [:.=....,.^.l.n...3...........8.
02e0 6c 01 fe 00 d6 46 c4 0f ff c5 06 3c 0d dc d7 a1 ef 39 60 47 44 fc d4 c5 6a 1a 07 9e 28 88 f6 47 l....F.....<.....9`GD...j...(..G
0300 c4 63 0c 0a 69 94 fe b9 34 ff 5f bf 14 9f 43 fd b4 01 11 31 0d bc 5e 10 0d a7 e7 30 06 a9 0a ae .c..i...4._...C....1..^....0....
0320 2a 35 d4 19 f5 b2 81 a8 80 54 05 a7 80 77 0a a2 51 e0 ee 41 ab 82 35 ea af 85 cb d3 6a 06 0d f5 *5.......T...w..Q..A..5.....j...
0340 16 75 7b 7a 5e cb 64 32 99 4c 26 93 c9 64 32 99 4c 26 93 69 9b bf 01 5c 03 d9 e1 c4 d2 1a 67 00 .u{z^.d2.L&..d2.L&.i...\......g.
0360 00 00 00 49 45 4e 44 ae 42 60 82 ...IEND.B`.
'#n194'>194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
--Minetest
--Copyright (C) 2018 rubenwardy
--
--This program is free software; you can redistribute it and/or modify
--it under the terms of the GNU Lesser General Public License as published by
--the Free Software Foundation; either version 2.1 of the License, or
--(at your option) any later version.
--
--This program is distributed in the hope that it will be useful,
--but WITHOUT ANY WARRANTY; without even the implied warranty of
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
--GNU Lesser General Public License for more details.
--
--You should have received a copy of the GNU Lesser General Public License along
--with this program; if not, write to the Free Software Foundation, Inc.,
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

local store = {}
local package_dialog = {}

-- Screenshot
local screenshot_dir = os.tempfolder()
assert(core.create_dir(screenshot_dir))
local screenshot_downloading = {}
local screenshot_downloaded = {}

-- Filter
local search_string = ""
local cur_page = 1
local num_per_page = 5
local filter_type = 1
local filter_types_titles = {
	fgettext("All packages"),
	fgettext("Games"),
	fgettext("Mods"),
	fgettext("Texture packs"),
}

local filter_types_type = {
	nil,
	"game",
	"mod",
	"txp",
}




local function download_package(param)
	if core.download_file(param.package.url, param.filename) then
		return {
			package = param.package,
			filename = param.filename,
			successful = true,
		}
	else
		core.log("error", "downloading " .. dump(param.package.url) .. " failed")
		return {
			package = param.package,
			successful = false,
		}
	end
end

local function start_install(calling_dialog, package)
	local params = {
		package = package,
		filename = os.tempfolder() .. "_MODNAME_" .. package.name .. ".zip",
	}

	local function callback(result)
		if result.successful then
			local path, msg = pkgmgr.install(result.package.type,
					result.filename, result.package.name,
					result.package.path)
			if not path then
				gamedata.errormessage = msg
			else
				local conf_path
				local name_is_title = false
				if result.package.type == "mod" then
					conf_path = path .. DIR_DELIM .. "mod.conf"
				elseif result.package.type == "game" then
					conf_path = path .. DIR_DELIM .. "game.conf"
					name_is_title = true
				elseif result.package.type == "txp" then
					conf_path = path .. DIR_DELIM .. "texture_pack.conf"
				end

				if conf_path then
					local conf = Settings(conf_path)
					local function set_def(key, value)
						if conf:get(key) == nil then
							conf:set(key, value)
						end
					end
					if name_is_title then
						set_def("name",    result.package.title)
					else
						set_def("title",   result.package.title)
						set_def("name",    result.package.name)
					end
					set_def("description", result.package.short_description)
					set_def("author",      result.package.author)
					conf:set("release",    result.package.release)
					conf:write()
				end
			end
			os.remove(result.filename)
		else
			gamedata.errormessage = fgettext("Failed to download $1", package.name)
		end

		if gamedata.errormessage == nil then
			core.button_handler({btn_hidden_close_download=result})
		else
			core.button_handler({btn_hidden_close_download={successful=false}})
		end
	end

	if not core.handle_async(download_package, params, callback) then
		core.log("error", "ERROR: async event failed")
		gamedata.errormessage = fgettext("Failed to download $1", package.name)
	end

	local new_dlg = dialog_create("store_downloading",
		function(data)
			return "size[7,2]label[0.25,0.75;" ..
				fgettext("Downloading and installing $1, please wait...", data.title) .. "]"
		end,
		function(this,fields)
			if fields["btn_hidden_close_download"] ~= nil then
				this:delete()
				return true
			end

			return false
		end,
		nil)

	new_dlg:set_parent(calling_dialog)
	new_dlg.data.title = package.title
	calling_dialog:hide()
	new_dlg:show()
end

local function get_screenshot(package)
	if not package.thumbnail then
		return defaulttexturedir .. "no_screenshot.png"
	elseif screenshot_downloading[package.thumbnail] then
		return defaulttexturedir .. "loading_screenshot.png"
	end

	-- Get tmp screenshot path
	local filepath = screenshot_dir .. DIR_DELIM ..
		package.type .. "-" .. package.author .. "-" .. package.name .. ".png"

	-- Return if already downloaded
	local file = io.open(filepath, "r")
	if file then
		file:close()
		return filepath
	end

	-- Show error if we've failed to download before
	if screenshot_downloaded[package.thumbnail] then
		return defaulttexturedir .. "error_screenshot.png"
	end

	-- Download

	local function download_screenshot(params)
		return core.download_file(params.url, params.dest)
	end
	local function callback(success)
		screenshot_downloading[package.thumbnail] = nil
		screenshot_downloaded[package.thumbnail] = true
		if not success then
			core.log("warning", "Screenshot download failed for some reason")
		end

		local ele = ui.childlist.store
		if ele and not ele.hidden then
			core.update_formspec(ele:formspec())
		else
			ele = ui.childlist.package_view
			if ele and not ele.hidden then
				core.update_formspec(ele:formspec())
			end
		end
	end
	if core.handle_async(download_screenshot,
			{ dest = filepath, url = package.thumbnail }, callback) then
		screenshot_downloading[package.thumbnail] = true
	else
		core.log("error", "ERROR: async event failed")
		return defaulttexturedir .. "error_screenshot.png"
	end

	return defaulttexturedir .. "loading_screenshot.png"
end



function package_dialog.get_formspec()
	local package = package_dialog.package

	store.update_paths()

	local formspec = {
		"size[9,4;true]",
		"image[0,1;4.5,3;", get_screenshot(package), ']',
		"label[3.8,1;",
		minetest.colorize(mt_color_green, core.formspec_escape(package.title)), "\n",
		minetest.colorize('#BFBFBF', "by " .. core.formspec_escape(package.author)), "]",
		"textarea[4,2;5.3,2;;;", core.formspec_escape(package.short_description), "]",
		"button[0,0;2,1;back;", fgettext("Back"), "]",
	}

	if not package.path then
		formspec[#formspec + 1] = "button[7,0;2,1;install;"
		formspec[#formspec + 1] = fgettext("Install")
		formspec[#formspec + 1] = "]"
	elseif package.installed_release < package.release then
		formspec[#formspec + 1] = "button[7,0;2,1;install;"
		formspec[#formspec + 1] = fgettext("Update")
		formspec[#formspec + 1] = "]"
		formspec[#formspec + 1] = "button[5,0;2,1;uninstall;"
		formspec[#formspec + 1] = fgettext("Uninstall")
		formspec[#formspec + 1] = "]"
	else
		formspec[#formspec + 1] = "button[7,0;2,1;uninstall;"
		formspec[#formspec + 1] = fgettext("Uninstall")
		formspec[#formspec + 1] = "]"
	end

	return table.concat(formspec, "")
end

function package_dialog.handle_submit(this, fields, tabname, tabdata)
	if fields.back then
		this:delete()
		return true
	end

	if fields.install then
		start_install(this, package_dialog.package)
		return true
	end

	if fields.uninstall then
		local dlg_delmod = create_delete_content_dlg(package_dialog.package)
		dlg_delmod:set_parent(this)
		this:hide()
		dlg_delmod:show()
		return true
	end

	return false
end

function package_dialog.create(package)
	package_dialog.package = package
	return dialog_create("package_view",
		package_dialog.get_formspec,
		package_dialog.handle_submit,
		nil)
end

function store.load()
	store.packages_full = core.get_package_list()
	store.packages = store.packages_full
	store.loaded = true
end

function store.update_paths()
	local mod_hash = {}
	pkgmgr.refresh_globals()
	for _, mod in pairs(pkgmgr.global_mods:get_list()) do
		mod_hash[mod.name] = mod
	end

	local game_hash = {}
	pkgmgr.update_gamelist()
	for _, game in pairs(pkgmgr.games) do
		game_hash[game.id] = game
	end

	local txp_hash = {}
	for _, txp in pairs(pkgmgr.get_texture_packs()) do
		txp_hash[txp.name] = txp
	end

	for _, package in pairs(store.packages_full) do
		local content
		if package.type == "mod" then
			content = mod_hash[package.name]
		elseif package.type == "game" then
			content = game_hash[package.name]
		elseif package.type == "txp" then
			content = txp_hash[package.name]
		end

		if content and content.author == package.author then
			package.path = content.path
			package.installed_release = content.release
		else
			package.path = nil
		end
	end
end

function store.filter_packages(query)
	if query == "" and filter_type == 1 then
		store.packages = store.packages_full
		return
	end

	local keywords = {}
	for word in query:lower():gmatch("%S+") do
		table.insert(keywords, word)
	end

	local function matches_keywords(package, keywords)
		for k = 1, #keywords do
			local keyword = keywords[k]

			if string.find(package.name:lower(), keyword, 1, true) or
					string.find(package.title:lower(), keyword, 1, true) or
					string.find(package.author:lower(), keyword, 1, true) or
					string.find(package.short_description:lower(), keyword, 1, true) then
				return true
			end
		end

		return false
	end

	store.packages = {}
	for _, package in pairs(store.packages_full) do
		if (query == "" or matches_keywords(package, keywords)) and
				(filter_type == 1 or package.type == filter_types_type[filter_type]) then
			store.packages[#store.packages + 1] = package
		end
	end

end

function store.get_formspec()
	assert(store.loaded)

	store.update_paths()

	local pages = math.ceil(#store.packages / num_per_page)
	if cur_page > pages then
		cur_page = 1
	end

	local formspec
	if #store.packages > 0 then
		formspec = {
			"size[12,7;true]",
			"position[0.5,0.55]",
			"field[0.2,0.1;7.8,1;search_string;;",
			core.formspec_escape(search_string), "]",
			"field_close_on_enter[search_string;false]",
			"button[7.7,-0.2;2,1;search;",
			fgettext("Search"), "]",
			"dropdown[9.7,-0.1;2.4;type;",
			table.concat(filter_types_titles, ","),
			";", filter_type, "]",
			-- "textlist[0,1;2.4,5.6;a;",
			-- table.concat(taglist, ","), "]",

			-- Page nav buttons
			"container[0,",
			num_per_page + 1.5, "]",
			"button[-0.1,0;3,1;back;",
			fgettext("Back to Main Menu"), "]",
			"button[7.1,0;1,1;pstart;<<]",
			"button[8.1,0;1,1;pback;<]",
			"label[9.2,0.2;",
			tonumber(cur_page), " / ",
			tonumber(pages), "]",
			"button[10.1,0;1,1;pnext;>]",
			"button[11.1,0;1,1;pend;>>]",
			"container_end[]",
		}
	else
		formspec = {
			"size[12,7;true]",
			"position[0.5,0.55]",
			"label[4,3;No packages could be retrieved]",
			"button[-0.1,",
			num_per_page + 1.5,
			";3,1;back;",
			fgettext("Back to Main Menu"), "]",
		}
	end

	local start_idx = (cur_page - 1) * num_per_page + 1
	for i=start_idx, math.min(#store.packages, start_idx+num_per_page-1) do
		local package = store.packages[i]
		formspec[#formspec + 1] = "container[0.5,"
		formspec[#formspec + 1] = (i - start_idx) * 1.1 + 1
		formspec[#formspec + 1] = "]"

		-- image
		formspec[#formspec + 1] = "image[-0.4,0;1.5,1;"
		formspec[#formspec + 1] = core.formspec_escape(get_screenshot(package))
		formspec[#formspec + 1] = "]"

		-- title
		formspec[#formspec + 1] = "label[1,-0.1;"
		formspec[#formspec + 1] = core.formspec_escape(
				minetest.colorize(mt_color_green, package.title) ..
				minetest.colorize("#BFBFBF", " by " .. package.author))
		formspec[#formspec + 1] = "]"

		-- description
		formspec[#formspec + 1] = "textarea[1.25,0.3;7.5,1;;;"
		formspec[#formspec + 1] = core.formspec_escape(package.short_description)
		formspec[#formspec + 1] = "]"

		-- buttons
		if not package.path then
			formspec[#formspec + 1] = "button[8.4,0;1.5,1;install_"
			formspec[#formspec + 1] = tostring(i)
			formspec[#formspec + 1] = ";"
			formspec[#formspec + 1] = fgettext("Install")
			formspec[#formspec + 1] = "]"