Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modal window helper #4223

Merged
merged 4 commits into from
Jan 23, 2023
Merged

Modal window helper #4223

merged 4 commits into from
Jan 23, 2023

Conversation

MillhioreBT
Copy link
Contributor

Pull Request Prelude

  • I have followed [proper The Forgotten Server code styling][code].
  • I have read and understood the [contribution guidelines][cont] before making this PR.
  • I am aware that this PR may be closed if the above-mentioned criteria are not fulfilled.

Changes Proposed

This file adds the possibility to create windows in a more beautiful way. I have taken ideas from the guy who published this file in OTLand, I have only modified it to add all the methods and a way to be able to use, reuse and modify them.

The order of execution of the calls is: choice > button > default
If a choice has a callback it will be activated when you press any button, however the button function will not be activated even if it has one. if another choice does not have a callback, the button callback is called, finally the default callback will be called if there is no callback associated with the button or the choice.

Examples:

normal.lua
local talkAction = TalkAction("!modal")

function talkAction.onSay(player, words, param)
	local menu = ModalWindow{
		title = "Menu",
		message = "Test Menu"
	}

	for index = 1, 4 do
		menu:addChoice(string.format("Choice %d", index))
	end

	menu:addButton("Close", function (player, button, choice)
		player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have clicked the Close button.")
	end)

	menu:addButton("Select", function (player, button, choice)
		player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You selected choice " .. choice.text)
	end)

	menu:sendToPlayer(player)
	return false
end

talkAction:separator(" ")
talkAction:register()
choice.lua

Access to the local variables of the loop iteration where it was created.

local config = {
	{ name="Promo1", itemId = 2160, count = 1, price = 1000 },
	{ name="Promo2", itemId = 2160, count = 5, price = 15000 },
	{ name="Promo3", itemId = 2160, count = 10, price = 260000 }
}

local talkAction = TalkAction("!modal")

function talkAction.onSay(player, words, param)
	local menu = ModalWindow{
		title = "Menu",
		message = "Test Menu"
	}

	for i, info in pairs(config) do
		menu:addChoice(string.format("%s", info.name), function (player, button, choice)
			if button.name ~= "Select" then
				return
			end

			player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have selected " .. info.name)
		end)
	end

	menu:addButton("Close")
	menu:addButton("Select")
	menu:sendToPlayer(player)
	return false
end

talkAction:separator(" ")
talkAction:register()
item_menu_back_menu.lua
local config = {
	{ name="Promo1", itemId = 2160, count = 1, price = 1000 },
	{ name="Promo2", itemId = 2160, count = 5, price = 15000 },
	{ name="Promo3", itemId = 2160, count = 10, price = 260000 }
}

local talkAction = TalkAction("!modal")

function talkAction.onSay(player, words, param)
	local menu = ModalWindow{
		title = "Menu",
		message = "Test Menu"
	}

	local secondMenu = ModalWindow{
		title = "Second Menu",
		message = "Test Second Menu"
	}

	for i, info in pairs(config) do
		menu:addChoice(string.format("%s", info.name), function (player, button, choice)
			if button.name ~= "Select" then
				return
			end

			local itemType = ItemType(info.itemId)
			secondMenu:clear()
			secondMenu:addChoice(string.format("Name: %s", itemType:getName()))
			secondMenu:addChoice(string.format("Weight: %s", itemType:getWeight()))
			secondMenu:addChoice(string.format("Price: %s", info.price))

			secondMenu:addButton("Close")
			secondMenu:addButton("Back", function (player, button, choice)
				menu:setMessage("Test Menu from Back Test Second Menu")
				menu:sendToPlayer(player)
			end)

			secondMenu:sendToPlayer(player)
		end)
	end

	menu:addButton("Close")
	menu:addButton("Select")

	menu:sendToPlayer(player)
	return false
end

talkAction:separator(" ")
talkAction:register()
Using callChoice or callButton and clear, to reuse the callbacks, this way we can navigate in a loop going forwards or backwards easily with access to all local variables of its state in the loop. call_choice_andclear.lua
local config = {
	{ name="Promo1", itemId = 2160, count = 1, price = 1000 },
	{ name="Promo2", itemId = 2160, count = 5, price = 15000 },
	{ name="Promo3", itemId = 2160, count = 10, price = 260000 }
}

local talkAction = TalkAction("!modal")

function talkAction.onSay(player, words, param)
	local menu = ModalWindow{
		title = "Menu",
		message = "Test Menu"
	}

	local secondMenu = ModalWindow{
		title = "Second Menu",
		message = "Test Second Menu"
	}

	for i, info in pairs(config) do
		menu:addChoice(string.format("%s", info.name), function (player, button, choice)
			if button.name ~= "Select" then
				return
			end

			local itemType = ItemType(info.itemId)
			secondMenu:clear()
			secondMenu:addChoice(string.format("Name: %s", itemType:getName()))
			secondMenu:addChoice(string.format("Weight: %s", itemType:getWeight()))
			secondMenu:addChoice(string.format("Price: %s", info.price))

			secondMenu:addButton("Close")
			secondMenu:addButton("Back", function (player, button, choice)
				secondMenu:setMessage("Test Menu from Back Test Second Menu")
				menu:sendToPlayer(player)
			end)


			if i > 1 then
				secondMenu:addButton("Prev", function (player, button, choice)
					secondMenu:setMessage("Test Second Menu from Previous Test Menu")
					button.name = "Select"
					menu:callChoice(string.format("%s", config[i - 1].name), player, button, choice)
				end)
			end

			if i < #config then
				secondMenu:addButton("Next", function (player, button, choice)
					secondMenu:setMessage("Test Second Menu from Next Test Menu")
					button.name = "Select"
					menu:callChoice(string.format("%s", config[i + 1].name), player, button, choice)
				end)
			end

			secondMenu:sendToPlayer(player)
		end)
	end

	menu:addButton("Close")
	menu:addButton("Select")

	menu:sendToPlayer(player)
	return false
end

talkAction:separator(" ")
talkAction:register()

These are a couple of ways to create some simple and even pretty windows, without a lot of code and reusing all the locale, use your imagination,

If you have any suggestion let me know. maybe it could be improved a little more?

Issues addressed: Nothing!

@EPuncker EPuncker added the enhancement Increase or improvement in quality, value, or extent label Oct 6, 2022
@MillhioreBT MillhioreBT requested review from ranisalt and removed request for yamaken93, DSpeichert, EvilHero90 and nekiro October 20, 2022 23:23
ranisalt
ranisalt previously approved these changes Oct 21, 2022
Copy link
Member

@ranisalt ranisalt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but I would like to see an example before it gets merged.

@omarcopires
Copy link
Contributor

I've been using it on my test server (Styller Yurots) for some time as a basis for other modal systems and no problems have occurred to me so far.
One suggestion would be to move the functions file to libs instead of creaturescript.

Thank you so much for bringing this to TFS.

@EPuncker EPuncker merged commit 96bb8fa into otland:master Jan 23, 2023
@ranisalt
Copy link
Member

Bravo!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Increase or improvement in quality, value, or extent
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants