Editor enhancements (#8903)
Map/Scenario Editor * Rename Load Map to Load Map/Scenario (since it can load both), Edit Scenario to Edit Scenario Settings, Save Map to just Save. * Rearrange menu order * Add icon for the preferences menu item (used the preexisting settings.png icon) * Open folder correctly at Add-on's scenario directory instead of editor/scenarios. (#8910) * Show Save Scenario As only for Scenarios * Use the settings.png icon for Preferences menu item * Add functionality to "Loyal" checkbox (Unit tool -> Place unit -> Right click menu) (#8445) * Show warning when maps are saved in scenarios folder or vice versa (#8911) * Unit List moved to Units menu from File menu to reduce some pressure from the latter. * Status Table menu item disabled since it does nothing. (Should be reenabled once the functionality has been added.) * Improve reload functionality in Editor (F5). Reload happens directly from memory and no temp files are needed. Also, the undo/redo stacks will be preserved. (#9024) Time Schedule Editor * Browse buttons now set wesnoth style paths instead of just pasting the absolute path returned by the file dialog * Change text boxes from inactive to uneditable. * Code generation improvements * Add copyright notice to tod_new_schedule * Confirmation messages * Preview buttons for image and sound files and new icons for the preview button (2 sets : preview image and preview sound) Unit Type Editor * Confirmation messages * New icons for the preview button (2 sets : preview image and preview sound) Add-on menu * Two new menu entries for (1) opening the Add-on selection dialog, (2) opening the folder corresponding to the Add-on The open add-on folder option shows a GUI2 file dialog at the add-on's folder which can be used to open any file. If it is a loadable map/scenario it will be opened in the editor, otherwise the OS's default application for that file will be opened. File Dialog * Redesigned with new icons * New Open External button that opens selected file/folder in the platform's default application (independently of what pressing Open would do). This could be used to quickly open a folder or preview the file before actually selecting it. * Extension checking and filename validation. (See #8911)
|
@ -17736,6 +17736,13 @@ Date,File,License,Author - Real Name(other name);Real Name(other name);etc,Notes
|
|||
2013/05/26,images/icons/action/playlist_30-active.png,GNU GPL v2+,Emilien Rotival(LordBob),,,74fd5c0b4927aafc27e79c8a360fe2c8
|
||||
2013/05/26,images/icons/action/playlist_30-pressed.png,GNU GPL v2+,Emilien Rotival(LordBob),,,4a4338bcdcd23b78ea227461c68fc867
|
||||
2013/05/26,images/icons/action/playlist_30.png,GNU GPL v2+,Emilien Rotival(LordBob),,,d719535714ed129c56133c2a0d3cd704
|
||||
2024/05/24,images/icons/action/preferences_25.png,GNU GPL v2+,Emilien Rotival(LordBob),"same as settings.png, scaled down",,6a827ee3ad77fd60b17e4ea7167d7907
|
||||
2024/05/23,images/icons/action/preview_25-active.png,GNU GPL v2+,Subhraman Sarkar(babaissarkar),,,6ad340e7d910c9b0fa31ce79e09164f1
|
||||
2024/05/24,images/icons/action/preview_25-pressed.png,GNU GPL v2+,Subhraman Sarkar(babaissarkar),,,f93f8e433440defa9b6743593c122ead
|
||||
2024/05/25,images/icons/action/preview_25.png,GNU GPL v2+,Subhraman Sarkar(babaissarkar),,,a157e05242054558882f3c778e04717e
|
||||
2024/05/26,images/icons/action/preview_30-active.png,GNU GPL v2+,Subhraman Sarkar(babaissarkar),,,3e92dd9e71fc3eb6f4c443960719eaec
|
||||
2024/05/27,images/icons/action/preview_30-pressed.png,GNU GPL v2+,Subhraman Sarkar(babaissarkar),,,11fa82232a9564c68f3847a4197f1df9
|
||||
2024/05/28,images/icons/action/preview_30.png,GNU GPL v2+,Subhraman Sarkar(babaissarkar),,,aaa5307d0142806fcdd108c75bfe8860
|
||||
2013/04/29,images/icons/action/redo_25-active.png,GNU GPL v2+,Emilien Rotival(LordBob),,,b7643aaf484e4ea98ee362f3b1b33915
|
||||
2013/04/29,images/icons/action/redo_25-pressed.png,GNU GPL v2+,Emilien Rotival(LordBob),,,2d71a8c4d3ea72a9dc2149e5d22437c2
|
||||
2013/04/29,images/icons/action/redo_25.png,GNU GPL v2+,Emilien Rotival(LordBob),,,a4d057572a76752b3d40e0bc63228f16
|
||||
|
@ -18322,7 +18329,8 @@ Date,File,License,Author - Real Name(other name);Real Name(other name);etc,Notes
|
|||
2011/03/11,images/misc/ellipse-selected-top.png,GNU GPL v2+,Jordà Polo(ettin);Lari Nieminen(zookeeper),,,383c573e6b6eb97e3d09ea97d63107e1
|
||||
2011/03/11,images/misc/ellipse-top.png,GNU GPL v2+,Jordà Polo(ettin);Lari Nieminen(zookeeper),,,914b3908e00ab55071bde61dce55a6e6
|
||||
2011/03/11,images/misc/eye.png,GNU GPL v2+,David White(dave),,,5e56c4e45341c3915664ca4f0c096897
|
||||
2019/01/01,images/misc/folder-bookmark-icon.png,GNU GPL v2+,Emilien Rotival(LordBob),,,59a3279e2a6326f61b2f35531495d25e
|
||||
2024/05/27,images/misc/file.png,GNU GPL v2+,Subhraman Sarkar(babaissarkar),,,edbfcfc60063ab4f5bfc2ccd09c4c7bd
|
||||
2024/05/27,images/misc/folder-bookmark-icon.png,GNU GPL v2+,Subhraman Sarkar(babaissarkar);Emilien Rotival(LordBob),,,d325820e7532a93fbd76e230bbecc00b
|
||||
2019/01/01,images/misc/folder-icon.png,GNU GPL v2+,Emilien Rotival(LordBob),,,2f646c254de628f5c388ce330d22918d
|
||||
2011/03/11,images/misc/font8x8.png,GNU GPL v2+,unknown,,,f1b9efcedc4c8f5f46c890036469a538
|
||||
2011/03/27,images/misc/hidden.png,GNU GPL v2+,Ali El Gariani(alink),,,508dc64614fd0b5d5abc492c39a4926d
|
||||
|
|
Can't render this file because it is too large.
|
|
@ -468,7 +468,15 @@
|
|||
"preview"
|
||||
"Preview button"
|
||||
"buttons/button_square/button_square_25"
|
||||
"icons/action/zoomdefault_25"
|
||||
"icons/action/preview_25"
|
||||
()
|
||||
}
|
||||
|
||||
{_GUI_DEFINITION
|
||||
"play"
|
||||
"Play button"
|
||||
"buttons/button_square/button_square_25"
|
||||
"icons/action/play_25"
|
||||
()
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
### Definition of the custom tod window in the editor.
|
||||
###
|
||||
|
||||
#define _GUI_DATA_PATH_ENTRY ID_STEM LABEL
|
||||
#define _GUI_DATA_PATH_ENTRY ID_STEM LABEL PREVIEW_BUTTON
|
||||
[row]
|
||||
grow_factor = 0
|
||||
|
||||
|
@ -33,9 +33,12 @@
|
|||
[text_box]
|
||||
id = "path_" + {ID_STEM}
|
||||
definition = "default"
|
||||
editable = false
|
||||
[/text_box]
|
||||
|
||||
[/column]
|
||||
|
||||
{PREVIEW_BUTTON}
|
||||
|
||||
[column]
|
||||
grow_factor = 0
|
||||
|
@ -72,6 +75,42 @@
|
|||
[/row]
|
||||
#enddef
|
||||
|
||||
#define _GUI_DATA_PATH_ENTRY_IMAGE ID_STEM LABEL
|
||||
{_GUI_DATA_PATH_ENTRY {ID_STEM} {LABEL} (
|
||||
[column]
|
||||
grow_factor = 0
|
||||
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_grow = true
|
||||
|
||||
[button]
|
||||
id = "preview_" + {ID_STEM}
|
||||
definition = "preview"
|
||||
tooltip = _ "Preview image"
|
||||
[/button]
|
||||
[/column]
|
||||
)}
|
||||
#enddef
|
||||
|
||||
#define _GUI_DATA_PATH_ENTRY_SOUND ID_STEM LABEL
|
||||
{_GUI_DATA_PATH_ENTRY {ID_STEM} {LABEL} (
|
||||
[column]
|
||||
grow_factor = 0
|
||||
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_grow = true
|
||||
|
||||
[button]
|
||||
id = "preview_" + {ID_STEM}
|
||||
definition = "play"
|
||||
tooltip = _ "Play sound"
|
||||
[/button]
|
||||
[/column]
|
||||
)}
|
||||
#enddef
|
||||
|
||||
#define _GUI_COLOR_SLIDER _ID _LABEL
|
||||
[row]
|
||||
grow_factor = 0
|
||||
|
@ -310,9 +349,9 @@
|
|||
|
||||
[grid]
|
||||
|
||||
{_GUI_DATA_PATH_ENTRY "image" ( _ "Image:")}
|
||||
{_GUI_DATA_PATH_ENTRY "mask" ( _ "Mask:")}
|
||||
{_GUI_DATA_PATH_ENTRY "sound" ( _ "Sound:")}
|
||||
{_GUI_DATA_PATH_ENTRY_IMAGE "image" ( _ "Image:")}
|
||||
{_GUI_DATA_PATH_ENTRY_IMAGE "mask" ( _ "Mask:")}
|
||||
{_GUI_DATA_PATH_ENTRY_SOUND "sound" ( _ "Sound:")}
|
||||
|
||||
[/grid]
|
||||
|
||||
|
@ -454,8 +493,9 @@
|
|||
horizontal_alignment = "right"
|
||||
|
||||
[button]
|
||||
id = "preview"
|
||||
id = "preview_color"
|
||||
definition = "preview"
|
||||
tooltip = _ "Preview color changes on map"
|
||||
[/button]
|
||||
[/column]
|
||||
|
||||
|
|
|
@ -124,27 +124,14 @@
|
|||
### Main Stats page
|
||||
[row]
|
||||
[column]
|
||||
[grid]
|
||||
[row]
|
||||
[column]
|
||||
[panel]
|
||||
definition="box_display"
|
||||
horizontal_alignment = left
|
||||
vertical_alignment = top
|
||||
[panel]
|
||||
definition="box_display"
|
||||
[grid]
|
||||
[row]
|
||||
[column]
|
||||
[grid]
|
||||
id="grid_stats"
|
||||
[row]
|
||||
[column]
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_alignment = "left"
|
||||
|
||||
[label]
|
||||
id = "title"
|
||||
definition = "title"
|
||||
label = _ "Stats"
|
||||
[/label]
|
||||
[/column]
|
||||
{_GUI_INFO_TAB_PADDING}
|
||||
[/row]
|
||||
[row]
|
||||
[column]
|
||||
grow_factor = 0
|
||||
|
@ -340,7 +327,8 @@
|
|||
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_alignment = "left"
|
||||
horizontal_grow = true
|
||||
vertical_grow = true
|
||||
|
||||
[scroll_text]
|
||||
id = "desc_box"
|
||||
|
@ -373,7 +361,7 @@
|
|||
definition = "default"
|
||||
[/menu_button]
|
||||
[/column]
|
||||
[/row]
|
||||
[/row]
|
||||
|
||||
[row]
|
||||
[column]
|
||||
|
@ -495,10 +483,10 @@
|
|||
[/column]
|
||||
[/row]
|
||||
[/grid]
|
||||
[/panel]
|
||||
[/column]
|
||||
[/row]
|
||||
[/grid]
|
||||
[/column]
|
||||
[/row]
|
||||
[/grid]
|
||||
[/panel]
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
|
@ -518,6 +506,8 @@
|
|||
### Attacks
|
||||
[row]
|
||||
[column]
|
||||
horizontal_alignment = left
|
||||
vertical_alignment = top
|
||||
[panel]
|
||||
definition="box_display"
|
||||
[grid]
|
||||
|
@ -821,29 +811,14 @@
|
|||
|
||||
#define _GUI_ADVANCED_PAGE
|
||||
### Advanced stats
|
||||
|
||||
[row]
|
||||
[column]
|
||||
horizontal_alignment = "left"
|
||||
horizontal_alignment = left
|
||||
vertical_alignment = top
|
||||
[panel]
|
||||
definition="box_display"
|
||||
[grid]
|
||||
id="grid_atk"
|
||||
[row]
|
||||
[column]
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_alignment = "left"
|
||||
|
||||
[label]
|
||||
id = "title"
|
||||
definition = "title"
|
||||
label = _ "Advanced"
|
||||
[/label]
|
||||
[/column]
|
||||
|
||||
{_GUI_INFO_TAB_PADDING}
|
||||
[/row]
|
||||
id="grid_adv"
|
||||
|
||||
{_GUI_DATA_PATH_ENTRY_2_COL small_profile_image (_ "Small Profile")}
|
||||
|
||||
|
@ -1118,32 +1093,32 @@
|
|||
#enddef
|
||||
|
||||
#define _GUI_WML_PAGE
|
||||
[row]
|
||||
[column]
|
||||
horizontal_grow = true
|
||||
vertical_grow = true
|
||||
[panel]
|
||||
definition="box_display"
|
||||
[grid]
|
||||
id="grid_wml"
|
||||
[row]
|
||||
[column]
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_grow = true
|
||||
vertical_grow = true
|
||||
|
||||
[scroll_text]
|
||||
id = "wml_view"
|
||||
definition = "verbatim"
|
||||
editable = false
|
||||
[/scroll_text]
|
||||
[/column]
|
||||
[/row]
|
||||
[/grid]
|
||||
[/panel]
|
||||
[/column]
|
||||
[/row]
|
||||
[row]
|
||||
[column]
|
||||
horizontal_grow = true
|
||||
vertical_grow = true
|
||||
[panel]
|
||||
definition="box_display"
|
||||
[grid]
|
||||
id="grid_wml"
|
||||
[row]
|
||||
[column]
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_grow = true
|
||||
vertical_grow = true
|
||||
|
||||
[scroll_text]
|
||||
id = "wml_view"
|
||||
definition = "verbatim"
|
||||
editable = false
|
||||
[/scroll_text]
|
||||
[/column]
|
||||
[/row]
|
||||
[/grid]
|
||||
[/panel]
|
||||
[/column]
|
||||
[/row]
|
||||
#enddef
|
||||
|
||||
[window]
|
||||
|
@ -1153,10 +1128,6 @@
|
|||
[resolution]
|
||||
definition = "default"
|
||||
|
||||
automatic_placement = true
|
||||
vertical_placement = "center"
|
||||
horizontal_placement = "center"
|
||||
|
||||
[tooltip]
|
||||
id = "tooltip"
|
||||
[/tooltip]
|
||||
|
@ -1184,126 +1155,63 @@
|
|||
id="main_grid"
|
||||
[row]
|
||||
[column]
|
||||
border=all
|
||||
border_size=5
|
||||
vertical_alignment=top
|
||||
horizontal_alignment=left
|
||||
|
||||
[label]
|
||||
definition=title
|
||||
label= _ "New Unit Type"
|
||||
[/label]
|
||||
[/column]
|
||||
[/row]
|
||||
[row]
|
||||
[column]
|
||||
[spacer]
|
||||
height = 5
|
||||
[/spacer]
|
||||
[/column]
|
||||
[/row]
|
||||
[row]
|
||||
[column]
|
||||
vertical_alignment=top
|
||||
[grid]
|
||||
id="row_grid"
|
||||
[row]
|
||||
[column]
|
||||
[listbox]
|
||||
id="tabs"
|
||||
[list_definition]
|
||||
[row]
|
||||
[column]
|
||||
[toggle_panel]
|
||||
linked_group = "tabs"
|
||||
|
||||
[grid]
|
||||
|
||||
[row]
|
||||
|
||||
{_GUI_INFO_TAB_PADDING}
|
||||
|
||||
[column]
|
||||
grow_factor = 1
|
||||
border = all
|
||||
border_size = 5
|
||||
|
||||
[image]
|
||||
id = "tab_image"
|
||||
[/image]
|
||||
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
grow_factor = 1
|
||||
border = all
|
||||
border_size = 5
|
||||
|
||||
[label]
|
||||
id = "tab_label"
|
||||
wrap = true
|
||||
[/label]
|
||||
|
||||
[/column]
|
||||
|
||||
{_GUI_INFO_TAB_PADDING}
|
||||
|
||||
[/row]
|
||||
|
||||
[/grid]
|
||||
|
||||
[/toggle_panel]
|
||||
[/column]
|
||||
[/row]
|
||||
[/list_definition]
|
||||
[list_data]
|
||||
[row]
|
||||
[column]
|
||||
[widget]
|
||||
id = "tab_image"
|
||||
label = "/data/core/images/units/human-loyalists/general.png"
|
||||
[/widget]
|
||||
[widget]
|
||||
id = "tab_label"
|
||||
label = _ "Main Stats"
|
||||
[/widget]
|
||||
[/column]
|
||||
[/row]
|
||||
[row]
|
||||
[column]
|
||||
[widget]
|
||||
id = "tab_image"
|
||||
label = "/data/core/images/attacks/rectangular-shield.png"
|
||||
[/widget]
|
||||
[widget]
|
||||
id = "tab_label"
|
||||
label = _ "Advanced"
|
||||
[/widget]
|
||||
[/column]
|
||||
[/row]
|
||||
[row]
|
||||
[column]
|
||||
[widget]
|
||||
id = "tab_image"
|
||||
label = "/data/core/images/attacks/sword-human.png"
|
||||
[/widget]
|
||||
[widget]
|
||||
id = "tab_label"
|
||||
label = _ "Attacks"
|
||||
[/widget]
|
||||
[/column]
|
||||
[/row]
|
||||
[row]
|
||||
[column]
|
||||
[widget]
|
||||
id = "tab_image"
|
||||
label = "/data/core/images/attacks/gaze.png"
|
||||
[/widget]
|
||||
[widget]
|
||||
id = "tab_label"
|
||||
label = _ "WML View"
|
||||
[/widget]
|
||||
[/column]
|
||||
[/row]
|
||||
[/list_data]
|
||||
[/listbox]
|
||||
[/column]
|
||||
[column]
|
||||
[stacked_widget]
|
||||
id = "page"
|
||||
definition = "default"
|
||||
[layer]
|
||||
{_GUI_MAIN_STATS_PAGE}
|
||||
[/layer]
|
||||
[layer]
|
||||
{_GUI_ADVANCED_PAGE}
|
||||
[/layer]
|
||||
[layer]
|
||||
{_GUI_ATTACK_PAGE}
|
||||
[/layer]
|
||||
[layer]
|
||||
{_GUI_WML_PAGE}
|
||||
[/layer]
|
||||
[/stacked_widget]
|
||||
vertical_alignment = top
|
||||
[tab_container]
|
||||
id = tabs
|
||||
[tab]
|
||||
name = _ "Main Stats"
|
||||
image = "/data/core/images/units/human-loyalists/general.png"
|
||||
[data]
|
||||
{_GUI_MAIN_STATS_PAGE}
|
||||
[/data]
|
||||
[/tab]
|
||||
[tab]
|
||||
name = _ "Advanced"
|
||||
image = "/data/core/images/attacks/rectangular-shield.png"
|
||||
[data]
|
||||
{_GUI_ADVANCED_PAGE}
|
||||
[/data]
|
||||
[/tab]
|
||||
[tab]
|
||||
name = _ "Attacks"
|
||||
image = "/data/core/images/attacks/sword-human.png"
|
||||
[data]
|
||||
{_GUI_ATTACK_PAGE}
|
||||
[/data]
|
||||
[/tab]
|
||||
[tab]
|
||||
name = _ "WML View"
|
||||
image = "/data/core/images/attacks/gaze.png"
|
||||
[data]
|
||||
{_GUI_WML_PAGE}
|
||||
[/data]
|
||||
[/tab]
|
||||
[/tab_container]
|
||||
[/column]
|
||||
[/row]
|
||||
[/grid]
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
[resolution]
|
||||
definition = "default"
|
||||
|
||||
{GUI_WINDOW_FIXED_SIZE_CENTERED 700 750}
|
||||
{GUI_WINDOW_FIXED_SIZE_CENTERED 750 650}
|
||||
|
||||
[linked_group]
|
||||
id = "bookmark_icons"
|
||||
|
@ -80,294 +80,6 @@
|
|||
|
||||
[/row]
|
||||
|
||||
[row]
|
||||
grow_factor = 1
|
||||
|
||||
[column]
|
||||
horizontal_grow = true
|
||||
vertical_grow = true
|
||||
|
||||
[grid]
|
||||
|
||||
[row]
|
||||
grow_factor = 0
|
||||
|
||||
[column]
|
||||
grow_factor = 0
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_alignment = "left"
|
||||
|
||||
[label]
|
||||
definition = "gold_small"
|
||||
label = _ "Places"
|
||||
[/label]
|
||||
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
grow_factor = 1
|
||||
horizontal_grow = true
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[label]
|
||||
id = "current_dir"
|
||||
definition = "gold_small"
|
||||
wrap = false
|
||||
can_shrink = true
|
||||
[/label]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[row]
|
||||
grow_factor = 1
|
||||
|
||||
[column]
|
||||
grow_factor = 0
|
||||
|
||||
horizontal_grow = true
|
||||
vertical_grow = true
|
||||
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[listbox]
|
||||
id = "bookmarks"
|
||||
definition = "default"
|
||||
has_minimum = false
|
||||
horizontal_scrollbar_mode = "never"
|
||||
|
||||
[list_definition]
|
||||
|
||||
[row]
|
||||
|
||||
[column]
|
||||
vertical_grow = true
|
||||
horizontal_grow = true
|
||||
|
||||
[toggle_panel]
|
||||
definition = "default"
|
||||
|
||||
[grid]
|
||||
|
||||
[row]
|
||||
|
||||
[column]
|
||||
grow_factor = 0
|
||||
horizontal_alignment = "left"
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[image]
|
||||
id = "icon"
|
||||
definition = "default"
|
||||
linked_group = "bookmark_icons"
|
||||
label = "misc/folder-bookmark-icon.png"
|
||||
[/image]
|
||||
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
grow_factor = 1
|
||||
horizontal_grow = true
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[label]
|
||||
id = "bookmark"
|
||||
definition = "default"
|
||||
linked_group = "bookmark_labels"
|
||||
wrap = true
|
||||
[/label]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[/grid]
|
||||
|
||||
[/toggle_panel]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[/list_definition]
|
||||
|
||||
[/listbox]
|
||||
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
grow_factor = 1
|
||||
|
||||
horizontal_grow = true
|
||||
vertical_grow = true
|
||||
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[listbox]
|
||||
id = "filelist"
|
||||
definition = "default"
|
||||
|
||||
[list_definition]
|
||||
|
||||
[row]
|
||||
|
||||
[column]
|
||||
vertical_grow = true
|
||||
horizontal_grow = true
|
||||
|
||||
[toggle_panel]
|
||||
# Needed for double-click event handling!
|
||||
id = "item_panel"
|
||||
definition = "default"
|
||||
|
||||
[grid]
|
||||
|
||||
[row]
|
||||
|
||||
[column]
|
||||
grow_factor = 0
|
||||
horizontal_alignment = "left"
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[image]
|
||||
id = "icon"
|
||||
definition = "default"
|
||||
linked_group = "fileview_icons"
|
||||
[/image]
|
||||
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
grow_factor = 1
|
||||
horizontal_grow = true
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[label]
|
||||
id = "file"
|
||||
definition = "default"
|
||||
linked_group = "fileview_labels"
|
||||
[/label]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[/grid]
|
||||
|
||||
[/toggle_panel]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[/list_definition]
|
||||
|
||||
[/listbox]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[row]
|
||||
grow_factor = 0
|
||||
|
||||
[column]
|
||||
horizontal_grow = true
|
||||
|
||||
[grid]
|
||||
|
||||
[row]
|
||||
|
||||
[column]
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_alignment = "left"
|
||||
grow_factor = 1
|
||||
|
||||
[button]
|
||||
id = "add_bookmark"
|
||||
definition = "add"
|
||||
tooltip = _ "Bookmarks the current folder"
|
||||
[/button]
|
||||
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_alignment = "right"
|
||||
|
||||
[button]
|
||||
id = "remove_bookmark"
|
||||
definition = "delete"
|
||||
tooltip = _ "Removes the current bookmark"
|
||||
[/button]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[/grid]
|
||||
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
horizontal_grow = true
|
||||
|
||||
[grid]
|
||||
|
||||
[row]
|
||||
|
||||
[column]
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_alignment = "left"
|
||||
grow_factor = 1
|
||||
|
||||
[button]
|
||||
id = "delete_file"
|
||||
#definition = "action_delete_file"
|
||||
label = _ "Delete"
|
||||
[/button]
|
||||
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_alignment = "right"
|
||||
|
||||
[button]
|
||||
id = "new_dir"
|
||||
definition = "default"
|
||||
label = _ "New Folder"
|
||||
[/button]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[/grid]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[/grid]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[row]
|
||||
grow_factor = 0
|
||||
|
||||
|
@ -407,6 +119,366 @@
|
|||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[row]
|
||||
[column]
|
||||
[spacer][/spacer]
|
||||
[/column]
|
||||
[column]
|
||||
border = "left"
|
||||
border_size = 5
|
||||
horizontal_grow = true
|
||||
|
||||
[label]
|
||||
id = "validation_msg"
|
||||
definition = "default"
|
||||
use_markup = true
|
||||
wrap = false
|
||||
[/label]
|
||||
[/column]
|
||||
[/row]
|
||||
|
||||
[/grid]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[row]
|
||||
[column]
|
||||
[spacer]
|
||||
height = 10
|
||||
[/spacer]
|
||||
[/column]
|
||||
[/row]
|
||||
|
||||
[row]
|
||||
grow_factor = 1
|
||||
|
||||
[column]
|
||||
horizontal_alignment = left
|
||||
vertical_grow = true
|
||||
|
||||
[grid]
|
||||
|
||||
[row]
|
||||
grow_factor = 0
|
||||
|
||||
[column]
|
||||
grow_factor = 0
|
||||
vertical_grow = true
|
||||
|
||||
[grid]
|
||||
[row]
|
||||
[column]
|
||||
horizontal_alignment = left
|
||||
vertical_alignment = top
|
||||
[panel]
|
||||
definition = box_display
|
||||
[grid]
|
||||
[row]
|
||||
[column]
|
||||
grow_factor = 0
|
||||
border = top,left,right
|
||||
border_size = 5
|
||||
horizontal_alignment = "left"
|
||||
|
||||
[label]
|
||||
definition = "gold_small"
|
||||
label = _ "Places"
|
||||
[/label]
|
||||
[/column]
|
||||
[/row]
|
||||
[row]
|
||||
[column]
|
||||
border = bottom,left,right
|
||||
border_size = 5
|
||||
horizontal_grow = true
|
||||
vertical_grow = true
|
||||
|
||||
[listbox]
|
||||
id = "bookmarks"
|
||||
definition = "default"
|
||||
has_minimum = false
|
||||
horizontal_scrollbar_mode = "never"
|
||||
|
||||
[list_definition]
|
||||
|
||||
[row]
|
||||
|
||||
[column]
|
||||
vertical_grow = true
|
||||
horizontal_grow = true
|
||||
|
||||
[toggle_panel]
|
||||
definition = "default"
|
||||
|
||||
[grid]
|
||||
|
||||
[row]
|
||||
|
||||
[column]
|
||||
grow_factor = 0
|
||||
horizontal_alignment = "left"
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[image]
|
||||
id = "icon"
|
||||
definition = "default"
|
||||
linked_group = "bookmark_icons"
|
||||
label = "misc/folder-bookmark-icon.png"
|
||||
[/image]
|
||||
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
grow_factor = 1
|
||||
horizontal_grow = true
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[label]
|
||||
id = "bookmark"
|
||||
definition = "default"
|
||||
linked_group = "bookmark_labels"
|
||||
wrap = true
|
||||
[/label]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[/grid]
|
||||
|
||||
[/toggle_panel]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[/list_definition]
|
||||
|
||||
[/listbox]
|
||||
[/column]
|
||||
[/row]
|
||||
[row]
|
||||
[column]
|
||||
horizontal_alignment = left
|
||||
[grid]
|
||||
[row]
|
||||
[column]
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_alignment = "left"
|
||||
grow_factor = 1
|
||||
|
||||
[button]
|
||||
id = "add_bookmark"
|
||||
definition = add
|
||||
tooltip = _ "Bookmarks the current folder"
|
||||
[/button]
|
||||
|
||||
[/column]
|
||||
[column]
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_alignment = "left"
|
||||
|
||||
[button]
|
||||
id = "remove_bookmark"
|
||||
definition = delete
|
||||
tooltip = _ "Removes the current bookmark"
|
||||
[/button]
|
||||
|
||||
[/column]
|
||||
[/row]
|
||||
[/grid]
|
||||
[/column]
|
||||
[/row]
|
||||
[/grid]
|
||||
[/panel]
|
||||
[/column]
|
||||
[/row]
|
||||
|
||||
[row]
|
||||
[column]
|
||||
horizontal_alignment = center
|
||||
vertical_alignment = bottom
|
||||
[grid]
|
||||
[row]
|
||||
[column]
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_alignment = "left"
|
||||
|
||||
[button]
|
||||
id = "open_ext"
|
||||
definition = "default"
|
||||
label = _ "Open External"
|
||||
tooltip = _ "Open selected using platform's default applications"
|
||||
[/button]
|
||||
|
||||
[/column]
|
||||
[/row]
|
||||
[row]
|
||||
[column]
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_alignment = "left"
|
||||
|
||||
[button]
|
||||
id = "new_dir"
|
||||
definition = "default"
|
||||
label = _ "New Folder"
|
||||
[/button]
|
||||
|
||||
[/column]
|
||||
[/row]
|
||||
[row]
|
||||
[column]
|
||||
border = "all"
|
||||
border_size = 5
|
||||
horizontal_alignment = "left"
|
||||
grow_factor = 1
|
||||
|
||||
[button]
|
||||
id = "delete_file"
|
||||
label = _ "Delete"
|
||||
[/button]
|
||||
|
||||
[/column]
|
||||
[/row]
|
||||
[/grid]
|
||||
[/column]
|
||||
[/row]
|
||||
[/grid]
|
||||
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
[spacer]
|
||||
width = 5
|
||||
[/spacer]
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
grow_factor = 0
|
||||
vertical_grow = true
|
||||
horizontal_grow = true
|
||||
|
||||
[panel]
|
||||
definition = box_display
|
||||
[grid]
|
||||
[row]
|
||||
[column]
|
||||
vertical_alignment = top
|
||||
[grid]
|
||||
[row]
|
||||
[column]
|
||||
border = "top,right,bottom"
|
||||
border_size = 5
|
||||
[spacer]
|
||||
width = 440
|
||||
[/spacer]
|
||||
[/column]
|
||||
[/row]
|
||||
[row]
|
||||
[column]
|
||||
horizontal_grow = true
|
||||
vertical_alignment = top
|
||||
border = "top,right,bottom"
|
||||
border_size = 5
|
||||
|
||||
[label]
|
||||
id = "current_dir"
|
||||
definition = "gold_small"
|
||||
wrap = false
|
||||
can_shrink = true
|
||||
[/label]
|
||||
|
||||
[/column]
|
||||
[/row]
|
||||
[row]
|
||||
[column]
|
||||
horizontal_grow = true
|
||||
vertical_alignment = top
|
||||
border = "top,right,bottom"
|
||||
border_size = 5
|
||||
|
||||
[listbox]
|
||||
id = "filelist"
|
||||
definition = "default"
|
||||
|
||||
[list_definition]
|
||||
|
||||
[row]
|
||||
|
||||
[column]
|
||||
vertical_grow = true
|
||||
horizontal_grow = true
|
||||
|
||||
[toggle_panel]
|
||||
# Needed for double-click event handling!
|
||||
id = "item_panel"
|
||||
definition = "default"
|
||||
|
||||
[grid]
|
||||
|
||||
[row]
|
||||
|
||||
[column]
|
||||
grow_factor = 0
|
||||
horizontal_alignment = "left"
|
||||
border = "top,bottom"
|
||||
border_size = 5
|
||||
|
||||
[image]
|
||||
id = "icon"
|
||||
definition = "default"
|
||||
linked_group = "fileview_icons"
|
||||
[/image]
|
||||
|
||||
[/column]
|
||||
|
||||
[column]
|
||||
grow_factor = 1
|
||||
horizontal_grow = true
|
||||
border = "all"
|
||||
border_size = 5
|
||||
|
||||
[label]
|
||||
id = "file"
|
||||
definition = "default"
|
||||
linked_group = "fileview_labels"
|
||||
[/label]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[/grid]
|
||||
|
||||
[/toggle_panel]
|
||||
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[/list_definition]
|
||||
|
||||
[/listbox]
|
||||
|
||||
[/column]
|
||||
[/row]
|
||||
[/grid]
|
||||
[/column]
|
||||
[/row]
|
||||
[/grid]
|
||||
[/panel]
|
||||
[/column]
|
||||
|
||||
[/row]
|
||||
|
||||
[/grid]
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
[menu]
|
||||
id=menu-editor-paste-context
|
||||
is_context_menu=true
|
||||
items=describeterrain,menu-unit-facing,editor-unit-toggle-loyal,editor-change-unitid,renameunit,describeunit,editor-deleteunit,editor-toggle-renameable,editor-toggle-canrecruit,editor-cut,editor-copy,editor-paste,editor-tool-select,editor-select-all,editor-select-inverse,editor-select-none,editor-clipboard-rotate-cw,editor-clipboard-rotate-ccw,editor-clipboard-flip-horizontal,editor-clipboard-flip-vertical,editor-selection-fill,editor-selection-rotate,editor-selection-flip,editor-selection-randomize,editor-save-area
|
||||
items=describeterrain,editor-change-unitid,renameunit,describeunit,editor-deleteunit,menu-unit-facing,editor-unit-toggle-loyal,editor-toggle-renameable,editor-toggle-canrecruit,editor-cut,editor-copy,editor-paste,editor-tool-select,editor-select-all,editor-select-inverse,editor-select-none,editor-clipboard-rotate-cw,editor-clipboard-rotate-ccw,editor-clipboard-flip-horizontal,editor-clipboard-flip-vertical,editor-selection-fill,editor-selection-rotate,editor-selection-flip,editor-selection-randomize,editor-save-area
|
||||
[/menu]
|
||||
|
||||
####### Menu Bar
|
||||
|
@ -61,7 +61,7 @@
|
|||
title= _ "File"
|
||||
type=turbo
|
||||
font_size=9
|
||||
items=editor-scenario-edit,statustable,unitlist,editor-map-new,editor-scenario-new,editor-map-load,menu-editor-recent,editor-map-revert,editor-map-save,editor-map-save-as,editor-scenario-save-as,mapscreenshot,editor-map-save-all,preferences,help,editor-close-map,quit,quit-to-desktop
|
||||
items=editor-map-new,editor-scenario-new,editor-scenario-edit,statustable,editor-map-load,menu-editor-recent,editor-map-revert,editor-map-save,editor-map-save-as,editor-scenario-save-as,mapscreenshot,editor-map-save-all,preferences,help,editor-close-map,quit,quit-to-desktop
|
||||
ref=top-panel
|
||||
rect="=,=+1,+100,+20"
|
||||
xanchor=fixed
|
||||
|
@ -109,7 +109,7 @@
|
|||
id=menu-editor-addon
|
||||
title= _ "Add-on"
|
||||
image=button_menu/menu_button_copper_H20
|
||||
items=editor-pbl, editor-addon-id
|
||||
items=editor-pbl, editor-addon-id, editor-addon-select, editor-addon-open
|
||||
rect="+0,=,+100,="
|
||||
xanchor=fixed
|
||||
yanchor=fixed
|
||||
|
@ -140,7 +140,7 @@
|
|||
id=menu-editor-unit
|
||||
title= _ "Unit"
|
||||
image=button_menu/menu_button_copper_H20
|
||||
items=editor-edit-unit
|
||||
items=unitlist,editor-edit-unit
|
||||
rect="+0,=,+100,="
|
||||
xanchor=fixed
|
||||
yanchor=fixed
|
||||
|
|
BIN
images/icons/action/preferences_25.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
images/icons/action/preview_25-active.png
Normal file
After Width: | Height: | Size: 952 B |
BIN
images/icons/action/preview_25-pressed.png
Normal file
After Width: | Height: | Size: 887 B |
BIN
images/icons/action/preview_25.png
Normal file
After Width: | Height: | Size: 878 B |
BIN
images/icons/action/preview_30-active.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
images/icons/action/preview_30-pressed.png
Normal file
After Width: | Height: | Size: 993 B |
BIN
images/icons/action/preview_30.png
Normal file
After Width: | Height: | Size: 991 B |
BIN
images/misc/file.png
Normal file
After Width: | Height: | Size: 659 B |
Before Width: | Height: | Size: 131 B After Width: | Height: | Size: 4.8 KiB |
|
@ -17,6 +17,8 @@
|
|||
|
||||
#include "editor/map/context_manager.hpp"
|
||||
|
||||
#include "desktop/open.hpp"
|
||||
|
||||
#include "editor/action/action.hpp"
|
||||
#include "editor/action/action_unit.hpp"
|
||||
#include "editor/action/action_select.hpp"
|
||||
|
@ -33,6 +35,7 @@
|
|||
#include "gui/dialogs/editor/edit_unit.hpp"
|
||||
#include "gui/dialogs/editor/custom_tod.hpp"
|
||||
#include "gui/dialogs/editor/tod_new_schedule.hpp"
|
||||
#include "gui/dialogs/file_dialog.hpp"
|
||||
#include "gui/dialogs/message.hpp"
|
||||
#include "gui/dialogs/preferences_dialog.hpp"
|
||||
#include "gui/dialogs/transient_message.hpp"
|
||||
|
@ -88,7 +91,6 @@ editor_controller::editor_controller(bool clear_id)
|
|||
toolkit_.reset(new editor_toolkit(*gui_.get(), key_, game_config_, *context_manager_.get()));
|
||||
help_manager_.reset(new help::help_manager(&game_config_));
|
||||
context_manager_->locs_ = toolkit_->get_palette_manager()->location_palette_.get();
|
||||
context_manager_->switch_context(0, true);
|
||||
init_tods(game_config_);
|
||||
init_music(game_config_);
|
||||
get_current_map_context().set_starting_position_labels(gui());
|
||||
|
@ -238,7 +240,7 @@ void editor_controller::custom_tods_dialog()
|
|||
tod_manager& manager = *get_current_map_context().get_time_manager();
|
||||
std::vector<time_of_day> prev_schedule = manager.times();
|
||||
|
||||
gui2::dialogs::custom_tod tod_dlg(manager.times(), manager.get_current_time());
|
||||
gui2::dialogs::custom_tod tod_dlg(manager.times(), manager.get_current_time(), current_addon_id_);
|
||||
|
||||
/* Register callback to the dialog so that the map changes can be
|
||||
* previewed in real time.
|
||||
|
@ -251,12 +253,12 @@ void editor_controller::custom_tods_dialog()
|
|||
tod_dlg.register_callback(update_func);
|
||||
|
||||
/* Autogenerate schedule id */
|
||||
// TODO : sch_name should be translatable
|
||||
std::int64_t current_millis = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||
std::string sch_id = current_addon_id_+"-schedule";
|
||||
std::string sch_name;
|
||||
/* Set correct textdomain */
|
||||
t_string sch_name("", "wesnoth-"+current_addon_id_);
|
||||
|
||||
// TODO : Needs better error handling
|
||||
// TODO : Needs better error handling messages
|
||||
/* Show dialog and update current schedule */
|
||||
if(tod_dlg.show()) {
|
||||
/* Save the new schedule */
|
||||
|
@ -359,8 +361,12 @@ bool editor_controller::can_execute_command(const hotkey::ui_command& cmd) const
|
|||
case HOTKEY_UNIT_LIST:
|
||||
return !get_current_map_context().units().empty();
|
||||
|
||||
// TODO Disabling this for now until the functionality can be implemnted.
|
||||
// See the status_table() method
|
||||
case HOTKEY_STATUS_TABLE:
|
||||
return !get_current_map_context().teams().empty();
|
||||
//return !get_current_map_context().teams().empty();
|
||||
return false;
|
||||
/////////////////////////////
|
||||
|
||||
case HOTKEY_TERRAIN_DESCRIPTION:
|
||||
return gui().mouseover_hex().valid();
|
||||
|
@ -380,29 +386,33 @@ bool editor_controller::can_execute_command(const hotkey::ui_command& cmd) const
|
|||
return (toolkit_->is_mouse_action_set(HOTKEY_EDITOR_TOOL_UNIT) &&
|
||||
units.find(loc) != units.end());
|
||||
}
|
||||
|
||||
case HOTKEY_UNDO:
|
||||
case HOTKEY_EDITOR_PARTIAL_UNDO:
|
||||
return get_current_map_context().can_undo();
|
||||
case HOTKEY_REDO:
|
||||
return get_current_map_context().can_redo();
|
||||
case HOTKEY_EDITOR_PARTIAL_UNDO:
|
||||
return get_current_map_context().can_undo();
|
||||
|
||||
case TITLE_SCREEN__RELOAD_WML:
|
||||
case HOTKEY_QUIT_TO_DESKTOP:
|
||||
case HOTKEY_EDITOR_MAP_NEW:
|
||||
case HOTKEY_EDITOR_SCENARIO_NEW:
|
||||
case HOTKEY_EDITOR_MAP_LOAD:
|
||||
case HOTKEY_EDITOR_MAP_SAVE_AS:
|
||||
case HOTKEY_EDITOR_SCENARIO_SAVE_AS:
|
||||
return true;
|
||||
|
||||
// Only enable when editing a scenario
|
||||
case HOTKEY_EDITOR_EDIT_UNIT:
|
||||
case HOTKEY_EDITOR_CUSTOM_TODS:
|
||||
case HOTKEY_EDITOR_SCENARIO_SAVE_AS:
|
||||
return !get_current_map_context().is_pure_map();
|
||||
|
||||
case HOTKEY_EDITOR_PBL:
|
||||
case HOTKEY_EDITOR_CHANGE_ADDON_ID:
|
||||
case HOTKEY_EDITOR_SELECT_ADDON:
|
||||
case HOTKEY_EDITOR_OPEN_ADDON:
|
||||
return true;
|
||||
|
||||
case HOTKEY_EDITOR_AREA_ADD:
|
||||
case HOTKEY_EDITOR_SIDE_NEW:
|
||||
return !get_current_map_context().is_pure_map();
|
||||
|
@ -802,7 +812,7 @@ bool editor_controller::do_execute_command(const hotkey::ui_command& cmd, bool p
|
|||
quit_confirmation::quit_to_desktop();
|
||||
return true;
|
||||
case TITLE_SCREEN__RELOAD_WML:
|
||||
context_manager_->save_all_maps(true);
|
||||
context_manager_->save_contexts();
|
||||
do_quit_ = true;
|
||||
quit_mode_ = EXIT_RELOAD_DATA;
|
||||
return true;
|
||||
|
@ -837,27 +847,54 @@ bool editor_controller::do_execute_command(const hotkey::ui_command& cmd, bool p
|
|||
return true;
|
||||
|
||||
case HOTKEY_EDITOR_PBL:
|
||||
if(current_addon_id_ == "") {
|
||||
current_addon_id_ = editor::initialize_addon();
|
||||
context_manager_->set_addon_id(current_addon_id_);
|
||||
}
|
||||
initialize_addon_if_empty();
|
||||
|
||||
if(current_addon_id_ != "") {
|
||||
if(!current_addon_id_.empty()) {
|
||||
context_manager_->edit_pbl();
|
||||
}
|
||||
return true;
|
||||
|
||||
case HOTKEY_EDITOR_CHANGE_ADDON_ID:
|
||||
if(current_addon_id_ == "") {
|
||||
current_addon_id_ = editor::initialize_addon();
|
||||
context_manager_->set_addon_id(current_addon_id_);
|
||||
}
|
||||
initialize_addon_if_empty();
|
||||
|
||||
if(current_addon_id_ != "") {
|
||||
if(!current_addon_id_.empty()) {
|
||||
context_manager_->change_addon_id();
|
||||
}
|
||||
return true;
|
||||
|
||||
case HOTKEY_EDITOR_SELECT_ADDON:
|
||||
current_addon_id_ = editor::initialize_addon();
|
||||
context_manager_->set_addon_id(current_addon_id_);
|
||||
return true;
|
||||
|
||||
case HOTKEY_EDITOR_OPEN_ADDON:
|
||||
{
|
||||
initialize_addon_if_empty();
|
||||
|
||||
gui2::dialogs::file_dialog dlg;
|
||||
|
||||
dlg.set_title(_("Add-on Files"))
|
||||
.set_path(filesystem::get_current_editor_dir(current_addon_id_));
|
||||
|
||||
if (dlg.show()) {
|
||||
std::string filepath = dlg.path();
|
||||
if (filepath.substr(filepath.size() - 4) == ".map"
|
||||
|| filepath.substr(filepath.size() - 4) == ".cfg") {
|
||||
// Open map or scenario
|
||||
context_manager_->load_map(filepath, true);
|
||||
} else {
|
||||
// Open file using OS application for that format
|
||||
if (desktop::open_object_is_supported()) {
|
||||
desktop::open_object(filepath);
|
||||
} else {
|
||||
gui2::show_message("", _("Opening files is not supported, contact your packager"), gui2::dialogs::message::auto_close);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
case HOTKEY_EDITOR_AREA_ADD:
|
||||
add_area();
|
||||
return true;
|
||||
|
@ -884,6 +921,14 @@ bool editor_controller::do_execute_command(const hotkey::ui_command& cmd, bool p
|
|||
un->anim_comp().set_standing();
|
||||
}
|
||||
return true;
|
||||
case HOTKEY_EDITOR_UNIT_TOGGLE_LOYAL:
|
||||
{
|
||||
map_location loc = gui_->mouseover_hex();
|
||||
const unit_map::unit_iterator un = get_current_map_context().units().find(loc);
|
||||
bool loyal = un->loyal();
|
||||
un->set_loyal(!loyal);
|
||||
}
|
||||
return true;
|
||||
case HOTKEY_DELETE_UNIT:
|
||||
{
|
||||
map_location loc = gui_->mouseover_hex();
|
||||
|
@ -994,12 +1039,9 @@ bool editor_controller::do_execute_command(const hotkey::ui_command& cmd, bool p
|
|||
context_manager_->new_map_dialog();
|
||||
return true;
|
||||
case HOTKEY_EDITOR_SCENARIO_NEW:
|
||||
if(current_addon_id_ == "") {
|
||||
current_addon_id_ = editor::initialize_addon();
|
||||
context_manager_->set_addon_id(current_addon_id_);
|
||||
}
|
||||
initialize_addon_if_empty();
|
||||
|
||||
if(current_addon_id_ != "") {
|
||||
if(!current_addon_id_.empty()) {
|
||||
context_manager_->new_scenario_dialog();
|
||||
}
|
||||
return true;
|
||||
|
@ -1013,12 +1055,9 @@ bool editor_controller::do_execute_command(const hotkey::ui_command& cmd, bool p
|
|||
context_manager_->save_map_as_dialog();
|
||||
return true;
|
||||
case HOTKEY_EDITOR_SCENARIO_SAVE_AS:
|
||||
if(current_addon_id_ == "") {
|
||||
current_addon_id_ = editor::initialize_addon();
|
||||
context_manager_->set_addon_id(current_addon_id_);
|
||||
}
|
||||
initialize_addon_if_empty();
|
||||
|
||||
if(current_addon_id_ != "") {
|
||||
if(!current_addon_id_.empty()) {
|
||||
context_manager_->save_scenario_as_dialog();
|
||||
}
|
||||
return true;
|
||||
|
@ -1109,6 +1148,13 @@ bool editor_controller::do_execute_command(const hotkey::ui_command& cmd, bool p
|
|||
}
|
||||
}
|
||||
|
||||
void editor_controller::initialize_addon_if_empty() {
|
||||
if(current_addon_id_.empty()) {
|
||||
current_addon_id_ = editor::initialize_addon();
|
||||
}
|
||||
context_manager_->set_addon_id(current_addon_id_);
|
||||
}
|
||||
|
||||
void editor_controller::show_help()
|
||||
{
|
||||
help::show_help("..editor");
|
||||
|
|
|
@ -65,10 +65,7 @@ class editor_controller : public controller_base,
|
|||
editor_controller& operator=(const editor_controller&) = delete;
|
||||
|
||||
/**
|
||||
* The constructor. A initial map context can be specified here, the controller
|
||||
* will assume ownership and delete the pointer during destruction, but changes
|
||||
* to the map can be retrieved between the main loop's end and the controller's
|
||||
* destruction.
|
||||
* The constructor.
|
||||
*/
|
||||
editor_controller(bool clear_id);
|
||||
|
||||
|
@ -165,6 +162,9 @@ class editor_controller : public controller_base,
|
|||
return context_manager_->get_map_context();
|
||||
}
|
||||
|
||||
/** Initialize an addon if the addon id is empty */
|
||||
void initialize_addon_if_empty();
|
||||
|
||||
protected:
|
||||
/* controller_base overrides */
|
||||
void process_keyup_event(const SDL_Event& event) override;
|
||||
|
|
|
@ -118,7 +118,7 @@ EXIT_STATUS start(bool clear_id, const std::string& filename, bool take_screensh
|
|||
|
||||
editor_controller editor(clear_id);
|
||||
|
||||
if (!filename.empty() && filesystem::file_exists (filename)) {
|
||||
if (!filename.empty() && filesystem::file_exists(filename)) {
|
||||
if (filesystem::is_directory(filename)) {
|
||||
editor.context_manager_->set_default_dir(filename);
|
||||
editor.context_manager_->load_map_dialog(true);
|
||||
|
@ -126,8 +126,7 @@ EXIT_STATUS start(bool clear_id, const std::string& filename, bool take_screensh
|
|||
editor.context_manager_->load_map(filename, false);
|
||||
|
||||
// HACK: this fixes an issue where the button overlays would be missing when
|
||||
// the loaded map appears. Since we're gonna drop this ridiculous GUI1 drawing
|
||||
// stuff in 1.15 I'm not going to waste time coming up with a better fix.
|
||||
// the loaded map appears.
|
||||
//
|
||||
// Do note adding a redraw_everything call to context_manager::refresh_all also
|
||||
// fixes the issue, but I'm pretty sure thats just because editor_controller::
|
||||
|
|
|
@ -52,12 +52,14 @@
|
|||
|
||||
#include <memory>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace editor {
|
||||
namespace {
|
||||
|
||||
static std::vector<std::string> saved_windows_;
|
||||
std::vector<std::unique_ptr<editor::map_context>> saved_contexts_;
|
||||
int last_context_ = 0;
|
||||
|
||||
static const std::string get_menu_marker(const bool changed)
|
||||
const std::string get_menu_marker(const bool changed)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << "[<span ";
|
||||
|
@ -70,11 +72,15 @@ static const std::string get_menu_marker(const bool changed)
|
|||
return ss.str();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace editor {
|
||||
|
||||
context_manager::context_manager(editor_display& gui, const game_config_view& game_config, const std::string& addon_id)
|
||||
: locs_(nullptr)
|
||||
, gui_(gui)
|
||||
, game_config_(game_config)
|
||||
, default_dir_(prefs::get().default_dir())
|
||||
, default_dir_(filesystem::get_dir(filesystem::get_legacy_editor_dir()))
|
||||
, current_addon_(addon_id)
|
||||
, map_generators_()
|
||||
, last_map_generator_(nullptr)
|
||||
|
@ -84,11 +90,6 @@ context_manager::context_manager(editor_display& gui, const game_config_view& ga
|
|||
, clipboard_()
|
||||
{
|
||||
resources::filter_con = this;
|
||||
|
||||
if(default_dir_.empty()) {
|
||||
default_dir_ = filesystem::get_dir(filesystem::get_user_data_dir() + "/editor");
|
||||
}
|
||||
|
||||
create_default_context();
|
||||
init_map_generators(game_config);
|
||||
}
|
||||
|
@ -207,7 +208,7 @@ void context_manager::load_map_dialog(bool force_same_context /* = false */)
|
|||
{
|
||||
std::string fn = get_map_context().get_filename();
|
||||
if(fn.empty()) {
|
||||
fn = filesystem::get_legacy_editor_dir()+"/maps";
|
||||
fn = filesystem::get_current_editor_dir(current_addon_) +"/maps";
|
||||
}
|
||||
|
||||
gui2::dialogs::file_dialog dlg;
|
||||
|
@ -243,7 +244,7 @@ void context_manager::edit_side_dialog(int side_index)
|
|||
|
||||
void context_manager::edit_pbl()
|
||||
{
|
||||
if(current_addon_ != "") {
|
||||
if(!current_addon_.empty()) {
|
||||
std::string pbl = filesystem::get_current_editor_dir(current_addon_) + "/_server.pbl";
|
||||
gui2::dialogs::editor_edit_pbl::execute(pbl, current_addon_);
|
||||
}
|
||||
|
@ -266,7 +267,7 @@ void context_manager::change_addon_id()
|
|||
|
||||
current_addon_ = new_addon_id;
|
||||
|
||||
for(context_ptr& context : map_contexts_) {
|
||||
for(std::unique_ptr<map_context>& context : map_contexts_) {
|
||||
context->set_addon_id(current_addon_);
|
||||
}
|
||||
}
|
||||
|
@ -673,9 +674,11 @@ void context_manager::resize_map_dialog()
|
|||
|
||||
void context_manager::save_map_as_dialog()
|
||||
{
|
||||
bool first_pick = false;
|
||||
std::string input_name = get_map_context().get_filename();
|
||||
if(input_name.empty()) {
|
||||
input_name = filesystem::get_legacy_editor_dir()+"/maps";
|
||||
first_pick = true;
|
||||
input_name = filesystem::get_current_editor_dir(editor_controller::current_addon_id_)+"/maps";
|
||||
}
|
||||
|
||||
gui2::dialogs::file_dialog dlg;
|
||||
|
@ -683,20 +686,35 @@ void context_manager::save_map_as_dialog()
|
|||
dlg.set_title(_("Save Map As"))
|
||||
.set_save_mode(true)
|
||||
.set_path(input_name)
|
||||
.set_extension(".map");
|
||||
.set_extension(".map")
|
||||
.set_extension(".mask");
|
||||
|
||||
if(!dlg.show()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::size_t is_open = check_open_map(dlg.path());
|
||||
boost::filesystem::path save_path(dlg.path());
|
||||
|
||||
// Show warning the first time user tries to save in a wrong folder
|
||||
std::string last_folder = save_path.parent_path().filename().string();
|
||||
if ((last_folder == "scenarios")
|
||||
&& first_pick
|
||||
&& (gui2::show_message(
|
||||
_("Error"),
|
||||
VGETTEXT("Do you really want to save $type1 in $type2 folder?", {{"type1", "map"}, {"type2", "scenarios"}}),
|
||||
gui2::dialogs::message::yes_no_buttons) != gui2::retval::OK))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::size_t is_open = check_open_map(save_path.string());
|
||||
if(is_open < map_contexts_.size() && is_open != static_cast<unsigned>(current_context_index_)) {
|
||||
gui2::show_transient_message(_("This map is already open."), dlg.path());
|
||||
gui2::show_transient_message(_("This map is already open."), save_path.string());
|
||||
}
|
||||
|
||||
std::string old_filename = get_map_context().get_filename();
|
||||
|
||||
get_map_context().set_filename(dlg.path());
|
||||
get_map_context().set_filename(save_path.string());
|
||||
|
||||
if(!write_map(true)) {
|
||||
get_map_context().set_filename(old_filename);
|
||||
|
@ -705,9 +723,11 @@ void context_manager::save_map_as_dialog()
|
|||
|
||||
void context_manager::save_scenario_as_dialog()
|
||||
{
|
||||
bool first_pick = false;
|
||||
std::string input_name = get_map_context().get_filename();
|
||||
if(input_name.empty()) {
|
||||
input_name = filesystem::get_legacy_editor_dir()+"/scenarios";
|
||||
first_pick = true;
|
||||
input_name = filesystem::get_current_editor_dir(editor_controller::current_addon_id_) + "/scenarios";
|
||||
}
|
||||
|
||||
gui2::dialogs::file_dialog dlg;
|
||||
|
@ -722,15 +742,29 @@ void context_manager::save_scenario_as_dialog()
|
|||
return;
|
||||
}
|
||||
|
||||
std::size_t is_open = check_open_map(dlg.path());
|
||||
boost::filesystem::path save_path(dlg.path());
|
||||
|
||||
// Show warning the first time user tries to save in a wrong folder
|
||||
std::string last_folder = save_path.parent_path().filename().string();
|
||||
if ((last_folder == "maps")
|
||||
&& first_pick
|
||||
&& (gui2::show_message(
|
||||
_("Error"),
|
||||
VGETTEXT("Do you really want to save $type1 in $type2 folder?", {{"type1", "scenario"}, {"type2", "maps"}}),
|
||||
gui2::dialogs::message::yes_no_buttons) != gui2::retval::OK))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::size_t is_open = check_open_map(save_path.string());
|
||||
if(is_open < map_contexts_.size() && is_open != static_cast<unsigned>(current_context_index_)) {
|
||||
gui2::show_transient_message(_("This scenario is already open."), dlg.path());
|
||||
gui2::show_transient_message(_("This scenario is already open."), save_path.string());
|
||||
return;
|
||||
}
|
||||
|
||||
std::string old_filename = get_map_context().get_filename();
|
||||
|
||||
get_map_context().set_filename(dlg.path());
|
||||
get_map_context().set_filename(save_path.string());
|
||||
|
||||
if(!write_scenario(true)) {
|
||||
get_map_context().set_filename(old_filename);
|
||||
|
@ -804,34 +838,25 @@ void context_manager::fill_selection()
|
|||
perform_refresh(editor_action_paint_area(get_map_context().map().selection(), get_selected_bg_terrain()));
|
||||
}
|
||||
|
||||
void context_manager::save_all_maps(bool auto_save_windows)
|
||||
void context_manager::save_all_maps()
|
||||
{
|
||||
int current = current_context_index_;
|
||||
saved_windows_.clear();
|
||||
for(std::size_t i = 0; i < map_contexts_.size(); ++i) {
|
||||
switch_context(i);
|
||||
std::string name = get_map_context().get_filename();
|
||||
if(auto_save_windows) {
|
||||
if(name.empty() || filesystem::is_directory(name)) {
|
||||
std::ostringstream s;
|
||||
s << default_dir_ << "/" << "window_" << i + 1;
|
||||
if(!get_map_context().is_embedded() && !get_map_context().is_pure_map()) {
|
||||
s << ".cfg";
|
||||
} else {
|
||||
s << ".map";
|
||||
}
|
||||
name = s.str();
|
||||
get_map_context().set_filename(name);
|
||||
}
|
||||
}
|
||||
saved_windows_.push_back(name);
|
||||
save_map();
|
||||
}
|
||||
|
||||
switch_context(current);
|
||||
}
|
||||
|
||||
void context_manager::save_map()
|
||||
void context_manager::save_contexts()
|
||||
{
|
||||
saved_contexts_.swap(map_contexts_);
|
||||
std::swap(last_context_, current_context_index_);
|
||||
create_blank_context();
|
||||
switch_context(0, true);
|
||||
}
|
||||
|
||||
void context_manager::save_map(bool show_confirmation)
|
||||
{
|
||||
const std::string& name = get_map_context().get_filename();
|
||||
if(name.empty() || filesystem::is_directory(name)) {
|
||||
|
@ -842,9 +867,9 @@ void context_manager::save_map()
|
|||
}
|
||||
} else {
|
||||
if(get_map_context().is_pure_map()) {
|
||||
write_map();
|
||||
write_map(show_confirmation);
|
||||
} else {
|
||||
write_scenario();
|
||||
write_scenario(show_confirmation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -908,17 +933,17 @@ void context_manager::load_map(const std::string& filename, bool new_context)
|
|||
}
|
||||
|
||||
if(filesystem::ends_with(filename, ".cfg")) {
|
||||
if(editor_controller::current_addon_id_ == "") {
|
||||
if(editor_controller::current_addon_id_.empty()) {
|
||||
// if no addon id has been set and the file being loaded is from an addon
|
||||
// then use the file path to determine the addon rather than showing a dialog
|
||||
editor_controller::current_addon_id_ = filesystem::get_addon_id_from_path(filename);
|
||||
if(editor_controller::current_addon_id_ == "") {
|
||||
if(editor_controller::current_addon_id_.empty()) {
|
||||
editor_controller::current_addon_id_ = editor::initialize_addon();
|
||||
}
|
||||
set_addon_id(editor_controller::current_addon_id_);
|
||||
}
|
||||
|
||||
if(editor_controller::current_addon_id_ == "") {
|
||||
if(editor_controller::current_addon_id_.empty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -926,7 +951,7 @@ void context_manager::load_map(const std::string& filename, bool new_context)
|
|||
LOG_ED << "Load map: " << filename << (new_context ? " (new)" : " (same)");
|
||||
try {
|
||||
{
|
||||
context_ptr mc(new map_context(game_config_, filename, current_addon_));
|
||||
auto mc = std::make_unique<map_context>(game_config_, filename, current_addon_);
|
||||
if(mc->get_filename() != filename) {
|
||||
if(new_context && check_switch_open_map(mc->get_filename())) {
|
||||
return;
|
||||
|
@ -1009,11 +1034,11 @@ void context_manager::new_scenario(int width, int height, const t_translation::t
|
|||
template<typename... T>
|
||||
int context_manager::add_map_context(const T&... args)
|
||||
{
|
||||
map_contexts_.emplace_back(new map_context(args...));
|
||||
map_contexts_.emplace_back(std::make_unique<map_context>(args...));
|
||||
return map_contexts_.size() - 1;
|
||||
}
|
||||
|
||||
int context_manager::add_map_context_of(context_ptr&& mc)
|
||||
int context_manager::add_map_context_of(std::unique_ptr<map_context>&& mc)
|
||||
{
|
||||
map_contexts_.emplace_back(std::move(mc));
|
||||
return map_contexts_.size() - 1;
|
||||
|
@ -1022,11 +1047,10 @@ int context_manager::add_map_context_of(context_ptr&& mc)
|
|||
template<typename... T>
|
||||
void context_manager::replace_map_context(const T&... args)
|
||||
{
|
||||
context_ptr new_mc(new map_context(args...));
|
||||
replace_map_context_with(std::move(new_mc));
|
||||
replace_map_context_with(std::move(std::make_unique<map_context>(args...)));
|
||||
}
|
||||
|
||||
void context_manager::replace_map_context_with(context_ptr&& mc)
|
||||
void context_manager::replace_map_context_with(std::unique_ptr<map_context>&& mc)
|
||||
{
|
||||
map_contexts_[current_context_index_].swap(mc);
|
||||
refresh_on_context_change();
|
||||
|
@ -1034,19 +1058,23 @@ void context_manager::replace_map_context_with(context_ptr&& mc)
|
|||
|
||||
void context_manager::create_default_context()
|
||||
{
|
||||
if(saved_windows_.empty()) {
|
||||
t_translation::terrain_code default_terrain =
|
||||
if(saved_contexts_.empty()) {
|
||||
create_blank_context();
|
||||
switch_context(0, true);
|
||||
} else {
|
||||
saved_contexts_.swap(map_contexts_);
|
||||
switch_context(last_context_, true);
|
||||
last_context_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void context_manager::create_blank_context()
|
||||
{
|
||||
t_translation::terrain_code default_terrain =
|
||||
t_translation::read_terrain_code(game_config::default_terrain);
|
||||
|
||||
const config& default_schedule = game_config_.find_mandatory_child("editor_times", "id", "empty");
|
||||
add_map_context(editor_map(44, 33, default_terrain), true, default_schedule, current_addon_);
|
||||
} else {
|
||||
for(const std::string& filename : saved_windows_) {
|
||||
add_map_context(game_config_, filename, current_addon_);
|
||||
}
|
||||
|
||||
saved_windows_.clear();
|
||||
}
|
||||
const config& default_schedule = game_config_.find_mandatory_child("editor_times", "id", "empty");
|
||||
add_map_context(editor_map(44, 33, default_terrain), true, default_schedule, current_addon_);
|
||||
}
|
||||
|
||||
void context_manager::close_current_context()
|
||||
|
|
|
@ -29,8 +29,6 @@ namespace editor
|
|||
class context_manager : public filter_context
|
||||
{
|
||||
public:
|
||||
using context_ptr = std::unique_ptr<map_context>;
|
||||
|
||||
context_manager(editor_display& gui, const game_config_view& game_config, const std::string& addon_id);
|
||||
~context_manager();
|
||||
|
||||
|
@ -75,15 +73,15 @@ public:
|
|||
*/
|
||||
void perform_refresh(const editor_action& action, bool drag_part = false);
|
||||
|
||||
/**
|
||||
* Save all maps, open dialog if not named yet, except when using
|
||||
* auto_save_windows which will name unnamed maps "windows_N".
|
||||
* Also record all filenames for future reopening.
|
||||
*/
|
||||
void save_all_maps(bool auto_save_windows = false);
|
||||
|
||||
/** Save all open map_contexts to memory */
|
||||
void save_contexts();
|
||||
|
||||
/** Save all maps, show save dialogs for unsaved ones */
|
||||
void save_all_maps();
|
||||
|
||||
/** Save the map, open dialog if not named yet. */
|
||||
void save_map();
|
||||
void save_map(bool show_confirmation = true);
|
||||
|
||||
editor_display& gui()
|
||||
{
|
||||
|
@ -229,7 +227,7 @@ private:
|
|||
template<typename... T>
|
||||
int add_map_context(const T&... args);
|
||||
|
||||
int add_map_context_of(context_ptr&& mc);
|
||||
int add_map_context_of(std::unique_ptr<map_context>&& mc);
|
||||
|
||||
/**
|
||||
* Replace the current map context and refresh accordingly
|
||||
|
@ -237,14 +235,16 @@ private:
|
|||
template<typename... T>
|
||||
void replace_map_context(const T&... args);
|
||||
|
||||
void replace_map_context_with(context_ptr&& mc);
|
||||
void replace_map_context_with(std::unique_ptr<map_context>&& mc);
|
||||
|
||||
/**
|
||||
* Creates a default map context object, used to ensure there is always at least one.
|
||||
* Except when we saved windows, in which case reopen them
|
||||
* When we have saved contexts, reopen them instead.
|
||||
*/
|
||||
void create_default_context();
|
||||
|
||||
void create_blank_context();
|
||||
|
||||
/** Performs the necessary housekeeping necessary when switching contexts. */
|
||||
void refresh_on_context_change();
|
||||
|
||||
|
@ -266,8 +266,8 @@ private:
|
|||
* Save the map under a given filename. Displays an error message on failure.
|
||||
* @return true on success
|
||||
*/
|
||||
bool write_map(bool display_confirmation = false);
|
||||
bool write_scenario(bool display_confirmation = false);
|
||||
bool write_map(bool display_confirmation = true);
|
||||
bool write_scenario(bool display_confirmation = true);
|
||||
|
||||
/**
|
||||
* Create a new map.
|
||||
|
@ -335,7 +335,7 @@ private:
|
|||
int auto_update_transitions_;
|
||||
|
||||
/** The currently opened map context object */
|
||||
std::vector<context_ptr> map_contexts_;
|
||||
std::vector<std::unique_ptr<map_context>> map_contexts_;
|
||||
|
||||
/** Clipboard map_fragment -- used for copy-paste. */
|
||||
map_fragment clipboard_;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "formula/string_utils.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "gui/dialogs/message.hpp"
|
||||
#include "gui/dialogs/transient_message.hpp"
|
||||
#include "map/label.hpp"
|
||||
#include "preferences/preferences.hpp"
|
||||
#include "serialization/binary_or_text.hpp"
|
||||
|
@ -723,6 +724,10 @@ config map_context::to_config()
|
|||
}
|
||||
|
||||
// [unit]s
|
||||
config traits;
|
||||
preproc_map traits_map;
|
||||
read(traits, *(preprocess_file(game_config::path+"/data/core/macros/traits.cfg", &traits_map)));
|
||||
|
||||
for(const auto& unit : units_) {
|
||||
config& u = event.add_child("unit");
|
||||
|
||||
|
@ -744,6 +749,15 @@ config map_context::to_config()
|
|||
if(unit.unrenamable()) {
|
||||
u["unrenamable"] = unit.unrenamable();
|
||||
}
|
||||
|
||||
if(unit.loyal()) {
|
||||
config trait_loyal;
|
||||
read(trait_loyal, traits_map["TRAIT_LOYAL"].value);
|
||||
u.append(trait_loyal);
|
||||
}
|
||||
//TODO this entire block could also be replaced by unit.write(u, true)
|
||||
//however, the resultant config is massive and contains many attributes we don't need.
|
||||
//need to find a middle ground here.
|
||||
}
|
||||
|
||||
// [side]s
|
||||
|
@ -800,8 +814,7 @@ void map_context::save_schedule(const std::string& schedule_id, const std::strin
|
|||
} catch(const filesystem::io_exception& e) {
|
||||
utils::string_map symbols;
|
||||
symbols["msg"] = e.what();
|
||||
//TODO : Needs to be replaced with a better message later.
|
||||
const std::string msg = VGETTEXT("Could not save the scenario: $msg", symbols);
|
||||
const std::string msg = VGETTEXT("Could not save time schedule: $msg", symbols);
|
||||
throw editor_map_save_exception(msg);
|
||||
}
|
||||
|
||||
|
@ -820,6 +833,7 @@ void map_context::save_schedule(const std::string& schedule_id, const std::strin
|
|||
std::stringstream wml_stream;
|
||||
|
||||
wml_stream
|
||||
<< "#textdomain " << current_textdomain << "\n"
|
||||
<< "#\n"
|
||||
<< "# This file was generated using the scenario editor.\n"
|
||||
<< "#\n"
|
||||
|
@ -834,14 +848,13 @@ void map_context::save_schedule(const std::string& schedule_id, const std::strin
|
|||
|
||||
if(!wml_stream.str().empty()) {
|
||||
filesystem::write_file(schedule_path, wml_stream.str());
|
||||
gui2::show_transient_message("", _("Time schedule saved."));
|
||||
}
|
||||
|
||||
} catch(const filesystem::io_exception& e) {
|
||||
utils::string_map symbols;
|
||||
symbols["msg"] = e.what();
|
||||
//TODO : Needs to be replaced with a better message later.
|
||||
const std::string msg = VGETTEXT("Could not save the scenario: $msg", symbols);
|
||||
|
||||
const std::string msg = VGETTEXT("Could not save time schedule: $msg", symbols);
|
||||
throw editor_map_save_exception(msg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -447,7 +447,7 @@ protected:
|
|||
void perform_action_between_stacks(action_stack& from, action_stack& to);
|
||||
|
||||
/**
|
||||
* The undo stack. A double-ended queues due to the need to add items to one end,
|
||||
* The undo stack. A double-ended queue due to the need to add items to one end,
|
||||
* and remove from both when performing the undo or when trimming the size. This container owns
|
||||
* all contents, i.e. no action in the stack shall be deleted, and unless otherwise noted the contents
|
||||
* could be deleted at an time during normal operation of the stack. To work on an action, either
|
||||
|
|
|
@ -1467,6 +1467,41 @@ std::string normalize_path(const std::string& fpath, bool normalize_separators,
|
|||
}
|
||||
}
|
||||
|
||||
bool to_asset_path(std::string& path, std::string addon_id, std::string asset_type)
|
||||
{
|
||||
std::string rel_path = "";
|
||||
std::string core_asset_dir = get_dir(game_config::path + "/data/core/" + asset_type);
|
||||
std::string addon_asset_dir;
|
||||
|
||||
bool found = false;
|
||||
bool is_in_core_dir = (path.find(core_asset_dir) != std::string::npos);
|
||||
bool is_in_addon_dir = false;
|
||||
|
||||
if (is_in_core_dir) {
|
||||
rel_path = path.erase(0, core_asset_dir.size()+1);
|
||||
found = true;
|
||||
} else if (!addon_id.empty()) {
|
||||
addon_asset_dir = get_current_editor_dir(addon_id) + "/" + asset_type;
|
||||
is_in_addon_dir = (path.find(addon_asset_dir) != std::string::npos);
|
||||
if (is_in_addon_dir) {
|
||||
rel_path = path.erase(0, addon_asset_dir.size()+1);
|
||||
found = true;
|
||||
} else {
|
||||
// Not found in either core or addons dirs,
|
||||
// return a possible path where the asset could be copied.
|
||||
std::string filename = boost::filesystem::path(path).filename().string();
|
||||
std::string asset_path = addon_asset_dir + "/" + filename;
|
||||
rel_path = filename;
|
||||
found = false;
|
||||
}
|
||||
} else {
|
||||
found = false;
|
||||
}
|
||||
|
||||
path = rel_path;
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* The paths manager is responsible for recording the various paths
|
||||
* that binary files may be located at.
|
||||
|
|
|
@ -345,6 +345,11 @@ std::string normalize_path(const std::string& path,
|
|||
bool normalize_separators = false,
|
||||
bool resolve_dot_entries = false);
|
||||
|
||||
/** Helper function to convert absolute path to wesnoth relative path */
|
||||
bool to_asset_path(std::string& abs_path,
|
||||
std::string addon_id,
|
||||
std::string asset_type);
|
||||
|
||||
/**
|
||||
* Sanitizes a path to remove references to the user's name.
|
||||
*/
|
||||
|
|
|
@ -24,13 +24,16 @@
|
|||
#include "gettext.hpp"
|
||||
#include "gui/auxiliary/field.hpp"
|
||||
#include "gui/dialogs/file_dialog.hpp"
|
||||
#include "gui/dialogs/message.hpp"
|
||||
#include "gui/widgets/button.hpp"
|
||||
#include "gui/widgets/image.hpp"
|
||||
#include "gui/widgets/label.hpp"
|
||||
#include "gui/widgets/slider.hpp"
|
||||
#include "gui/widgets/text_box.hpp"
|
||||
#include "sound.hpp"
|
||||
|
||||
#include <functional>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace gui2::dialogs
|
||||
{
|
||||
|
@ -55,8 +58,9 @@ static custom_tod::string_pair tod_getter_sound(const time_of_day& tod)
|
|||
|
||||
REGISTER_DIALOG(custom_tod)
|
||||
|
||||
custom_tod::custom_tod(const std::vector<time_of_day>& times, int current_time)
|
||||
custom_tod::custom_tod(const std::vector<time_of_day>& times, int current_time, const std::string addon_id)
|
||||
: modal_dialog(window_id())
|
||||
, addon_id_(addon_id)
|
||||
, times_(times)
|
||||
, current_tod_(current_time)
|
||||
, color_field_r_(register_integer("tod_red", true))
|
||||
|
@ -82,12 +86,10 @@ void custom_tod::pre_show(window& window)
|
|||
window.add_to_tab_order(find_widget<text_box>(&window, "tod_id", false, true));
|
||||
|
||||
for(const auto& data : metadata_stuff) {
|
||||
find_widget<text_box>(&window, "path_" + data.first, false).set_active(false);
|
||||
|
||||
button& copy_w = find_widget<button>(&window, "copy_" + data.first, false);
|
||||
|
||||
connect_signal_mouse_left_click(copy_w,
|
||||
std::bind(&custom_tod::copy_to_clipboard_callback, this, data.second));
|
||||
std::bind(&custom_tod::copy_to_clipboard_callback, this, data));
|
||||
|
||||
if(!desktop::clipboard::available()) {
|
||||
copy_w.set_active(false);
|
||||
|
@ -107,6 +109,18 @@ void custom_tod::pre_show(window& window)
|
|||
find_widget<button>(&window, "browse_sound", false),
|
||||
std::bind(&custom_tod::select_file<tod_getter_sound>, this, "data/core/sounds/ambient"));
|
||||
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&window, "preview_image", false),
|
||||
std::bind(&custom_tod::update_image, this, "image"));
|
||||
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&window, "preview_mask", false),
|
||||
std::bind(&custom_tod::update_image, this, "mask"));
|
||||
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&window, "preview_sound", false),
|
||||
std::bind(&custom_tod::play_sound, this));
|
||||
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&window, "next_tod", false),
|
||||
std::bind(&custom_tod::do_next_tod, this));
|
||||
|
@ -124,7 +138,7 @@ void custom_tod::pre_show(window& window)
|
|||
std::bind(&custom_tod::do_delete_tod, this));
|
||||
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&window, "preview", false),
|
||||
find_widget<button>(&window, "preview_color", false),
|
||||
std::bind(&custom_tod::preview_schedule, this));
|
||||
|
||||
connect_signal_notify_modified(
|
||||
|
@ -166,12 +180,29 @@ void custom_tod::select_file(const std::string& default_dir)
|
|||
|
||||
if(dlg.show()) {
|
||||
dn = dlg.path();
|
||||
const std::string& message
|
||||
= _("This file is outside Wesnoth's data dirs. Do you wish to copy it into your add-on?");
|
||||
|
||||
if(data.first == "image") {
|
||||
if (!filesystem::to_asset_path(dn, addon_id_, "images")) {
|
||||
if(gui2::show_message(_("Confirm"), message, message::yes_no_buttons) == gui2::retval::OK) {
|
||||
filesystem::copy_file(dlg.path(), dn);
|
||||
}
|
||||
}
|
||||
times_[current_tod_].image = dn;
|
||||
} else if(data.first == "mask") {
|
||||
if (!filesystem::to_asset_path(dn, addon_id_, "images")) {
|
||||
if(gui2::show_message(_("Confirm"), message, message::yes_no_buttons) == gui2::retval::OK) {
|
||||
filesystem::copy_file(dlg.path(), dn);
|
||||
}
|
||||
}
|
||||
times_[current_tod_].image_mask = dn;
|
||||
} else if(data.first == "sound") {
|
||||
if (!filesystem::to_asset_path(dn, addon_id_, "sounds")) {
|
||||
if(gui2::show_message(_("Confirm"), message, message::yes_no_buttons) == gui2::retval::OK) {
|
||||
filesystem::copy_file(dlg.path(), dn);
|
||||
}
|
||||
}
|
||||
times_[current_tod_].sounds = dn;
|
||||
}
|
||||
}
|
||||
|
@ -243,6 +274,18 @@ void custom_tod::color_slider_callback(COLOR_TYPE type)
|
|||
update_tod_display();
|
||||
}
|
||||
|
||||
void custom_tod::play_sound() {
|
||||
std::string sound_path = find_widget<text_box>(get_window(), "path_sound", false).get_value();
|
||||
sound::play_sound(sound_path, sound::SOUND_SOURCES);
|
||||
}
|
||||
|
||||
void custom_tod::update_image(const std::string& id_stem) {
|
||||
std::string img_path = find_widget<text_box>(get_window(), "path_"+id_stem, false).get_value();
|
||||
find_widget<image>(get_window(), "current_tod_" + id_stem, false).set_label(img_path);
|
||||
|
||||
get_window()->invalidate_layout();
|
||||
}
|
||||
|
||||
void custom_tod::update_tod_display()
|
||||
{
|
||||
display* disp = display::get_singleton();
|
||||
|
@ -251,8 +294,7 @@ void custom_tod::update_tod_display()
|
|||
// The display handles invaliding whatever tiles need invalidating.
|
||||
disp->update_tod(&get_selected_tod());
|
||||
|
||||
// NOTE: revert to invalidate_layout if necessary to display the ToD mask image.
|
||||
get_window()->queue_redraw();
|
||||
get_window()->invalidate_layout();
|
||||
}
|
||||
|
||||
void custom_tod::update_lawful_bonus()
|
||||
|
@ -287,9 +329,12 @@ void custom_tod::update_selected_tod_info()
|
|||
update_tod_display();
|
||||
}
|
||||
|
||||
void custom_tod::copy_to_clipboard_callback(tod_attribute_getter getter)
|
||||
void custom_tod::copy_to_clipboard_callback(std::pair<std::string, tod_attribute_getter> data)
|
||||
{
|
||||
auto& [type, getter] = data;
|
||||
button& copy_w = find_widget<button>(get_window(), "copy_" + type, false);
|
||||
desktop::clipboard::copy_to_clipboard(getter(get_selected_tod()).second, false);
|
||||
copy_w.set_success(true);
|
||||
}
|
||||
|
||||
/** Quickly preview the schedule changes and color */
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace dialogs
|
|||
class custom_tod : public modal_dialog
|
||||
{
|
||||
public:
|
||||
custom_tod(const std::vector<time_of_day>& times, int current_time);
|
||||
custom_tod(const std::vector<time_of_day>& times, int current_time, const std::string addon_id = "");
|
||||
|
||||
/** The execute function. See @ref modal_dialog for more information. */
|
||||
DEFINE_SIMPLE_EXECUTE_WRAPPER(custom_tod)
|
||||
|
@ -82,15 +82,24 @@ private:
|
|||
|
||||
void update_selected_tod_info();
|
||||
|
||||
void copy_to_clipboard_callback(tod_attribute_getter getter);
|
||||
void copy_to_clipboard_callback(std::pair<std::string, tod_attribute_getter> data);
|
||||
|
||||
/** Update current TOD with values from the GUI */
|
||||
void update_schedule();
|
||||
|
||||
/** Available time_of_days */
|
||||
/** Update image when preview is pressed */
|
||||
void update_image(const std::string& id_stem);
|
||||
|
||||
/** Play sound when play is pressed */
|
||||
void play_sound();
|
||||
|
||||
/** ID of the current addon. The schedule file will be saved here. */
|
||||
const std::string addon_id_;
|
||||
|
||||
/** Available time of days */
|
||||
std::vector<time_of_day> times_;
|
||||
|
||||
/** Current ToD index */
|
||||
/** Current time of day (ToD) index */
|
||||
int current_tod_;
|
||||
|
||||
field_integer* color_field_r_;
|
||||
|
|
|
@ -22,29 +22,32 @@
|
|||
#include "filesystem.hpp"
|
||||
#include "formula/string_utils.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "units/types.hpp"
|
||||
#include "gui/dialogs/unit_create.hpp"
|
||||
#include "gui/auxiliary/find_widget.hpp"
|
||||
#include "gui/dialogs/file_dialog.hpp"
|
||||
#include "gui/dialogs/message.hpp"
|
||||
#include "gui/dialogs/unit_create.hpp"
|
||||
#include "gui/dialogs/transient_message.hpp"
|
||||
#include "gui/widgets/button.hpp"
|
||||
#include "gui/widgets/image.hpp"
|
||||
#include "gui/widgets/scroll_label.hpp"
|
||||
#include "gui/widgets/spinner.hpp"
|
||||
#include "gui/widgets/label.hpp"
|
||||
#include "gui/widgets/listbox.hpp"
|
||||
#include "gui/widgets/menu_button.hpp"
|
||||
#include "gui/widgets/scroll_text.hpp"
|
||||
#include "gui/widgets/multimenu_button.hpp"
|
||||
#include "gui/widgets/scroll_label.hpp"
|
||||
#include "gui/widgets/scroll_text.hpp"
|
||||
#include "gui/widgets/slider.hpp"
|
||||
#include "gui/widgets/stacked_widget.hpp"
|
||||
#include "gui/widgets/spinner.hpp"
|
||||
#include "gui/widgets/tab_container.hpp"
|
||||
#include "gui/widgets/text_box.hpp"
|
||||
#include "gui/widgets/toggle_button.hpp"
|
||||
#include "gui/auxiliary/find_widget.hpp"
|
||||
#include "picture.hpp"
|
||||
#include "serialization/binary_or_text.hpp"
|
||||
#include "serialization/parser.hpp"
|
||||
#include "serialization/preprocessor.hpp"
|
||||
#include "units/types.hpp"
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <sstream>
|
||||
|
||||
namespace gui2::dialogs
|
||||
|
@ -66,7 +69,7 @@ editor_edit_unit::editor_edit_unit(const game_config_view& game_config, const st
|
|||
|
||||
read(specials, *(preprocess_file(game_config::path+"/data/core/macros/abilities.cfg", &abilities_map_)));
|
||||
for (const auto& x : abilities_map_) {
|
||||
/** Don't add any macros that have INTERNAL */
|
||||
// Don't add any macros that have INTERNAL
|
||||
if (x.first.find("INTERNAL") == std::string::npos) {
|
||||
abilities_list_.emplace_back("label", x.first, "checkbox", false);
|
||||
}
|
||||
|
@ -77,6 +80,15 @@ editor_edit_unit::editor_edit_unit(const game_config_view& game_config, const st
|
|||
}
|
||||
|
||||
void editor_edit_unit::pre_show(window& win) {
|
||||
tab_container& tabs = find_widget<tab_container>(&win, "tabs", false);
|
||||
connect_signal_notify_modified(tabs, std::bind(&editor_edit_unit::on_page_select, this));
|
||||
|
||||
//
|
||||
// Main Stats tab
|
||||
//
|
||||
|
||||
tabs.select_tab(0);
|
||||
|
||||
menu_button& alignments = find_widget<menu_button>(&win, "alignment_list", false);
|
||||
// TODO:change alignments to existing translatable strings
|
||||
align_list_.emplace_back("label", _("lawful"));
|
||||
|
@ -95,6 +107,42 @@ void editor_edit_unit::pre_show(window& win) {
|
|||
races.set_values(race_list_);
|
||||
}
|
||||
|
||||
button& load = find_widget<button>(&win, "load_unit_type", false);
|
||||
std::stringstream tooltip;
|
||||
tooltip << vgettext_impl("wesnoth", "Hotkey(s): ", {{}});
|
||||
#ifdef __APPLE__
|
||||
tooltip << "cmd+o";
|
||||
#else
|
||||
tooltip << "ctrl+o";
|
||||
#endif
|
||||
load.set_tooltip(tooltip.str());
|
||||
connect_signal_mouse_left_click(load, std::bind(&editor_edit_unit::load_unit_type, this));
|
||||
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&win, "browse_unit_image", false),
|
||||
std::bind(&editor_edit_unit::select_file, this, "data/core/images/units", "unit_image"));
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&win, "preview_unit_image", false),
|
||||
std::bind(&editor_edit_unit::update_image, this, "unit_image"));
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&win, "browse_portrait_image", false),
|
||||
std::bind(&editor_edit_unit::select_file, this, "data/core/images/portraits", "portrait_image"));
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&win, "preview_portrait_image", false),
|
||||
std::bind(&editor_edit_unit::update_image, this, "portrait_image"));
|
||||
|
||||
connect_signal_notify_modified(
|
||||
find_widget<text_box>(&win, "name_box", false),
|
||||
std::bind(&editor_edit_unit::button_state_change, this));
|
||||
connect_signal_notify_modified(
|
||||
find_widget<text_box>(&win, "id_box", false),
|
||||
std::bind(&editor_edit_unit::button_state_change, this));
|
||||
|
||||
//
|
||||
// Advanced Tab
|
||||
//
|
||||
tabs.select_tab(1);
|
||||
|
||||
menu_button& movetypes = find_widget<menu_button>(&win, "movetype_list", false);
|
||||
for(const auto& mt : unit_types.movement_types()) {
|
||||
movetype_list_.emplace_back("label", mt.first);
|
||||
|
@ -125,7 +173,6 @@ void editor_edit_unit::pre_show(window& win) {
|
|||
}
|
||||
|
||||
menu_button& resistances = find_widget<menu_button>(&win, "resistances_list", false);
|
||||
menu_button& attack_types = find_widget<menu_button>(&win, "attack_type_list", false);
|
||||
|
||||
const config& resistances_attr = game_config_
|
||||
.mandatory_child("units")
|
||||
|
@ -137,7 +184,6 @@ void editor_edit_unit::pre_show(window& win) {
|
|||
|
||||
if (resistances_list_.size() > 0) {
|
||||
resistances.set_values(resistances_list_);
|
||||
attack_types.set_values(resistances_list_);
|
||||
res_toggles_.resize(resistances_list_.size());
|
||||
}
|
||||
|
||||
|
@ -149,57 +195,18 @@ void editor_edit_unit::pre_show(window& win) {
|
|||
usage_type_list_.emplace_back("label", _("healer"));
|
||||
usage_types.set_values(usage_type_list_);
|
||||
|
||||
multimenu_button& specials = find_widget<multimenu_button>(&win, "weapon_specials_list", false);
|
||||
specials.set_values(specials_list_);
|
||||
multimenu_button& abilities = find_widget<multimenu_button>(&win, "abilities_list", false);
|
||||
abilities.set_values(abilities_list_);
|
||||
|
||||
group<std::string> range_group;
|
||||
range_group.add_member(find_widget<toggle_button>(&win, "range_melee", false, true), "melee");
|
||||
range_group.add_member(find_widget<toggle_button>(&win, "range_ranged", false, true), "ranged");
|
||||
range_group.set_member_states("melee");
|
||||
|
||||
// Connect signals
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&win, "browse_unit_image", false),
|
||||
std::bind(&editor_edit_unit::select_file, this, "data/core/images/units", "unit_image"));
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&win, "preview_unit_image", false),
|
||||
std::bind(&editor_edit_unit::update_image, this, "unit_image"));
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&win, "browse_portrait_image", false),
|
||||
std::bind(&editor_edit_unit::select_file, this, "data/core/images/portraits", "portrait_image"));
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&win, "preview_portrait_image", false),
|
||||
std::bind(&editor_edit_unit::update_image, this, "portrait_image"));
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&win, "browse_small_profile_image", false),
|
||||
std::bind(&editor_edit_unit::select_file, this, "data/core/images/portraits", "small_profile_image"));
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&win, "preview_small_profile_image", false),
|
||||
std::bind(&editor_edit_unit::update_image, this, "small_profile_image"));
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&win, "browse_attack_image", false),
|
||||
std::bind(&editor_edit_unit::select_file, this, "data/core/images/attacks", "attack_image"));
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&win, "preview_attack_image", false),
|
||||
std::bind(&editor_edit_unit::update_image, this, "attack_image"));
|
||||
|
||||
button& load = find_widget<button>(&win, "load_unit_type", false);
|
||||
connect_signal_mouse_left_click(load, std::bind(&editor_edit_unit::load_unit_type, this));
|
||||
std::stringstream tooltip;
|
||||
tooltip << vgettext_impl("wesnoth", "Hotkey(s): ", {{}});
|
||||
#ifdef __APPLE__
|
||||
tooltip << "cmd+o";
|
||||
#else
|
||||
tooltip << "ctrl+o";
|
||||
#endif
|
||||
load.set_tooltip(tooltip.str());
|
||||
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&win, "load_movetype", false),
|
||||
std::bind(&editor_edit_unit::load_movetype, this));
|
||||
|
||||
connect_signal_notify_modified(
|
||||
find_widget<slider>(&win, "resistances_slider", false),
|
||||
std::bind(&editor_edit_unit::store_resistances, this));
|
||||
|
@ -235,28 +242,39 @@ void editor_edit_unit::pre_show(window& win) {
|
|||
}
|
||||
|
||||
if (!def_toggles_.empty()) {
|
||||
enable_defense_slider();
|
||||
enable_defense_slider();
|
||||
}
|
||||
|
||||
if (!move_toggles_.empty()) {
|
||||
enable_movement_slider();
|
||||
enable_movement_slider();
|
||||
}
|
||||
|
||||
//
|
||||
// Attack Tab
|
||||
//
|
||||
tabs.select_tab(2);
|
||||
multimenu_button& specials = find_widget<multimenu_button>(&win, "weapon_specials_list", false);
|
||||
specials.set_values(specials_list_);
|
||||
group<std::string> range_group;
|
||||
range_group.add_member(find_widget<toggle_button>(&win, "range_melee", false, true), "melee");
|
||||
range_group.add_member(find_widget<toggle_button>(&win, "range_ranged", false, true), "ranged");
|
||||
range_group.set_member_states("melee");
|
||||
|
||||
menu_button& attack_types = find_widget<menu_button>(&win, "attack_type_list", false);
|
||||
if (resistances_list_.size() > 0) {
|
||||
attack_types.set_values(resistances_list_);
|
||||
}
|
||||
|
||||
// Connect signals
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&win, "browse_attack_image", false),
|
||||
std::bind(&editor_edit_unit::select_file, this, "data/core/images/attacks", "attack_image"));
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&win, "preview_attack_image", false),
|
||||
std::bind(&editor_edit_unit::update_image, this, "attack_image"));
|
||||
connect_signal_notify_modified(
|
||||
find_widget<menu_button>(&win, "atk_list", false),
|
||||
std::bind(&editor_edit_unit::select_attack, this));
|
||||
|
||||
connect_signal_notify_modified(
|
||||
find_widget<text_box>(&win, "name_box", false),
|
||||
std::bind(&editor_edit_unit::button_state_change, this));
|
||||
connect_signal_notify_modified(
|
||||
find_widget<text_box>(&win, "id_box", false),
|
||||
std::bind(&editor_edit_unit::button_state_change, this));
|
||||
|
||||
// Disable OK button at start, since ID and Name boxes are empty
|
||||
button_state_change();
|
||||
|
||||
// Attack page
|
||||
connect_signal_mouse_left_click(
|
||||
find_widget<button>(&win, "atk_new", false),
|
||||
std::bind(&editor_edit_unit::add_attack, this));
|
||||
|
@ -272,31 +290,20 @@ void editor_edit_unit::pre_show(window& win) {
|
|||
|
||||
update_index();
|
||||
|
||||
// Setup tabs
|
||||
listbox& selector = find_widget<listbox>(&win, "tabs", false);
|
||||
connect_signal_notify_modified(selector,
|
||||
std::bind(&editor_edit_unit::on_page_select, this));
|
||||
stacked_widget& page = find_widget<stacked_widget>(&win, "page", false);
|
||||
win.keyboard_capture(&selector);
|
||||
tabs.select_tab(0);
|
||||
|
||||
int main_index = 0;
|
||||
selector.select_row(main_index);
|
||||
page.select_layer(main_index);
|
||||
// Disable OK button at start, since ID and Name boxes are empty
|
||||
button_state_change();
|
||||
}
|
||||
|
||||
void editor_edit_unit::on_page_select()
|
||||
{
|
||||
save_unit_type();
|
||||
|
||||
const int selected_row =
|
||||
std::max(0, find_widget<listbox>(get_window(), "tabs", false).get_selected_row());
|
||||
find_widget<stacked_widget>(get_window(), "page", false).select_layer(static_cast<unsigned int>(selected_row));
|
||||
|
||||
if (selected_row == 3) {
|
||||
tab_container& tabs = find_widget<tab_container>(get_window(), "tabs", false);
|
||||
if (tabs.get_active_tab_index() == 3) {
|
||||
update_wml_view();
|
||||
}
|
||||
|
||||
get_window()->invalidate_layout();
|
||||
}
|
||||
|
||||
void editor_edit_unit::select_file(const std::string& default_dir, const std::string& id_stem)
|
||||
|
@ -309,46 +316,37 @@ void editor_edit_unit::select_file(const std::string& default_dir, const std::st
|
|||
|
||||
if (dlg.show()) {
|
||||
|
||||
/* Convert absolute path to wesnoth relative path */
|
||||
std::string images_dir = filesystem::get_core_images_dir();
|
||||
std::string addons_dir = filesystem::get_current_editor_dir(addon_id_) + "/images";
|
||||
std::stringstream path;
|
||||
std::string dn = dlg.path();
|
||||
const std::string& message
|
||||
= _("This file is outside Wesnoth's data dirs. Do you wish to copy it into your add-on?");
|
||||
|
||||
if ((dlg.path().find(images_dir) == std::string::npos)
|
||||
&& (dlg.path().find(addons_dir) == std::string::npos)) {
|
||||
/* choosen file is outside wesnoth's images dir,
|
||||
* copy image to addons directory */
|
||||
std::string filename = boost::filesystem::path(dlg.path()).filename().string();
|
||||
if(id_stem == "unit_image") {
|
||||
|
||||
if (id_stem == "unit_image") {
|
||||
path << addons_dir + "/units/" + filename;
|
||||
} else if ((id_stem == "portrait_image")||(id_stem == "small_profile_image")) {
|
||||
path << addons_dir + "/portraits/" + filename;
|
||||
} else if (id_stem == "attack_image") {
|
||||
path << addons_dir + "/attacks/" + filename;
|
||||
if (!filesystem::to_asset_path(dn, addon_id_, "images")) {
|
||||
if(gui2::show_message(_("Confirm"), message, message::yes_no_buttons) == gui2::retval::OK) {
|
||||
filesystem::copy_file(dlg.path(), dn);
|
||||
}
|
||||
}
|
||||
|
||||
} else if((id_stem == "portrait_image")||(id_stem == "small_profile_image")) {
|
||||
|
||||
if (!filesystem::to_asset_path(dn, addon_id_, "images")) {
|
||||
if(gui2::show_message(_("Confirm"), message, message::yes_no_buttons) == gui2::retval::OK) {
|
||||
filesystem::copy_file(dlg.path(), dn);
|
||||
}
|
||||
}
|
||||
|
||||
} else if(id_stem == "attack_image") {
|
||||
|
||||
if (!filesystem::to_asset_path(dn, addon_id_, "images")) {
|
||||
if(gui2::show_message(_("Confirm"), message, message::yes_no_buttons) == gui2::retval::OK) {
|
||||
filesystem::copy_file(dlg.path(), dn);
|
||||
}
|
||||
}
|
||||
|
||||
filesystem::copy_file(dlg.path(), path.str());
|
||||
} else {
|
||||
path << dlg.path();
|
||||
}
|
||||
|
||||
if (path.str().find(images_dir) != std::string::npos) {
|
||||
// Image in Wesnoth core dir
|
||||
path.str(path.str().replace(0, images_dir.size()+1, ""));
|
||||
} else if (path.str().find(addons_dir) != std::string::npos) {
|
||||
// Image in addons dir
|
||||
path.str(path.str().replace(0, addons_dir.size()+1, ""));
|
||||
}
|
||||
|
||||
path.seekp(0, std::ios_base::end);
|
||||
|
||||
unsigned size = 200; // TODO: Arbitrary, can be changed later.
|
||||
if (check_big(dlg.path(), size)) {
|
||||
path << "~SCALE(" << size << "," << size << ")";
|
||||
}
|
||||
|
||||
find_widget<text_box>(get_window(), "path_"+id_stem, false).set_value(path.str());
|
||||
find_widget<text_box>(get_window(), "path_"+id_stem, false).set_value(dn);
|
||||
update_image(id_stem);
|
||||
}
|
||||
}
|
||||
|
@ -358,8 +356,9 @@ void editor_edit_unit::load_unit_type() {
|
|||
if (dlg_uc.show()) {
|
||||
const unit_type *type = unit_types.find(dlg_uc.choice());
|
||||
|
||||
stacked_widget& page = find_widget<stacked_widget>(get_window(), "page", false);
|
||||
page.select_layer(0);
|
||||
tab_container& tabs = find_widget<tab_container>(get_window(), "tabs", false);
|
||||
tabs.select_tab(0);
|
||||
|
||||
find_widget<text_box>(get_window(), "id_box", false).set_value(type->id());
|
||||
find_widget<text_box>(get_window(), "name_box", false).set_value(type->type_name().base_str());
|
||||
find_widget<spinner>(get_window(), "level_box", false).set_value(type->level());
|
||||
|
@ -396,7 +395,7 @@ void editor_edit_unit::load_unit_type() {
|
|||
|
||||
update_image("unit_image");
|
||||
|
||||
page.select_layer(1);
|
||||
tabs.select_tab(1);
|
||||
find_widget<text_box>(get_window(), "path_small_profile_image", false).set_value(type->small_profile());
|
||||
|
||||
set_selected_from_string(
|
||||
|
@ -452,7 +451,7 @@ void editor_edit_unit::load_unit_type() {
|
|||
|
||||
update_image("small_profile_image");
|
||||
|
||||
page.select_layer(2);
|
||||
tabs.select_tab(2);
|
||||
attacks_.clear();
|
||||
for(const auto& atk : type->attacks())
|
||||
{
|
||||
|
@ -472,9 +471,10 @@ void editor_edit_unit::load_unit_type() {
|
|||
update_attacks();
|
||||
update_index();
|
||||
|
||||
page.select_layer(0);
|
||||
tabs.select_tab(0);
|
||||
|
||||
button_state_change();
|
||||
get_window()->invalidate_layout();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,45 +486,46 @@ void editor_edit_unit::save_unit_type() {
|
|||
// Textdomain
|
||||
std::string current_textdomain = "wesnoth-"+addon_id_;
|
||||
|
||||
stacked_widget& page = find_widget<stacked_widget>(get_window(), "page", false);
|
||||
tab_container& tabs = find_widget<tab_container>(get_window(), "tabs", false);
|
||||
|
||||
// Page 1
|
||||
page.select_layer(0);
|
||||
grid* grid = tabs.get_tab_grid(0);
|
||||
|
||||
|
||||
config& utype = type_cfg_.add_child("unit_type");
|
||||
utype["id"] = find_widget<text_box>(get_window(), "id_box", false).get_value();
|
||||
utype["name"] = t_string(find_widget<text_box>(get_window(), "name_box", false).get_value(), current_textdomain);
|
||||
utype["image"] = find_widget<text_box>(get_window(), "path_unit_image", false).get_value();
|
||||
utype["profile"] = find_widget<text_box>(get_window(), "path_portrait_image", false).get_value();
|
||||
utype["level"] = find_widget<spinner>(get_window(), "level_box", false).get_value();
|
||||
utype["advances_to"] = find_widget<text_box>(get_window(), "adv_box", false).get_value();
|
||||
utype["hitpoints"] = find_widget<slider>(get_window(), "hp_slider", false).get_value();
|
||||
utype["experience"] = find_widget<slider>(get_window(), "xp_slider", false).get_value();
|
||||
utype["cost"] = find_widget<slider>(get_window(), "cost_slider", false).get_value();
|
||||
utype["movement"] = find_widget<slider>(get_window(), "move_slider", false).get_value();
|
||||
utype["description"] = t_string(find_widget<scroll_text>(get_window(), "desc_box", false).get_value(), current_textdomain);
|
||||
utype["race"] = find_widget<menu_button>(get_window(), "race_list", false).get_value_string();
|
||||
utype["alignment"] = find_widget<menu_button>(get_window(), "alignment_list", false).get_value_string();
|
||||
utype["id"] = find_widget<text_box>(grid, "id_box", false).get_value();
|
||||
utype["name"] = t_string(find_widget<text_box>(grid, "name_box", false).get_value(), current_textdomain);
|
||||
utype["image"] = find_widget<text_box>(grid, "path_unit_image", false).get_value();
|
||||
utype["profile"] = find_widget<text_box>(grid, "path_portrait_image", false).get_value();
|
||||
utype["level"] = find_widget<spinner>(grid, "level_box", false).get_value();
|
||||
utype["advances_to"] = find_widget<text_box>(grid, "adv_box", false).get_value();
|
||||
utype["hitpoints"] = find_widget<slider>(grid, "hp_slider", false).get_value();
|
||||
utype["experience"] = find_widget<slider>(grid, "xp_slider", false).get_value();
|
||||
utype["cost"] = find_widget<slider>(grid, "cost_slider", false).get_value();
|
||||
utype["movement"] = find_widget<slider>(grid, "move_slider", false).get_value();
|
||||
utype["description"] = t_string(find_widget<scroll_text>(grid, "desc_box", false).get_value(), current_textdomain);
|
||||
utype["race"] = find_widget<menu_button>(grid, "race_list", false).get_value_string();
|
||||
utype["alignment"] = find_widget<menu_button>(grid, "alignment_list", false).get_value_string();
|
||||
|
||||
// Gender
|
||||
if (find_widget<toggle_button>(get_window(), "gender_male", false).get_value()) {
|
||||
if (find_widget<toggle_button>(get_window(), "gender_female", false).get_value()) {
|
||||
if (find_widget<toggle_button>(grid, "gender_male", false).get_value()) {
|
||||
if (find_widget<toggle_button>(grid, "gender_female", false).get_value()) {
|
||||
utype["gender"] = "male,female";
|
||||
} else {
|
||||
utype["gender"] = "male";
|
||||
}
|
||||
} else {
|
||||
if (find_widget<toggle_button>(get_window(), "gender_female", false).get_value()) {
|
||||
if (find_widget<toggle_button>(grid, "gender_female", false).get_value()) {
|
||||
utype["gender"] = "female";
|
||||
}
|
||||
}
|
||||
|
||||
// Page 2
|
||||
page.select_layer(1);
|
||||
grid = tabs.get_tab_grid(1);
|
||||
|
||||
utype["small_profile"] = find_widget<text_box>(get_window(), "path_small_profile_image", false).get_value();
|
||||
utype["movement_type"] = find_widget<menu_button>(get_window(), "movetype_list", false).get_value_string();
|
||||
utype["usage"] = find_widget<menu_button>(get_window(), "usage_list", false).get_value_string();
|
||||
utype["small_profile"] = find_widget<text_box>(grid, "path_small_profile_image", false).get_value();
|
||||
utype["movement_type"] = find_widget<menu_button>(grid, "movetype_list", false).get_value_string();
|
||||
utype["usage"] = find_widget<menu_button>(grid, "usage_list", false).get_value_string();
|
||||
|
||||
if (res_toggles_.any()) {
|
||||
config& resistances = utype.add_child("resistance");
|
||||
|
@ -559,7 +560,7 @@ void editor_edit_unit::save_unit_type() {
|
|||
}
|
||||
}
|
||||
|
||||
const auto& abilities_states = find_widget<multimenu_button>(get_window(), "abilities_list", false).get_toggle_states();
|
||||
const auto& abilities_states = find_widget<multimenu_button>(grid, "abilities_list", false).get_toggle_states();
|
||||
if (abilities_states.any()) {
|
||||
unsigned int i = 0;
|
||||
sel_abilities_.clear();
|
||||
|
@ -658,8 +659,10 @@ void editor_edit_unit::store_attack() {
|
|||
}
|
||||
|
||||
config& attack = attacks_.at(selected_attack_-1).second;
|
||||
stacked_widget& page = find_widget<stacked_widget>(get_window(), "page", false);
|
||||
page.select_layer(2);
|
||||
|
||||
tab_container& tabs = find_widget<tab_container>(get_window(), "tabs", false);
|
||||
int prev_tab = tabs.get_active_tab_index();
|
||||
tabs.select_tab(2);
|
||||
|
||||
attack["name"] = find_widget<text_box>(get_window(), "atk_id_box", false).get_value();
|
||||
attack["description"] = t_string(find_widget<text_box>(get_window(), "atk_name_box", false).get_value(), current_textdomain);
|
||||
|
@ -675,14 +678,17 @@ void editor_edit_unit::store_attack() {
|
|||
}
|
||||
|
||||
attacks_.at(selected_attack_-1).first = find_widget<multimenu_button>(get_window(), "weapon_specials_list", false).get_toggle_states();
|
||||
|
||||
tabs.select_tab(prev_tab);
|
||||
}
|
||||
|
||||
void editor_edit_unit::update_attacks() {
|
||||
//Load data
|
||||
config& attack = attacks_.at(selected_attack_-1).second;
|
||||
|
||||
stacked_widget& page = find_widget<stacked_widget>(get_window(), "page", false);
|
||||
page.select_layer(2);
|
||||
tab_container& tabs = find_widget<tab_container>(get_window(), "tabs", false);
|
||||
int prev_tab = tabs.get_active_tab_index();
|
||||
tabs.select_tab(2);
|
||||
|
||||
find_widget<text_box>(get_window(), "atk_id_box", false).set_value(attack["name"]);
|
||||
find_widget<text_box>(get_window(), "atk_name_box", false).set_value(attack["description"]);
|
||||
|
@ -707,9 +713,15 @@ void editor_edit_unit::update_attacks() {
|
|||
|
||||
find_widget<multimenu_button>(get_window(), "weapon_specials_list", false)
|
||||
.select_options(attacks_.at(selected_attack_-1).first);
|
||||
|
||||
tabs.select_tab(prev_tab);
|
||||
}
|
||||
|
||||
void editor_edit_unit::update_index() {
|
||||
tab_container& tabs = find_widget<tab_container>(get_window(), "tabs", false);
|
||||
int prev_tab = tabs.get_active_tab_index();
|
||||
tabs.select_tab(2);
|
||||
|
||||
if (selected_attack_ <= 1) {
|
||||
find_widget<button>(get_window(), "atk_prev", false).set_active(false);
|
||||
} else {
|
||||
|
@ -741,16 +753,20 @@ void editor_edit_unit::update_index() {
|
|||
//Set index
|
||||
const std::string new_index_str = formatter() << selected_attack_ << "/" << attacks_.size();
|
||||
find_widget<label>(get_window(), "atk_number", false).set_label(new_index_str);
|
||||
|
||||
tabs.select_tab(prev_tab);
|
||||
}
|
||||
|
||||
void editor_edit_unit::add_attack() {
|
||||
// Textdomain
|
||||
std::string current_textdomain = "wesnoth-"+addon_id_;
|
||||
|
||||
tab_container& tabs = find_widget<tab_container>(get_window(), "tabs", false);
|
||||
int prev_tab = tabs.get_active_tab_index();
|
||||
tabs.select_tab(2);
|
||||
|
||||
config attack;
|
||||
|
||||
stacked_widget& page = find_widget<stacked_widget>(get_window(), "page", false);
|
||||
page.select_layer(2);
|
||||
attack["name"] = find_widget<text_box>(get_window(), "atk_id_box", false).get_value();
|
||||
attack["description"] = t_string(find_widget<text_box>(get_window(), "atk_name_box", false).get_value(), current_textdomain);
|
||||
attack["icon"] = find_widget<text_box>(get_window(), "path_attack_image", false).get_value();
|
||||
|
@ -772,9 +788,15 @@ void editor_edit_unit::add_attack() {
|
|||
, attack));
|
||||
|
||||
update_index();
|
||||
|
||||
tabs.select_tab(prev_tab);
|
||||
}
|
||||
|
||||
void editor_edit_unit::delete_attack() {
|
||||
tab_container& tabs = find_widget<tab_container>(get_window(), "tabs", false);
|
||||
int prev_tab = tabs.get_active_tab_index();
|
||||
tabs.select_tab(2);
|
||||
|
||||
//remove attack
|
||||
if (attacks_.size() > 0) {
|
||||
attacks_.erase(attacks_.begin() + selected_attack_ - 1);
|
||||
|
@ -796,6 +818,8 @@ void editor_edit_unit::delete_attack() {
|
|||
}
|
||||
|
||||
update_index();
|
||||
|
||||
tabs.select_tab(prev_tab);
|
||||
}
|
||||
|
||||
void editor_edit_unit::next_attack() {
|
||||
|
@ -829,7 +853,12 @@ void editor_edit_unit::select_attack() {
|
|||
update_index();
|
||||
}
|
||||
|
||||
//TODO Check if works with non-mainline movetypes
|
||||
void editor_edit_unit::load_movetype() {
|
||||
tab_container& tabs = find_widget<tab_container>(get_window(), "tabs", false);
|
||||
int prev_tab = tabs.get_active_tab_index();
|
||||
tabs.select_tab(1);
|
||||
|
||||
for(const auto& movetype : game_config_
|
||||
.mandatory_child("units")
|
||||
.child_range("movetype")) {
|
||||
|
@ -845,6 +874,8 @@ void editor_edit_unit::load_movetype() {
|
|||
update_movement_costs();
|
||||
}
|
||||
}
|
||||
|
||||
tabs.select_tab(prev_tab);
|
||||
}
|
||||
|
||||
void editor_edit_unit::write_macro(std::ostream& out, unsigned level, const std::string macro_name)
|
||||
|
@ -860,8 +891,8 @@ void editor_edit_unit::update_wml_view() {
|
|||
store_attack();
|
||||
save_unit_type();
|
||||
|
||||
stacked_widget& page = find_widget<stacked_widget>(get_window(), "page", false);
|
||||
page.select_layer(3);
|
||||
tab_container& tabs = find_widget<tab_container>(get_window(), "tabs", false);
|
||||
tabs.select_tab(3);
|
||||
|
||||
std::stringstream wml_stream;
|
||||
|
||||
|
@ -987,20 +1018,22 @@ void editor_edit_unit::update_image(const std::string& id_stem) {
|
|||
rel_path = rel_path.substr(0, rel_path.find("~"));
|
||||
}
|
||||
|
||||
std::string abs_path = filesystem::get_binary_file_location("images", rel_path);
|
||||
|
||||
std::stringstream mod_path(rel_path);
|
||||
mod_path.seekp(0, std::ios_base::end);
|
||||
unsigned size = 200; // TODO: Arbitrary, can be changed later.
|
||||
if ((abs_path.size() > 0) && check_big(abs_path, size)) {
|
||||
mod_path << "~SCALE(" << size << "," << size << ")";
|
||||
int scale_size = 200; // TODO: Arbitrary, can be changed later.
|
||||
if (rel_path.size() > 0) {
|
||||
point img_size = ::image::get_size(::image::locator{rel_path});
|
||||
float aspect_ratio = static_cast<float>(img_size.x)/img_size.y;
|
||||
if(img_size.x > scale_size) {
|
||||
rel_path.append("~SCALE(" + std::to_string(scale_size) + "," + std::to_string(scale_size*aspect_ratio) + ")");
|
||||
} else if (img_size.y > scale_size) {
|
||||
rel_path.append("~SCALE(" + std::to_string(scale_size/aspect_ratio) + "," + std::to_string(scale_size) + ")");
|
||||
}
|
||||
}
|
||||
|
||||
if (id_stem == "portrait_image") {
|
||||
// portrait image uses same [image] as unit_image
|
||||
find_widget<image>(get_window(), "unit_image", false).set_label(mod_path.str());
|
||||
find_widget<image>(get_window(), "unit_image", false).set_label(rel_path);
|
||||
} else {
|
||||
find_widget<image>(get_window(), id_stem, false).set_label(mod_path.str());
|
||||
find_widget<image>(get_window(), id_stem, false).set_label(rel_path);
|
||||
}
|
||||
|
||||
get_window()->invalidate_layout();
|
||||
|
@ -1010,7 +1043,7 @@ void editor_edit_unit::update_image(const std::string& id_stem) {
|
|||
bool editor_edit_unit::check_id(std::string id) {
|
||||
for(char c : id) {
|
||||
if (!(std::isalnum(c) || c == '_' || c == ' ')) {
|
||||
/* One bad char means entire id string is invalid */
|
||||
// One bad char means entire id string is invalid
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1018,8 +1051,11 @@ bool editor_edit_unit::check_id(std::string id) {
|
|||
}
|
||||
|
||||
void editor_edit_unit::button_state_change() {
|
||||
std::string id = find_widget<text_box>(get_window(), "id_box", false).get_value();
|
||||
std::string name = find_widget<text_box>(get_window(), "name_box", false).get_value();
|
||||
tab_container& tabs = find_widget<tab_container>(get_window(), "tabs", false);
|
||||
|
||||
std::string id = find_widget<text_box>(tabs.get_tab_grid(0), "id_box", false).get_value();
|
||||
std::string name = find_widget<text_box>(tabs.get_tab_grid(0), "name_box", false).get_value();
|
||||
|
||||
if (
|
||||
id.empty()
|
||||
|| name.empty()
|
||||
|
@ -1033,13 +1069,6 @@ void editor_edit_unit::button_state_change() {
|
|||
get_window()->queue_redraw();
|
||||
}
|
||||
|
||||
void editor_edit_unit::button_state_change_id() {
|
||||
std::string id = find_widget<text_box>(get_window(), "id_box", false).get_value();
|
||||
find_widget<button>(get_window(), "ok", false).set_active( !id.empty() || check_id(id) );
|
||||
|
||||
get_window()->queue_redraw();
|
||||
}
|
||||
|
||||
void editor_edit_unit::write() {
|
||||
// Write the file
|
||||
update_wml_view();
|
||||
|
@ -1053,8 +1082,9 @@ void editor_edit_unit::write() {
|
|||
// Write to file
|
||||
try {
|
||||
filesystem::write_file(unit_path, generated_wml);
|
||||
} catch(const filesystem::io_exception& /*e*/) {
|
||||
// TODO : Needs an error message
|
||||
gui2::show_transient_message("", _("Unit type saved."));
|
||||
} catch(const filesystem::io_exception& e) {
|
||||
gui2::show_transient_message("", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,8 +22,6 @@
|
|||
#include "serialization/preprocessor.hpp"
|
||||
|
||||
#include <boost/dynamic_bitset.hpp>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <SDL2/SDL_image.h>
|
||||
|
||||
namespace gui2
|
||||
{
|
||||
|
@ -52,7 +50,10 @@ private:
|
|||
config type_cfg_;
|
||||
config resistances_, defenses_, movement_;
|
||||
preproc_map specials_map_, abilities_map_;
|
||||
/** Used to control checkboxes, so that only specific values are overridden */
|
||||
/**
|
||||
* Used to control checkboxes for various resistances, defences, etc.
|
||||
* so that only specific values are overridden.
|
||||
*/
|
||||
boost::dynamic_bitset<> res_toggles_, def_toggles_, move_toggles_;
|
||||
|
||||
std::vector<config> align_list_, race_list_, movetype_list_, defense_list_, resistances_list_, usage_type_list_;
|
||||
|
@ -79,14 +80,6 @@ private:
|
|||
/** Save Unit Type data to cfg */
|
||||
void save_unit_type();
|
||||
|
||||
/** Check if width/height bigger
|
||||
* than a specified size */
|
||||
bool check_big(std::string img_abs_path, const int scale_size)
|
||||
{
|
||||
SDL_Surface * img_surf = IMG_Load(img_abs_path.c_str());
|
||||
return (img_surf->w > scale_size) || (img_surf->h > scale_size);
|
||||
}
|
||||
|
||||
/** Write macro to a stream at specified tab level */
|
||||
void write_macro(std::ostream& out, unsigned level, const std::string macro_name);
|
||||
|
||||
|
@ -132,7 +125,6 @@ private:
|
|||
|
||||
/** Callback to enable/disable OK button if ID/Name is invalid */
|
||||
void button_state_change();
|
||||
void button_state_change_id();
|
||||
|
||||
/** Utility method to check if ID contains any invalid characters */
|
||||
bool check_id(std::string id);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2023 - 2024
|
||||
by Subhraman Sarkar (babaissarkar) <suvrax@gmail.com>
|
||||
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
@ -27,7 +28,7 @@ namespace gui2::dialogs
|
|||
|
||||
REGISTER_DIALOG(tod_new_schedule);
|
||||
|
||||
tod_new_schedule::tod_new_schedule(std::string& schedule_id, std::string& schedule_name)
|
||||
tod_new_schedule::tod_new_schedule(std::string& schedule_id, t_string& schedule_name)
|
||||
: modal_dialog(window_id())
|
||||
, schedule_id_(schedule_id)
|
||||
, schedule_name_(schedule_name)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2023 - 2024
|
||||
by Subhraman Sarkar (babaissarkar) <suvrax@gmail.com>
|
||||
Part of the Battle for Wesnoth Project https://www.wesnoth.org/
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
@ -30,7 +31,7 @@ namespace dialogs
|
|||
class tod_new_schedule : public modal_dialog
|
||||
{
|
||||
public:
|
||||
tod_new_schedule(std::string& schedule_id, std::string& schedule_name);
|
||||
tod_new_schedule(std::string& schedule_id, t_string& schedule_name);
|
||||
|
||||
/** The execute function. See @ref modal_dialog for more information. */
|
||||
DEFINE_SIMPLE_EXECUTE_WRAPPER(tod_new_schedule);
|
||||
|
@ -42,7 +43,7 @@ private:
|
|||
virtual const std::string& window_id() const override;
|
||||
|
||||
std::string& schedule_id_;
|
||||
std::string& schedule_name_;
|
||||
t_string& schedule_name_;
|
||||
|
||||
/* Callback for enabling or disabling OK button */
|
||||
void button_state_change();
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "cursor.hpp"
|
||||
#include "desktop/paths.hpp"
|
||||
#include "desktop/open.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "formula/string_utils.hpp"
|
||||
#include "gui/auxiliary/find_widget.hpp"
|
||||
|
@ -46,11 +47,9 @@ namespace fs = filesystem;
|
|||
|
||||
namespace
|
||||
{
|
||||
const std::string icon_dir = "misc/folder-icon.png";
|
||||
// Empty icons with the same size as the above to force the icon column to have a
|
||||
// specific size even when there are no folders in the list.
|
||||
const std::string icon_file = icon_dir + "~O(0)";
|
||||
const std::string icon_parent = icon_dir + "~O(0)";
|
||||
const std::string icon_dir = "icons/action/browse_25.png";
|
||||
const std::string icon_parent = "icons/action/undo_25.png";
|
||||
const std::string icon_file = "misc/file.png";
|
||||
// NOTE: Does not need to be the same as PARENT_DIR! Use PARENT_DIR to build
|
||||
// relative paths for non-presentational purposes instead.
|
||||
const std::string label_parent = "..";
|
||||
|
@ -159,10 +158,54 @@ file_dialog& file_dialog::set_path(const std::string& value)
|
|||
file_dialog& file_dialog::set_filename(const std::string& value)
|
||||
{
|
||||
current_entry_ = value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void file_dialog::check_filename() {
|
||||
if(!save_mode_) {
|
||||
return;
|
||||
}
|
||||
|
||||
text_box& file_textbox = find_widget<text_box>(get_window(), "filename", false);
|
||||
button& save_btn = find_widget<button>(get_window(), "ok", false);
|
||||
|
||||
// empty filename
|
||||
std::string filename = file_textbox.get_value();
|
||||
styled_widget& validation_msg = find_widget<styled_widget>(get_window(), "validation_msg", false);
|
||||
|
||||
bool stat_invalid = filename.empty() || (filename.substr(0,1) == ".");
|
||||
bool wrong_ext = false;
|
||||
|
||||
if (stat_invalid) {
|
||||
validation_msg.set_label("<span color='#00dcff' size='small'>please enter a filename</span>");
|
||||
save_btn.set_active(false);
|
||||
} else {
|
||||
// wrong extension check
|
||||
for (const auto& extension : extensions_) {
|
||||
if (filename.size() >= extension.size()) {
|
||||
std::string ext = filename.substr(filename.size()-extension.size());
|
||||
if (ext == extension) {
|
||||
wrong_ext = false;
|
||||
break;
|
||||
} else {
|
||||
wrong_ext = true;
|
||||
}
|
||||
} else {
|
||||
// size of allowed extensions and the one typed don't match
|
||||
wrong_ext = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (wrong_ext) {
|
||||
validation_msg.set_label("<span color='red' face='DejaVuSans'>✘</span><span color='red' size='small'>wrong extension, use " + utils::join(extensions_, ", ") + "</span>");
|
||||
save_btn.set_active(false);
|
||||
} else {
|
||||
validation_msg.set_label("");
|
||||
save_btn.set_active(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void file_dialog::pre_show(window& window)
|
||||
{
|
||||
styled_widget& title = find_widget<styled_widget>(&window, "title", false);
|
||||
|
@ -228,16 +271,22 @@ void file_dialog::pre_show(window& window)
|
|||
sync_bookmarks_bar();
|
||||
|
||||
listbox& filelist = find_widget<listbox>(&window, "filelist", false);
|
||||
text_box& file_textbox = find_widget<text_box>(get_window(), "filename", false);
|
||||
|
||||
connect_signal_notify_modified(filelist,
|
||||
std::bind(&file_dialog::on_row_selected, this));
|
||||
connect_signal_notify_modified(bookmarks_bar,
|
||||
std::bind(&file_dialog::on_bookmark_selected, this));
|
||||
connect_signal_notify_modified(file_textbox,
|
||||
std::bind(&file_dialog::check_filename, this));
|
||||
|
||||
check_filename();
|
||||
|
||||
button& mkdir_button = find_widget<button>(&window, "new_dir", false);
|
||||
button& rm_button = find_widget<button>(&window, "delete_file", false);
|
||||
button& bookmark_add_button = find_widget<button>(&window, "add_bookmark", false);
|
||||
button& bookmark_del_button = find_widget<button>(&window, "remove_bookmark", false);
|
||||
button& open_ext_button = find_widget<button>(&window, "open_ext", false);
|
||||
|
||||
connect_signal_mouse_left_click(mkdir_button,
|
||||
std::bind(&file_dialog::on_dir_create_cmd, this));
|
||||
|
@ -248,6 +297,14 @@ void file_dialog::pre_show(window& window)
|
|||
connect_signal_mouse_left_click(bookmark_del_button,
|
||||
std::bind(&file_dialog::on_bookmark_del_cmd, this));
|
||||
|
||||
if (desktop::open_object_is_supported()) {
|
||||
connect_signal_mouse_left_click(open_ext_button,
|
||||
std::bind([this](){ desktop::open_object(path()); }));
|
||||
} else {
|
||||
open_ext_button.set_active(false);
|
||||
open_ext_button.set_tooltip(_("Opening files is not supported, contact your packager"));
|
||||
}
|
||||
|
||||
if(read_only_) {
|
||||
mkdir_button.set_active(false);
|
||||
rm_button.set_active(false);
|
||||
|
@ -258,7 +315,8 @@ void file_dialog::pre_show(window& window)
|
|||
|
||||
refresh_fileview();
|
||||
|
||||
window.keyboard_capture(find_widget<text_box>(&window, "filename", false, true));
|
||||
//window.keyboard_capture(find_widget<text_box>(&window, "filename", false, true));
|
||||
window.keyboard_capture(&file_textbox);
|
||||
window.add_to_keyboard_chain(&filelist);
|
||||
window.set_exit_hook(window::exit_hook::on_all, std::bind(&file_dialog::on_exit, this, std::placeholders::_1));
|
||||
}
|
||||
|
|
|
@ -114,20 +114,26 @@ public:
|
|||
file_dialog& set_filename(const std::string& value);
|
||||
|
||||
/**
|
||||
* Sets the default file extension for file names in save mode.
|
||||
* Sets allowed file extensions for file names in save mode.
|
||||
*
|
||||
* When this is set to a non-empty string and save mode is active, selecting
|
||||
* file entries will cause their name portions to be highlighted in the name
|
||||
* text box if their extensions match the provided template, and any time the
|
||||
* text box is cleared it will position the cursor before the extension as a
|
||||
* hint for the user.
|
||||
* hint for the user. Additionally, the user will not be able to save the file
|
||||
* with a wrong extension if this is set.
|
||||
*
|
||||
* In case of multiple extension, the first set extension is the default.
|
||||
*
|
||||
* The value provided to this method should be preceded by a dot if
|
||||
* applicable (e.g. ".cfg").
|
||||
*/
|
||||
file_dialog& set_extension(const std::string& value)
|
||||
{
|
||||
extension_ = value;
|
||||
if (extension_.empty()) {
|
||||
extension_ = value;
|
||||
}
|
||||
extensions_.push_back(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -206,6 +212,8 @@ private:
|
|||
bool read_only_;
|
||||
bool save_mode_;
|
||||
|
||||
std::vector<std::string> extensions_;
|
||||
|
||||
std::vector<std::string> dir_files_;
|
||||
std::vector<std::string> dir_subdirs_;
|
||||
|
||||
|
@ -257,6 +265,11 @@ private:
|
|||
|
||||
bool process_submit_common(const std::string& name);
|
||||
|
||||
/**
|
||||
* Check if the filename is valid and disable save button if invalid
|
||||
*/
|
||||
void check_filename();
|
||||
|
||||
/**
|
||||
* Updates the bookmarks bar state to reflect the internal state.
|
||||
*/
|
||||
|
|
|
@ -119,6 +119,7 @@ protected:
|
|||
update_layout();
|
||||
}
|
||||
|
||||
public:
|
||||
/** Inherited from text_box_base. */
|
||||
void goto_end_of_line(const bool select = false) override
|
||||
{
|
||||
|
@ -147,6 +148,7 @@ protected:
|
|||
update_layout();
|
||||
}
|
||||
|
||||
private:
|
||||
/** Inherited from text_box_base. */
|
||||
void paste_selection(const bool mouse) override
|
||||
{
|
||||
|
|
|
@ -68,6 +68,7 @@ void scroll_text::set_label(const t_string& label)
|
|||
if(resize_needed && get_size() != point()) {
|
||||
place(get_origin(), get_size());
|
||||
}
|
||||
widget->goto_start_of_data();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -105,17 +105,18 @@ void tab_container::add_tab_entry(const widget_data row)
|
|||
|
||||
void tab_container::select_tab(unsigned index)
|
||||
{
|
||||
unsigned count = get_tab_count();
|
||||
if (index < count) {
|
||||
if (index < get_tab_count()) {
|
||||
get_internal_list().select_row(index);
|
||||
generator_->select_item(index, true);
|
||||
}
|
||||
}
|
||||
|
||||
void tab_container::change_selection() {
|
||||
select_tab(get_internal_list().get_selected_row());
|
||||
select_tab(get_active_tab_index());
|
||||
place(get_origin(), get_size());
|
||||
queue_redraw();
|
||||
|
||||
fire(event::NOTIFY_MODIFIED, *this, nullptr);
|
||||
}
|
||||
|
||||
// }---------- DEFINITION ---------{
|
||||
|
|
|
@ -50,9 +50,25 @@ public:
|
|||
|
||||
void select_tab(unsigned index);
|
||||
|
||||
unsigned get_tab_count() {
|
||||
unsigned get_active_tab_index() {
|
||||
return get_internal_list().get_selected_row();
|
||||
}
|
||||
|
||||
unsigned get_tab_count() const {
|
||||
return builders_.size();
|
||||
}
|
||||
|
||||
grid* get_tab_grid(unsigned i)
|
||||
{
|
||||
assert(generator_);
|
||||
return &generator_->item(i);
|
||||
}
|
||||
|
||||
const grid* get_tab_grid(unsigned i) const
|
||||
{
|
||||
assert(generator_);
|
||||
return &generator_->item(i);
|
||||
}
|
||||
private:
|
||||
/**
|
||||
* Possible states of the widget.
|
||||
|
|
|
@ -180,8 +180,8 @@ constexpr std::array<hotkey_command_temp, HOTKEY_NULL - 1> master_hotkey_list {{
|
|||
{ HOTKEY_EDITOR_PARTIAL_UNDO, "editor-partial-undo", N_("Partial Undo"), false, scope_editor, HKCAT_SCENARIO, "" },
|
||||
{ HOTKEY_EDITOR_MAP_NEW, "editor-map-new", N_("New Map"), false, scope_editor, HKCAT_SCENARIO, "" },
|
||||
{ HOTKEY_EDITOR_SCENARIO_NEW, "editor-scenario-new", N_("New Scenario"), false, scope_editor, HKCAT_SCENARIO, "" },
|
||||
{ HOTKEY_EDITOR_MAP_LOAD, "editor-map-load", N_("Load Map"), false, scope_editor, HKCAT_MAP, "" },
|
||||
{ HOTKEY_EDITOR_MAP_SAVE, "editor-map-save", N_("Save Map"), false, scope_editor, HKCAT_MAP, "" },
|
||||
{ HOTKEY_EDITOR_MAP_LOAD, "editor-map-load", N_("Load Map/Scenario"), false, scope_editor, HKCAT_MAP, "" },
|
||||
{ HOTKEY_EDITOR_MAP_SAVE, "editor-map-save", N_("Save"), false, scope_editor, HKCAT_MAP, "" },
|
||||
{ HOTKEY_EDITOR_MAP_SAVE_AS, "editor-map-save-as", N_("Save Map As"), false, scope_editor, HKCAT_MAP, "" },
|
||||
{ HOTKEY_EDITOR_SCENARIO_SAVE_AS, "editor-scenario-save-as", N_("Save Scenario As"), false, scope_editor, HKCAT_SCENARIO, "" },
|
||||
{ HOTKEY_EDITOR_MAP_SAVE_ALL, "editor-map-save-all", N_("Save All Maps"), false, scope_editor, HKCAT_MAP, "" },
|
||||
|
@ -272,8 +272,10 @@ constexpr std::array<hotkey_command_temp, HOTKEY_NULL - 1> master_hotkey_list {{
|
|||
|
||||
{ HOTKEY_EDITOR_PBL, "editor-pbl", N_("Add-on Publishing Editor"), false, scope_editor, HKCAT_GENERAL, "" },
|
||||
{ HOTKEY_EDITOR_CHANGE_ADDON_ID, "editor-addon-id", N_("Change Add-on ID"), false, scope_editor, HKCAT_GENERAL, "" },
|
||||
{ HOTKEY_EDITOR_SELECT_ADDON, "editor-addon-select", N_("Select active Add-on"), false, scope_editor, HKCAT_GENERAL, "" },
|
||||
{ HOTKEY_EDITOR_OPEN_ADDON, "editor-addon-open", N_("Open Add-on folder"), false, scope_editor, HKCAT_GENERAL, "" },
|
||||
|
||||
{ HOTKEY_EDITOR_SCENARIO_EDIT, "editor-scenario-edit", N_("Edit Scenario"), false, scope_editor, HKCAT_SCENARIO, "" },
|
||||
{ HOTKEY_EDITOR_SCENARIO_EDIT, "editor-scenario-edit", N_("Edit Scenario Settings"), false, scope_editor, HKCAT_SCENARIO, "" },
|
||||
{ HOTKEY_EDITOR_SIDE_EDIT, "editor-side-edit", N_("Edit Side"), false, scope_editor, HKCAT_SCENARIO, "" },
|
||||
{ HOTKEY_EDITOR_SIDE_REMOVE, "editor-side-remove", N_("Remove Side"), false, scope_editor, HKCAT_SCENARIO, "" },
|
||||
|
||||
|
|
|
@ -193,6 +193,8 @@ enum HOTKEY_COMMAND {
|
|||
// Addons
|
||||
HOTKEY_EDITOR_PBL,
|
||||
HOTKEY_EDITOR_CHANGE_ADDON_ID,
|
||||
HOTKEY_EDITOR_SELECT_ADDON,
|
||||
HOTKEY_EDITOR_OPEN_ADDON,
|
||||
|
||||
// Scenario
|
||||
HOTKEY_EDITOR_SCENARIO_EDIT,
|
||||
|
|
|
@ -1434,7 +1434,7 @@ template<>
|
|||
struct dialog_tester<tod_new_schedule>
|
||||
{
|
||||
std::string id = "id";
|
||||
std::string name = "name";
|
||||
t_string name = "name";
|
||||
dialog_tester() {}
|
||||
tod_new_schedule* create()
|
||||
{
|
||||
|
|
|
@ -1592,6 +1592,7 @@ bool unit::get_attacks_changed() const
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void unit::write(config& cfg, bool write_all) const
|
||||
{
|
||||
config back;
|
||||
|
@ -1781,6 +1782,17 @@ bool unit::loyal() const
|
|||
return utils::holds_alternative<upkeep_loyal>(upkeep_);
|
||||
}
|
||||
|
||||
void unit::set_loyal(bool loyal)
|
||||
{
|
||||
if (loyal) {
|
||||
upkeep_ = upkeep_loyal{};
|
||||
overlays_.push_back("misc/loyal-icon.png");
|
||||
} else {
|
||||
upkeep_ = upkeep_full{};
|
||||
overlays_.erase(std::remove(overlays_.begin(), overlays_.end(), "misc/loyal-icon.png"), overlays_.end());
|
||||
}
|
||||
}
|
||||
|
||||
int unit::defense_modifier(const t_translation::terrain_code & terrain) const
|
||||
{
|
||||
int def = movement_type_.defense_modifier(terrain);
|
||||
|
|
|
@ -1282,6 +1282,8 @@ public:
|
|||
/** Gets whether this unit is loyal - ie, it costs no upkeep. */
|
||||
bool loyal() const;
|
||||
|
||||
void set_loyal(bool loyal);
|
||||
|
||||
/** Gets whether this unit is fearless - ie, unaffected by time of day. */
|
||||
bool is_fearless() const
|
||||
{
|
||||
|
|