273 lines
7.7 KiB
Lua
273 lines
7.7 KiB
Lua
local S = calendar._get_translator("calendar")
|
|
local F = minetest.formspec_escape
|
|
|
|
local COLOR_HOLIDAY = "#00FF00"
|
|
local COLOR_DAYBOX_HOLIDAY = "#00940FFF"
|
|
local COLOR_DAYBOX = "#1A1A1AFF"
|
|
local COLOR_DAYBOX_TODAY = "#FFF508FF"
|
|
local COLOR_TOOLTIP_TODAY = COLOR_DAYBOX_TODAY
|
|
|
|
local player_current_calendars = {}
|
|
|
|
ORDINAL = true
|
|
SHOW_WEEKDAYS = true
|
|
SHOW_TODAY = true
|
|
SHOW_HOLIDAYS = true
|
|
CHANGABLE = "full"
|
|
TODAY_BUTTON = true
|
|
|
|
local DEFAULT_SETTINGS = {
|
|
ordinal = ORDINAL,
|
|
show_weekdays = SHOW_WEEKDAYS,
|
|
show_today = SHOW_TODAY,
|
|
show_holidays = SHOW_HOLIDAYS,
|
|
changable = CHANGABLE,
|
|
today_button = TODAY_BUTTON,
|
|
}
|
|
|
|
local SHOW_AREA_TOOLTIPS = minetest.features.formspec_version_element
|
|
|
|
function calendar.show_calendar(player_name, settings, wanted_months, wanted_years, caption_format)
|
|
-- Get settings, use defaults if needed
|
|
if not settings then
|
|
settings = DEFAULT_SETTINGS
|
|
end
|
|
for k,v in pairs(DEFAULT_SETTINGS) do
|
|
if settings[k] == nil then
|
|
settings[k] = v
|
|
end
|
|
end
|
|
|
|
local days, months, years = calendar.get_date()
|
|
local total_days = minetest.get_day_count()
|
|
local ddays, dmonths, dyears = calendar.get_date(nil, settings.ordinal)
|
|
local wanted_dmonths, wanted_dyears
|
|
if not wanted_months then
|
|
wanted_months = months
|
|
end
|
|
if not wanted_years then
|
|
wanted_years = years
|
|
end
|
|
wanted_dmonths = wanted_months
|
|
wanted_dyears = wanted_years
|
|
if settings.ordinal then
|
|
wanted_dmonths = wanted_dmonths + 1
|
|
wanted_dyears = wanted_dyears + 1
|
|
end
|
|
local start_day, end_day
|
|
local tdays = 0
|
|
tdays = tdays + wanted_years * (calendar.MONTHS * calendar.MONTH_DAYS)
|
|
tdays = tdays + wanted_months * calendar.MONTH_DAYS
|
|
|
|
-- Render caption
|
|
local formspec = ""
|
|
local caption = ""
|
|
if caption_format then
|
|
local args = {}
|
|
if caption_format[3] then
|
|
for a=3, #caption_format do
|
|
table.insert(args, calendar.get_date_string(caption_format[a], tdays))
|
|
end
|
|
end
|
|
caption = calendar._translate(caption_format[2], caption_format[1], unpack(args))
|
|
else
|
|
if settings.ordinal then
|
|
caption = S("Month @1, year @2", wanted_dmonths, wanted_dyears)
|
|
else
|
|
caption = S("@1 months, @2 years", wanted_dmonths, wanted_dyears)
|
|
end
|
|
end
|
|
if caption ~= "" then
|
|
formspec = formspec .. "label[0.5,0.5;"..F(caption).."]"
|
|
end
|
|
|
|
-- Render weekday names
|
|
local tdays_start = tdays
|
|
local weekday, x, y
|
|
if settings.show_weekdays then
|
|
weekday = calendar.get_weekday(tdays)
|
|
x, y = 0.75, 1.2
|
|
for w=1, #calendar.weekday_names_short do
|
|
formspec = formspec .. "label["..x..","..y..";"..F(S(calendar.weekday_names_short[w])).."]"
|
|
x = x + 1.1
|
|
end
|
|
else
|
|
weekday = 0
|
|
end
|
|
|
|
-- Render day boxes, day numbers and highlights
|
|
x, y = 0.5, 1.7
|
|
for iday=0, calendar.MONTH_DAYS - 1 do
|
|
weekday = weekday + 1
|
|
if weekday > calendar.WEEK_DAYS then
|
|
weekday = 1
|
|
y = y + 1.1
|
|
end
|
|
x = (weekday*1.1)- 0.5
|
|
local pday = iday
|
|
if settings.ordinal then
|
|
pday = iday + 1
|
|
end
|
|
local day_str = tostring(pday)
|
|
local box_color = COLOR_DAYBOX
|
|
local holidays = calendar.get_holidays(tdays)
|
|
local tooltip_lines = {}
|
|
-- Highlight holiday
|
|
local is_holiday = false
|
|
if settings.show_holidays and #holidays > 0 then
|
|
is_holiday = true
|
|
for h=1, #holidays do
|
|
table.insert(tooltip_lines, minetest.colorize(COLOR_HOLIDAY, holidays[h].name))
|
|
end
|
|
day_str = minetest.colorize(COLOR_HOLIDAY, day_str)
|
|
box_color = COLOR_DAYBOX_HOLIDAY
|
|
if not SHOW_AREA_TOOLTIPS then
|
|
formspec = formspec .. "box["..(x-0.05)..","..(y-0.05)..";0.925,1;"..box_color.."]"
|
|
end
|
|
end
|
|
day_str = F(day_str)
|
|
-- Highlight today
|
|
if settings.show_today and tdays == total_days then
|
|
if SHOW_AREA_TOOLTIPS then
|
|
formspec = formspec .. "box["..(x-0.05)..","..(y-0.05)..";1.1,1.1;"..COLOR_DAYBOX_TODAY.."]"
|
|
else
|
|
formspec = formspec .. "box["..(x-0.1)..","..(y-0.1)..";1,1.1;"..COLOR_DAYBOX_TODAY.."]"
|
|
end
|
|
table.insert(tooltip_lines, minetest.colorize(COLOR_TOOLTIP_TODAY, S("Today")))
|
|
end
|
|
if SHOW_AREA_TOOLTIPS then
|
|
formspec = formspec .. "box["..x..","..y..";1,1;"..box_color.."]"
|
|
.. "label["..(x+0.15)..","..(y+0.075)..";"..day_str.."]"
|
|
else
|
|
local day_num = pday
|
|
if is_holiday then
|
|
day_num = minetest.colorize(COLOR_HOLIDAY, pday)
|
|
end
|
|
formspec = formspec .. "button["..x..","..y..";1,1;day"..iday..";"..F(day_num).."]"
|
|
end
|
|
if #tooltip_lines > 0 then
|
|
local tooltips = F(table.concat(tooltip_lines, "\n"))
|
|
if SHOW_AREA_TOOLTIPS then
|
|
formspec = formspec .. "tooltip["..x..","..y..";1,1;"..F(tooltips).."]"
|
|
else
|
|
formspec = formspec .. "tooltip[day"..iday..";"..F(tooltips).."]"
|
|
end
|
|
end
|
|
tdays = tdays + 1
|
|
end
|
|
y = y + 1.1
|
|
if settings.show_weekdays and calendar.get_weekday(tdays_start) <= calendar.get_weekday(tdays - 1) then
|
|
y = y + 1.1
|
|
end
|
|
y = y + 0.1
|
|
local chg_months = settings.changable == "full" or settings.changable == "months"
|
|
local chg_years = settings.changable == "full"
|
|
-- Add controls
|
|
if chg_months then
|
|
if wanted_months > 0 or wanted_years > 0 then
|
|
if chg_months or wanted_months > 0 then
|
|
formspec = formspec .. "button[1.5,"..y..";1,1;prev_month;<]"
|
|
.. "tooltip[prev_month;"..F(S("Previous month")).."]"
|
|
end
|
|
if chg_years then
|
|
formspec = formspec .. "button[0.5,"..y..";1,1;prev_year;<<]"
|
|
.. "tooltip[prev_year;"..F(S("Previous year")).."]"
|
|
end
|
|
end
|
|
if settings.today_button then
|
|
formspec = formspec .. "button[2.5,"..y..";2,1;today;"..F(S("Today")).."]"
|
|
end
|
|
|
|
if chg_months or wanted_months < calendar.MONTHS - 1 then
|
|
formspec = formspec .. "button[4.5,"..y..";1,1;next_month;>]"
|
|
.. "tooltip[next_month;"..F(S("Next month")).."]"
|
|
end
|
|
if chg_years then
|
|
formspec = formspec .. "button[5.5,"..y..";1,1;next_year;>>]"
|
|
.. "tooltip[next_year;"..F(S("Next year")).."]"
|
|
end
|
|
end
|
|
local size_x = math.max(calendar.WEEK_DAYS+2, 7)
|
|
local size_y = y+1.5
|
|
|
|
-- Formspec config
|
|
if minetest.features.formspec_version_element then
|
|
formspec = "formspec_version[3]" .. formspec
|
|
end
|
|
formspec = "size["..size_x..","..size_y.."]" .. formspec
|
|
minetest.show_formspec(player_name, "calendar:calendar", formspec)
|
|
|
|
player_current_calendars[player_name] = { years = wanted_years, months = wanted_months, settings = settings, caption_format = caption_format }
|
|
end
|
|
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
if formname ~= "calendar:calendar" then
|
|
return
|
|
end
|
|
if not player:is_player() then
|
|
return
|
|
end
|
|
local name = player:get_player_name()
|
|
local cur_years, cur_months
|
|
if not player_current_calendars then
|
|
return
|
|
end
|
|
local show = false
|
|
cur_years = player_current_calendars[name].years
|
|
cur_months = player_current_calendars[name].months
|
|
local settings = player_current_calendars[name].settings
|
|
if fields.today then
|
|
cur_years, cur_months = nil, nil
|
|
show = true
|
|
end
|
|
if settings.changable == "full" then
|
|
if fields.next_year then
|
|
cur_years = cur_years + 1
|
|
show = true
|
|
elseif fields.prev_year then
|
|
if cur_years == 0 then
|
|
cur_months = 0
|
|
else
|
|
cur_years = cur_years - 1
|
|
end
|
|
show = true
|
|
end
|
|
end
|
|
if fields.next_month then
|
|
cur_months = cur_months + 1
|
|
if cur_months > calendar.MONTHS - 1 then
|
|
if settings.changable == "months" or settings.changable == "full" then
|
|
cur_months = 0
|
|
cur_years = cur_years + 1
|
|
else
|
|
cur_months = calendar.MONTHS - 1
|
|
end
|
|
end
|
|
show = true
|
|
elseif fields.prev_month then
|
|
cur_months = cur_months - 1
|
|
if cur_months < 0 and cur_years > 0 then
|
|
if settings.changable == "months" or settings.changable == "full" then
|
|
cur_months = calendar.MONTHS - 1
|
|
cur_years = cur_years - 1
|
|
else
|
|
cur_months = 0
|
|
end
|
|
end
|
|
show = true
|
|
end
|
|
if show then
|
|
calendar.show_calendar(name,
|
|
settings,
|
|
cur_months, cur_years,
|
|
player_current_calendars[name].caption_format
|
|
)
|
|
end
|
|
end)
|
|
|
|
minetest.register_on_leaveplayer(function(player)
|
|
local name = player:get_player_name()
|
|
player_current_calendars[name] = nil
|
|
end)
|
|
|