Changeset View
Changeset View
Standalone View
Standalone View
source/blender/windowmanager/intern/wm_files.c
| Show First 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | |||||
| #include "ED_view3d_offscreen.h" | #include "ED_view3d_offscreen.h" | ||||
| #include "ED_util.h" | #include "ED_util.h" | ||||
| #include "ED_undo.h" | #include "ED_undo.h" | ||||
| #include "GHOST_C-api.h" | #include "GHOST_C-api.h" | ||||
| #include "GHOST_Path-api.h" | #include "GHOST_Path-api.h" | ||||
| #include "UI_interface.h" | #include "UI_interface.h" | ||||
| #include "UI_interface_icons.h" | |||||
| #include "UI_resources.h" | #include "UI_resources.h" | ||||
| #include "UI_view2d.h" | #include "UI_view2d.h" | ||||
| /* only to report a missing engine */ | /* only to report a missing engine */ | ||||
| #include "RE_engine.h" | #include "RE_engine.h" | ||||
| #ifdef WITH_PYTHON | #ifdef WITH_PYTHON | ||||
| # include "BPY_extern.h" | # include "BPY_extern.h" | ||||
| ▲ Show 20 Lines • Show All 2,926 Lines • ▼ Show 20 Lines | |||||
| static const char *close_file_dialog_name = "file_close_popup"; | static const char *close_file_dialog_name = "file_close_popup"; | ||||
| static uiBlock *block_create__close_file_dialog(struct bContext *C, | static uiBlock *block_create__close_file_dialog(struct bContext *C, | ||||
| struct ARegion *region, | struct ARegion *region, | ||||
| void *arg1) | void *arg1) | ||||
| { | { | ||||
| wmGenericCallback *post_action = (wmGenericCallback *)arg1; | wmGenericCallback *post_action = (wmGenericCallback *)arg1; | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| uiStyle *style = UI_style_get(); | uiStyle *style = UI_style_get_dpi(); | ||||
| uiFontStyle *fs = &style->widgetlabel; | const int dialog_width = U.widget_unit * 22; | ||||
| const short icon_size = 64 * U.dpi_fac; | |||||
| /* Filename */ | |||||
| const char *blendfile_pathpath = BKE_main_blendfile_path(bmain); | |||||
| char filename[FILE_MAX]; | |||||
| if (blendfile_pathpath[0] != '\0') { | |||||
| BLI_split_file_part(blendfile_pathpath, filename, sizeof(filename)); | |||||
| BLI_path_extension_replace(filename, sizeof(filename), ""); | |||||
| } | |||||
| else { | |||||
| STRNCPY(filename, IFACE_("Untitled")); | |||||
| } | |||||
| /* Title */ | /* Calculate icon column factor. */ | ||||
| char title[FILE_MAX + 100]; | const float split_factor = (float)icon_size / (float)(dialog_width - style->columnspace); | ||||
| UI_text_clip_middle_ex( | |||||
| fs, filename, U.widget_unit * 9, U.widget_unit * 2, sizeof(filename), '\0'); | |||||
| BLI_snprintf(title, sizeof(title), TIP_("Save changes to \"%s\" before closing?"), filename); | |||||
| int title_width = MAX2(UI_fontstyle_string_width(fs, title), U.widget_unit * 22); | |||||
| /* Create dialog */ | |||||
| uiBlock *block = UI_block_begin(C, region, close_file_dialog_name, UI_EMBOSS); | uiBlock *block = UI_block_begin(C, region, close_file_dialog_name, UI_EMBOSS); | ||||
| style = UI_style_get_dpi(); | |||||
| UI_block_flag_enable( | UI_block_flag_enable( | ||||
| block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_LOOP | UI_BLOCK_NO_WIN_CLIP | UI_BLOCK_NUMSELECT); | block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_LOOP | UI_BLOCK_NO_WIN_CLIP | UI_BLOCK_NUMSELECT); | ||||
| UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP); | UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP); | ||||
| UI_block_emboss_set(block, UI_EMBOSS); | UI_block_emboss_set(block, UI_EMBOSS); | ||||
| uiLayout *layout = UI_block_layout(block, | uiLayout *block_layout = UI_block_layout( | ||||
| UI_LAYOUT_VERTICAL, | block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, dialog_width, 0, 0, style); | ||||
| UI_LAYOUT_PANEL, | |||||
| 10, | |||||
| 2, | |||||
| U.widget_unit * 2 + title_width, | |||||
| U.widget_unit * 6, | |||||
| 0, | |||||
| style); | |||||
| /* Title */ | /* Split layout to put alert icon on left side. */ | ||||
| uiItemL_ex(layout, title, ICON_ERROR, true, false); | uiLayout *split_block = uiLayoutSplit(block_layout, split_factor, false); | ||||
| /* Alert Icon. */ | |||||
| uiLayout *layout = uiLayoutColumn(split_block, false); | |||||
| uiDefButAlert(block, ALERT_ICON_WARNING, 0, 0, 0, icon_size); | |||||
| /* The rest of the content on the right. */ | |||||
| layout = uiLayoutColumn(split_block, false); | |||||
| /* Title. */ | |||||
| uiItemL_ex(layout, TIP_("Save changes before closing?"), ICON_NONE, true, false); | |||||
| /* Filename. */ | |||||
| const char *blendfile_pathpath = BKE_main_blendfile_path(CTX_data_main(C)); | |||||
| char filename[FILE_MAX]; | |||||
| if (blendfile_pathpath[0] != '\0') { | |||||
| BLI_split_file_part(blendfile_pathpath, filename, sizeof(filename)); | |||||
| BLI_path_extension_replace(filename, sizeof(filename), ""); | |||||
| } | |||||
| else { | |||||
| STRNCPY(filename, IFACE_("Untitled")); | |||||
| } | |||||
| uiItemL(layout, filename, ICON_NONE); | |||||
| /* Image Saving */ | /* Image Saving Warnings. */ | ||||
| ReportList reports; | ReportList reports; | ||||
| BKE_reports_init(&reports, RPT_STORE); | BKE_reports_init(&reports, RPT_STORE); | ||||
| uint modified_images_count = ED_image_save_all_modified_info(bmain, &reports); | uint modified_images_count = ED_image_save_all_modified_info(bmain, &reports); | ||||
| LISTBASE_FOREACH (Report *, report, &reports.list) { | LISTBASE_FOREACH (Report *, report, &reports.list) { | ||||
| uiItemL_ex(layout, report->message, ICON_CANCEL, false, true); | uiLayout *row = uiLayoutColumn(layout, false); | ||||
| uiLayoutSetScaleY(row, 0.6f); | |||||
| uiItemS_ex(row, 1.2f); | |||||
| /* Error messages created in ED_image_save_all_modified_info() can be long, | |||||
| * but are made to separate into two parts at first colon between text and paths. | |||||
| */ | |||||
| char *message = BLI_strdupn(report->message, report->len); | |||||
| char *path_info = strstr(message, ": "); | |||||
campbellbarton: Name could be more descriptive eg, `line_brief` | |||||
| if (path_info) { | |||||
| /* Terminate message string at colon. */ | |||||
Not Done Inline ActionsIt's not clear why this is needed, comment should state what this is for (example message that needs this). campbellbarton: It's not clear why this is needed, comment should state what this is for (example message that… | |||||
| path_info[1] = '\0'; | |||||
| /* Skip over the ": " */ | |||||
| path_info += 2; | |||||
| } | |||||
| uiItemL_ex(row, message, ICON_NONE, false, true); | |||||
| if (path_info) { | |||||
| uiItemL_ex(row, path_info, ICON_NONE, false, true); | |||||
| } | |||||
| MEM_freeN(message); | |||||
| } | } | ||||
| /* Modified Images Checkbox. */ | |||||
| if (modified_images_count > 0) { | if (modified_images_count > 0) { | ||||
| char message[64]; | char message[64]; | ||||
| BLI_snprintf(message, | BLI_snprintf(message, | ||||
| sizeof(message), | sizeof(message), | ||||
| (modified_images_count == 1) ? "Save %u modified image" : | (modified_images_count == 1) ? "Save %u modified image" : | ||||
| "Save %u modified images", | "Save %u modified images", | ||||
| modified_images_count); | modified_images_count); | ||||
| uiItemS(layout); | uiItemS_ex(layout, 2.0f); | ||||
| uiDefButBitC(block, | uiDefButBitC(block, | ||||
| UI_BTYPE_CHECKBOX, | UI_BTYPE_CHECKBOX, | ||||
| 1, | 1, | ||||
| 0, | 0, | ||||
| message, | message, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| UI_UNIT_Y, | UI_UNIT_Y, | ||||
| &save_images_when_file_is_closed, | &save_images_when_file_is_closed, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| 0, | 0, | ||||
| ""); | ""); | ||||
| } | } | ||||
| BKE_reports_clear(&reports); | BKE_reports_clear(&reports); | ||||
| uiItemS_ex(layout, 3.0f); | uiItemS_ex(layout, 1.0f); | ||||
| /* Buttons */ | /* Buttons. */ | ||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||
| const bool windows_layout = true; | const bool windows_layout = true; | ||||
| #else | #else | ||||
| const bool windows_layout = false; | const bool windows_layout = false; | ||||
| #endif | #endif | ||||
Not Done Inline ActionsWould prefer to keep the name split, as this is in keeping with Python layout code, buttons is a bit general since most UI elements are called buttons in Blender. campbellbarton: Would prefer to keep the name `split`, as this is in keeping with Python layout code, buttons… | |||||
| if (windows_layout) { | if (windows_layout) { | ||||
| /* Windows standard layout. */ | /* Windows standard layout. */ | ||||
| uiLayout *split = uiLayoutSplit(layout, 0.18f, true); | uiLayout *split = uiLayoutSplit(block_layout, 0.174f, true); | ||||
| uiLayoutSetScaleY(split, 1.2f); | uiLayoutSetScaleY(split, 1.2f); | ||||
| uiLayout *col = uiLayoutColumn(split, false); | uiLayoutColumn(split, false); | ||||
| uiItemS(col); | uiItemS(layout); | ||||
| col = uiLayoutColumn(split, false); | uiLayoutColumn(split, false); | ||||
| wm_block_file_close_save_button(block, post_action); | wm_block_file_close_save_button(block, post_action); | ||||
| col = uiLayoutColumn(split, false); | uiLayoutColumn(split, false); | ||||
| wm_block_file_close_discard_button(block, post_action); | wm_block_file_close_discard_button(block, post_action); | ||||
| col = uiLayoutColumn(split, false); | uiLayoutColumn(split, false); | ||||
| wm_block_file_close_cancel_button(block, post_action); | wm_block_file_close_cancel_button(block, post_action); | ||||
| } | } | ||||
| else { | else { | ||||
| /* macOS and Linux standard layout. */ | /* macOS and Linux standard layout. */ | ||||
| uiLayout *split = uiLayoutSplit(layout, 0.0f, true); | uiLayout *split = uiLayoutSplit(block_layout, 0.167f, true); | ||||
| uiLayoutSetScaleY(split, 1.2f); | uiLayoutSetScaleY(split, 1.2f); | ||||
| uiLayout *col = uiLayoutColumn(split, true); | layout = uiLayoutColumn(split, false); | ||||
| uiItemS(layout); | |||||
| /* Split button area into two sections: 40/60. */ | |||||
| uiLayout *mac_left = uiLayoutSplit(split, 0.40f, true); | |||||
| /* First button uses 75% of left side (30% of original). */ | |||||
| uiLayoutSplit(mac_left, 0.75f, true); | |||||
| wm_block_file_close_discard_button(block, post_action); | wm_block_file_close_discard_button(block, post_action); | ||||
Not Done Inline Actions*picky* double spaces. campbellbarton: *picky* double spaces. | |||||
| col = uiLayoutColumn(split, true); | /* The right side is split 50/50 (each 30% of original). */ | ||||
| uiItemS(col); | uiLayout *mac_right = uiLayoutSplit(mac_left, 0.50f, true); | ||||
| col = uiLayoutColumn(split, true); | uiLayoutColumn(mac_right, false); | ||||
| wm_block_file_close_cancel_button(block, post_action); | wm_block_file_close_cancel_button(block, post_action); | ||||
| col = uiLayoutColumn(split, false); | uiLayoutColumn(mac_right, false); | ||||
| wm_block_file_close_save_button(block, post_action); | wm_block_file_close_save_button(block, post_action); | ||||
| } | } | ||||
| UI_block_bounds_set_centered(block, 14 * U.dpi_fac); | UI_block_bounds_set_centered(block, 14 * U.dpi_fac); | ||||
| return block; | return block; | ||||
| } | } | ||||
| static void free_post_file_close_action(void *arg) | static void free_post_file_close_action(void *arg) | ||||
| Show All 22 Lines | |||||
Name could be more descriptive eg, line_brief