z_mirror/TaskList

git clone https://git.raiguard.me/z_mirror/TaskList

Caleb HeuerAdd icon selector button to textfields155b98f

trunk
10.3 KiB340 linesraw
1local gui = require("gui")
2
3local constants = require("constants")
4local util = require("scripts.util")
5
6local actions = require("scripts.gui.edit-task.actions")
7
8-- GUI
9
10--- @class EditTaskGuiRefs
11--- @field window LuaGuiElement
12--- @field titlebar_flow LuaGuiElement
13--- @field title_textfield LuaGuiElement
14--- @field description_textfield LuaGuiElement
15--- @field add_to_top_checkbox LuaGuiElement
16--- @field private_checkbox LuaGuiElement
17--- @field assignee_dropdown LuaGuiElement
18--- @field status_dropdown LuaGuiElement
19--- @field footer_flow LuaGuiElement
20
21--- @class EditTaskGui
22local EditTaskGui = {}
23
24EditTaskGui.actions = actions
25
26function EditTaskGui:destroy()
27  local window = self.refs.window
28  if window and window.valid then
29    self.refs.window.destroy()
30  end
31  self.player_table.guis.edit_task = nil
32
33  if self.parent and self.parent.refs.window.valid and not self.parent.state.pinned then
34    self.player.opened = self.parent.refs.window --- @diagnostic disable-line
35  end
36
37  if self.state.standalone then
38    self.player.set_shortcut_toggled("tlst-new-task", false)
39  end
40end
41
42function EditTaskGui:dispatch(msg, e)
43  local transform = msg.transform
44  if transform then
45    if transform == "handle_titlebar_click" and e.button == defines.mouse_button_type.middle then
46      msg.action = "recenter"
47    end
48  end
49
50  if msg.action then
51    local handler = self.actions[msg.action]
52
53    -- Icon selector confirmations have these properties and should be ignored
54    -- to prevent selecting an icon from adding a new task
55    if e.element == nil and e.input_name == "tlst-linked-confirm-gui" and e.in_gui == true then
56      return
57    end
58
59    if handler then
60      handler(self, msg or {}, e or {})
61    end
62  end
63end
64
65-- BOOTSTRAP
66
67local index = {}
68
69--- @class NewTaskOptions
70--- @field parent_gui TasksGui?
71--- @field task Task?
72--- @field parent_task Task?
73--- @field set_private boolean?
74--- @field standalone boolean?
75--- @field ignore_close boolean?
76
77--- @param player LuaPlayer
78--- @param player_table PlayerTable
79--- @param options NewTaskOptions
80function index.new(player, player_table, options)
81  options = options or {}
82  local Task = options.task
83  local Parent = options.parent_gui
84  local ParentTask = options.parent_task
85
86  local players = { { "gui.tlst-unassigned" } }
87  local force = util.get_force(player)
88  local assignee_selection_index = 1
89  local player_selection_index = 0
90
91  local title_caption
92  if Task then
93    title_caption = { "gui.tlst-edit-task" }
94  else
95    title_caption = { "gui.tlst-new-task" }
96  end
97
98  Task = Task or {}
99
100  local assignable = true
101  local owner = Task.owner or ParentTask or {}
102  local assignee_index = 0
103  while owner.object_name == "Task" do
104    owner = owner.owner
105  end
106  if owner.object_name == "LuaPlayer" then
107    assignable = false
108    assignee_index = ParentTask and ParentTask.assignee and ParentTask.assignee.index or 0
109  else
110    assignee_index = Task.assignee and Task.assignee.index or 0
111  end
112
113  for player_index, other_player in pairs(game.players) do
114    if util.get_force(other_player) == force then
115      table.insert(players, other_player.name)
116      if player_index == player.index then
117        player_selection_index = #players
118      end
119      if assignee_index == player_index then
120        assignee_selection_index = #players
121      end
122    end
123  end
124
125  local default_task = player.mod_settings["tlst-new-tasks-in-progress"].value and "in_progress" or "not_started"
126  local status_items = {}
127  local selected_status_index = constants.task_status[default_task].index
128  for status_name, status_info in pairs(constants.task_status) do
129    if status_name == Task.status then
130      selected_status_index = status_info.index
131    end
132    table.insert(status_items, { "", "[img=flib_indicator_" .. status_info.color .. "]  ", status_info.label })
133  end
134
135  --- @type EditTaskGuiRefs
136  local refs = gui.build(player.gui.screen, {
137    {
138      type = "frame",
139      name = "tlst_edit_task_window",
140      style_mods = { width = 448 },
141      direction = "vertical",
142      ref = { "window" },
143      actions = {
144        on_closed = { gui = "edit_task", action = "close" },
145      },
146      {
147        type = "flow",
148        style = "flib_titlebar_flow",
149        ref = { "titlebar_flow" },
150        actions = {
151          on_click = { gui = "edit_task", transform = "handle_titlebar_click" },
152        },
153        { type = "label", style = "frame_title", caption = title_caption, ignored_by_interaction = true },
154        { type = "empty-widget", style = "flib_dialog_titlebar_drag_handle", ignored_by_interaction = true },
155      },
156      {
157        type = "frame",
158        style = "inside_shallow_frame",
159        direction = "vertical",
160        {
161          type = "frame",
162          style = "subheader_frame",
163          style_mods = { horizontally_stretchable = true },
164          visible = ParentTask and true or false,
165          {
166            type = "label",
167            style = "bold_label",
168            style_mods = { left_margin = 8 },
169            caption = ParentTask and { "gui.tlst-subtask-of", ParentTask.title } or nil,
170          },
171        },
172        {
173          type = "flow",
174          style_mods = { padding = 12, vertical_spacing = 8 },
175          direction = "vertical",
176          { type = "label", caption = { "gui.tlst-title" } },
177          {
178            type = "textfield",
179            style = "flib_widthless_textfield",
180            style_mods = { horizontally_stretchable = true },
181            text = Task.title,
182            icon_selector = true,
183            ref = { "title_textfield" },
184            actions = {
185              on_confirmed = { gui = "edit_task", action = "confirm" },
186            },
187          },
188          { type = "label", caption = { "gui.tlst-description" } },
189          {
190            type = "text-box",
191            style_mods = { height = 200, width = 400 },
192            text = Task.description,
193            icon_selector = true,
194            elem_mods = { word_wrap = true },
195            ref = { "description_textfield" },
196            actions = {
197              on_confirmed = { gui = "edit_task", action = "confirm" },
198            },
199          },
200          {
201            type = "flow",
202            visible = not Task.title,
203            {
204              type = "checkbox",
205              caption = { "gui.tlst-add-to-top" },
206              state = player.mod_settings["tlst-new-tasks-at-top"].value,
207              ref = { "add_to_top_checkbox" },
208            },
209            { type = "empty-widget", style = "flib_horizontal_pusher" },
210            {
211              type = "checkbox",
212              caption = { "", { "gui.tlst-private" }, " [img=info]" },
213              tooltip = { "gui.tlst-private-description" },
214              state = owner and owner.object_name == "LuaPlayer" or false,
215              enabled = not ParentTask,
216              ref = { "private_checkbox" },
217              actions = {
218                on_checked_state_changed = { gui = "edit_task", action = "update_assignee_dropdown" },
219              },
220            },
221          },
222          {
223            type = "flow",
224            style_mods = { vertical_align = "center" },
225            { type = "label", caption = { "gui.tlst-assignee" } },
226            { type = "empty-widget", style = "flib_horizontal_pusher" },
227            {
228              type = "drop-down",
229              items = players,
230              selected_index = assignee_selection_index,
231              enabled = assignable,
232              ref = { "assignee_dropdown" },
233            },
234          },
235          {
236            type = "flow",
237            style_mods = { vertical_align = "center" },
238            {
239              type = "label",
240              caption = { "", { "gui.tlst-status" }, " [img=info]" },
241              tooltip = { "gui.tlst-status-description" },
242            },
243            { type = "empty-widget", style = "flib_horizontal_pusher" },
244            {
245              type = "drop-down",
246              items = status_items,
247              selected_index = selected_status_index,
248              ref = { "status_dropdown" },
249            },
250          },
251        },
252      },
253      {
254        type = "flow",
255        style = "dialog_buttons_horizontal_flow",
256        actions = { on_click = { gui = "edit_task", transform = "handle_titlebar_click" } },
257        ref = { "footer_flow" },
258        {
259          type = "button",
260          style = "back_button",
261          caption = { "gui.cancel" },
262          actions = {
263            on_click = { gui = "edit_task", action = "close" },
264          },
265        },
266        { type = "empty-widget", style = "flib_dialog_footer_drag_handle", ignored_by_interaction = true },
267        Task.title and {
268          type = "button",
269          style = "tlst_red_dialog_button",
270          caption = { "gui.delete" },
271          actions = {
272            on_click = { gui = "edit_task", action = "delete" },
273          },
274        } or {},
275        Task.title and {
276          type = "empty-widget",
277          style = "flib_dialog_footer_drag_handle",
278          ignored_by_interaction = true,
279        } or {},
280        {
281          type = "button",
282          style = "confirm_button",
283          caption = { "gui.confirm" },
284          actions = {
285            on_click = { gui = "edit_task", action = "confirm" },
286          },
287        },
288      },
289    },
290  })
291
292  refs.window.force_auto_center()
293  refs.titlebar_flow.drag_target = refs.window
294  refs.footer_flow.drag_target = refs.window
295
296  if Parent then
297    if not Parent.state.pinned then
298      Parent.state.ignore_close = true
299    end
300    player.opened = refs.window
301  elseif options.standalone then
302    player.opened = refs.window
303    player.set_shortcut_toggled("tlst-new-task", true)
304  end
305
306  --- @class EditTaskGui
307  local self = {
308    parent = Parent,
309    player = player,
310    player_table = player_table,
311    refs = refs,
312    state = {
313      just_confirmed = options.ignore_close and true or false,
314      parent_task = ParentTask,
315      player_selection_index = player_selection_index,
316      standalone = options.standalone,
317      --- @type Task|nil
318      task = Task.title and Task or nil,
319    },
320  }
321
322  setmetatable(self, { __index = EditTaskGui })
323
324  player_table.guis.edit_task = self
325
326  if options.set_private then
327    self.refs.private_checkbox.state = true
328    self.actions.update_assignee_dropdown(self)
329  end
330
331  self.refs.title_textfield.select_all()
332  self.refs.title_textfield.focus()
333end
334
335--- @param Gui EditTaskGui
336function index.load(Gui)
337  setmetatable(Gui, { __index = EditTaskGui })
338end
339
340return index