Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_spreadsheet/space_spreadsheet.cc
| /* SPDX-License-Identifier: GPL-2.0-or-later */ | /* SPDX-License-Identifier: GPL-2.0-or-later */ | ||||
| #include <cstring> | #include <cstring> | ||||
| #include "BLI_listbase.h" | #include "BLI_listbase.h" | ||||
| #include "BKE_lib_remap.h" | #include "BKE_lib_remap.h" | ||||
| #include "BKE_screen.h" | #include "BKE_screen.h" | ||||
| #include "ED_screen.h" | #include "ED_screen.h" | ||||
| #include "ED_space_api.h" | #include "ED_space_api.h" | ||||
| #include "ED_spreadsheet.h" | #include "ED_spreadsheet.h" | ||||
| #include "ED_viewer_path.hh" | |||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "DNA_screen_types.h" | #include "DNA_screen_types.h" | ||||
| #include "DNA_space_types.h" | #include "DNA_space_types.h" | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "UI_interface.h" | #include "UI_interface.h" | ||||
| #include "UI_resources.h" | #include "UI_resources.h" | ||||
| #include "UI_view2d.h" | #include "UI_view2d.h" | ||||
| #include "BLO_read_write.h" | |||||
| #include "DEG_depsgraph_query.h" | #include "DEG_depsgraph_query.h" | ||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| #include "WM_types.h" | #include "WM_types.h" | ||||
| #include "BLT_translation.h" | #include "BLT_translation.h" | ||||
| #include "BLF_api.h" | #include "BLF_api.h" | ||||
| #include "spreadsheet_context.hh" | |||||
| #include "spreadsheet_data_source_geometry.hh" | #include "spreadsheet_data_source_geometry.hh" | ||||
| #include "spreadsheet_dataset_draw.hh" | #include "spreadsheet_dataset_draw.hh" | ||||
| #include "spreadsheet_intern.hh" | #include "spreadsheet_intern.hh" | ||||
| #include "spreadsheet_layout.hh" | #include "spreadsheet_layout.hh" | ||||
| #include "spreadsheet_row_filter.hh" | #include "spreadsheet_row_filter.hh" | ||||
| #include "spreadsheet_row_filter_ui.hh" | #include "spreadsheet_row_filter_ui.hh" | ||||
| using namespace blender; | using namespace blender; | ||||
| ▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | static void spreadsheet_free(SpaceLink *sl) | ||||
| MEM_delete(sspreadsheet->runtime); | MEM_delete(sspreadsheet->runtime); | ||||
| LISTBASE_FOREACH_MUTABLE (SpreadsheetRowFilter *, row_filter, &sspreadsheet->row_filters) { | LISTBASE_FOREACH_MUTABLE (SpreadsheetRowFilter *, row_filter, &sspreadsheet->row_filters) { | ||||
| spreadsheet_row_filter_free(row_filter); | spreadsheet_row_filter_free(row_filter); | ||||
| } | } | ||||
| LISTBASE_FOREACH_MUTABLE (SpreadsheetColumn *, column, &sspreadsheet->columns) { | LISTBASE_FOREACH_MUTABLE (SpreadsheetColumn *, column, &sspreadsheet->columns) { | ||||
| spreadsheet_column_free(column); | spreadsheet_column_free(column); | ||||
| } | } | ||||
| LISTBASE_FOREACH_MUTABLE (SpreadsheetContext *, context, &sspreadsheet->context_path) { | BKE_viewer_path_clear(&sspreadsheet->viewer_path); | ||||
| spreadsheet_context_free(context); | |||||
| } | |||||
| } | } | ||||
| static void spreadsheet_init(wmWindowManager *UNUSED(wm), ScrArea *area) | static void spreadsheet_init(wmWindowManager *UNUSED(wm), ScrArea *area) | ||||
| { | { | ||||
| SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)area->spacedata.first; | SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)area->spacedata.first; | ||||
| if (sspreadsheet->runtime == nullptr) { | if (sspreadsheet->runtime == nullptr) { | ||||
| sspreadsheet->runtime = MEM_new<SpaceSpreadsheet_Runtime>(__func__); | sspreadsheet->runtime = MEM_new<SpaceSpreadsheet_Runtime>(__func__); | ||||
| } | } | ||||
| Show All 17 Lines | LISTBASE_FOREACH (const SpreadsheetRowFilter *, src_filter, &sspreadsheet_old->row_filters) { | ||||
| BLI_addtail(&sspreadsheet_new->row_filters, new_filter); | BLI_addtail(&sspreadsheet_new->row_filters, new_filter); | ||||
| } | } | ||||
| BLI_listbase_clear(&sspreadsheet_new->columns); | BLI_listbase_clear(&sspreadsheet_new->columns); | ||||
| LISTBASE_FOREACH (SpreadsheetColumn *, src_column, &sspreadsheet_old->columns) { | LISTBASE_FOREACH (SpreadsheetColumn *, src_column, &sspreadsheet_old->columns) { | ||||
| SpreadsheetColumn *new_column = spreadsheet_column_copy(src_column); | SpreadsheetColumn *new_column = spreadsheet_column_copy(src_column); | ||||
| BLI_addtail(&sspreadsheet_new->columns, new_column); | BLI_addtail(&sspreadsheet_new->columns, new_column); | ||||
| } | } | ||||
| BLI_listbase_clear(&sspreadsheet_new->context_path); | BKE_viewer_path_copy(&sspreadsheet_new->viewer_path, &sspreadsheet_old->viewer_path); | ||||
| LISTBASE_FOREACH_MUTABLE (SpreadsheetContext *, src_context, &sspreadsheet_old->context_path) { | |||||
| SpreadsheetContext *new_context = spreadsheet_context_copy(src_context); | |||||
| BLI_addtail(&sspreadsheet_new->context_path, new_context); | |||||
| } | |||||
| return (SpaceLink *)sspreadsheet_new; | return (SpaceLink *)sspreadsheet_new; | ||||
| } | } | ||||
| static void spreadsheet_keymap(wmKeyConfig *keyconf) | static void spreadsheet_keymap(wmKeyConfig *keyconf) | ||||
| { | { | ||||
| /* Entire editor only. */ | /* Entire editor only. */ | ||||
| WM_keymap_ensure(keyconf, "Spreadsheet Generic", SPACE_SPREADSHEET, 0); | WM_keymap_ensure(keyconf, "Spreadsheet Generic", SPACE_SPREADSHEET, 0); | ||||
| } | } | ||||
| static void spreadsheet_id_remap(ScrArea *UNUSED(area), | static void spreadsheet_id_remap(ScrArea *UNUSED(area), | ||||
| SpaceLink *slink, | SpaceLink *slink, | ||||
| const IDRemapper *mappings) | const IDRemapper *mappings) | ||||
| { | { | ||||
| SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)slink; | SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)slink; | ||||
| LISTBASE_FOREACH (SpreadsheetContext *, context, &sspreadsheet->context_path) { | BKE_viewer_path_id_remap(&sspreadsheet->viewer_path, mappings); | ||||
| if (context->type != SPREADSHEET_CONTEXT_OBJECT) { | |||||
| continue; | |||||
| } | |||||
| SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)context; | |||||
| if (object_context->object != nullptr && GS(object_context->object->id.name) != ID_OB) { | |||||
| object_context->object = nullptr; | |||||
| continue; | |||||
| } | |||||
| BKE_id_remapper_apply(mappings, ((ID **)&object_context->object), ID_REMAP_APPLY_DEFAULT); | |||||
| } | |||||
| } | } | ||||
| static void spreadsheet_main_region_init(wmWindowManager *wm, ARegion *region) | static void spreadsheet_main_region_init(wmWindowManager *wm, ARegion *region) | ||||
| { | { | ||||
| region->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM; | region->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM; | ||||
| region->v2d.align = V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y; | region->v2d.align = V2D_ALIGN_NO_NEG_X | V2D_ALIGN_NO_POS_Y; | ||||
| region->v2d.keepzoom = V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT; | region->v2d.keepzoom = V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y | V2D_LIMITZOOM | V2D_KEEPASPECT; | ||||
| region->v2d.keeptot = V2D_KEEPTOT_STRICT; | region->v2d.keeptot = V2D_KEEPTOT_STRICT; | ||||
| Show All 9 Lines | UI_view2d_region_reinit(®ion->v2d, V2D_COMMONVIEW_LIST, region->winx, region->winy); | ||||
| wmKeyMap *keymap = WM_keymap_ensure( | wmKeyMap *keymap = WM_keymap_ensure( | ||||
| wm->defaultconf, "Spreadsheet Generic", SPACE_SPREADSHEET, 0); | wm->defaultconf, "Spreadsheet Generic", SPACE_SPREADSHEET, 0); | ||||
| WM_event_add_keymap_handler(®ion->handlers, keymap); | WM_event_add_keymap_handler(®ion->handlers, keymap); | ||||
| } | } | ||||
| } | } | ||||
| ID *ED_spreadsheet_get_current_id(const struct SpaceSpreadsheet *sspreadsheet) | ID *ED_spreadsheet_get_current_id(const struct SpaceSpreadsheet *sspreadsheet) | ||||
| { | { | ||||
| if (BLI_listbase_is_empty(&sspreadsheet->context_path)) { | if (BLI_listbase_is_empty(&sspreadsheet->viewer_path.path)) { | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| SpreadsheetContext *root_context = (SpreadsheetContext *)sspreadsheet->context_path.first; | ViewerPathElem *root_context = static_cast<ViewerPathElem *>( | ||||
| if (root_context->type != SPREADSHEET_CONTEXT_OBJECT) { | sspreadsheet->viewer_path.path.first); | ||||
| if (root_context->type != VIEWER_PATH_ELEM_TYPE_ID) { | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| SpreadsheetContextObject *object_context = (SpreadsheetContextObject *)root_context; | IDViewerPathElem *id_elem = reinterpret_cast<IDViewerPathElem *>(root_context); | ||||
| return (ID *)object_context->object; | return id_elem->id; | ||||
| } | } | ||||
| /* Check if the pinned context still exists. If it doesn't try to find a new context. */ | static void view_active_object(const bContext *C, SpaceSpreadsheet *sspreadsheet) | ||||
| static void update_pinned_context_path_if_outdated(const bContext *C) | |||||
| { | { | ||||
| SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C); | BKE_viewer_path_clear(&sspreadsheet->viewer_path); | ||||
| Main *bmain = CTX_data_main(C); | Object *ob = CTX_data_active_object(C); | ||||
| if (!ED_spreadsheet_context_path_exists(bmain, sspreadsheet)) { | if (ob == nullptr) { | ||||
| ED_spreadsheet_context_path_guess(C, sspreadsheet); | return; | ||||
| if (ED_spreadsheet_context_path_update_tag(sspreadsheet)) { | |||||
| ED_area_tag_redraw(CTX_wm_area(C)); | |||||
| } | } | ||||
| IDViewerPathElem *id_elem = BKE_viewer_path_elem_new_id(); | |||||
| id_elem->id = &ob->id; | |||||
| BLI_addtail(&sspreadsheet->viewer_path.path, id_elem); | |||||
| ED_area_tag_redraw(CTX_wm_area(C)); | |||||
| } | } | ||||
| if (BLI_listbase_is_empty(&sspreadsheet->context_path)) { | static void spreadsheet_update_context(const bContext *C) | ||||
| /* Don't pin empty context_path, that could be annoying. */ | { | ||||
| using blender::ed::viewer_path::ViewerPathForGeometryNodesViewer; | |||||
| SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C); | |||||
| Object *active_object = CTX_data_active_object(C); | |||||
| Object *context_object = blender::ed::viewer_path::parse_object_only(sspreadsheet->viewer_path); | |||||
| switch (eSpaceSpreadsheet_ObjectEvalState(sspreadsheet->object_eval_state)) { | |||||
| case SPREADSHEET_OBJECT_EVAL_STATE_ORIGINAL: | |||||
| case SPREADSHEET_OBJECT_EVAL_STATE_EVALUATED: { | |||||
| if (sspreadsheet->flag & SPREADSHEET_FLAG_PINNED) { | |||||
| if (context_object == nullptr) { | |||||
| /* Object is not available anymore, so clear the pinning. */ | |||||
| sspreadsheet->flag &= ~SPREADSHEET_FLAG_PINNED; | sspreadsheet->flag &= ~SPREADSHEET_FLAG_PINNED; | ||||
| } | } | ||||
| else { | |||||
| /* The object is still pinned, do nothing. */ | |||||
| break; | |||||
| } | } | ||||
| static void update_context_path_from_context(const bContext *C) | |||||
| { | |||||
| SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C); | |||||
| if (!ED_spreadsheet_context_path_is_active(C, sspreadsheet)) { | |||||
| ED_spreadsheet_context_path_guess(C, sspreadsheet); | |||||
| if (ED_spreadsheet_context_path_update_tag(sspreadsheet)) { | |||||
| ED_area_tag_redraw(CTX_wm_area(C)); | |||||
| } | } | ||||
| else { | |||||
| if (active_object != context_object) { | |||||
| /* The active object has changed, so view the new active object. */ | |||||
| view_active_object(C, sspreadsheet); | |||||
| } | |||||
| else { | |||||
| /* Nothing changed. */ | |||||
| break; | |||||
| } | } | ||||
| } | } | ||||
| break; | |||||
| void spreadsheet_update_context_path(const bContext *C) | } | ||||
| { | case SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE: { | ||||
| SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C); | WorkSpace *workspace = CTX_wm_workspace(C); | ||||
| if (sspreadsheet->flag & SPREADSHEET_FLAG_PINNED) { | if (sspreadsheet->flag & SPREADSHEET_FLAG_PINNED) { | ||||
| update_pinned_context_path_if_outdated(C); | const std::optional<ViewerPathForGeometryNodesViewer> parsed_path = | ||||
| blender::ed::viewer_path::parse_geometry_nodes_viewer(sspreadsheet->viewer_path); | |||||
| if (parsed_path.has_value()) { | |||||
| if (blender::ed::viewer_path::exists_geometry_nodes_viewer(*parsed_path)) { | |||||
| /* The pinned path is still valid, do nothing. */ | |||||
| break; | |||||
| } | |||||
| else { | |||||
| /* The pinned path does not exist anymore, clear pinning. */ | |||||
| sspreadsheet->flag &= ~SPREADSHEET_FLAG_PINNED; | |||||
| } | |||||
| } | } | ||||
| else { | else { | ||||
| update_context_path_from_context(C); | /* Unknown pinned path, clear pinning. */ | ||||
| sspreadsheet->flag &= ~SPREADSHEET_FLAG_PINNED; | |||||
| } | |||||
| } | |||||
| /* Now try to update the viewer path from the workspace. */ | |||||
| const std::optional<ViewerPathForGeometryNodesViewer> workspace_parsed_path = | |||||
| blender::ed::viewer_path::parse_geometry_nodes_viewer(workspace->viewer_path); | |||||
| if (workspace_parsed_path.has_value()) { | |||||
| if (BKE_viewer_path_equal(&sspreadsheet->viewer_path, &workspace->viewer_path)) { | |||||
| /* Nothing changed. */ | |||||
| break; | |||||
| } | |||||
| else { | |||||
| /* Update the viewer path from the workspace. */ | |||||
| BKE_viewer_path_clear(&sspreadsheet->viewer_path); | |||||
| BKE_viewer_path_copy(&sspreadsheet->viewer_path, &workspace->viewer_path); | |||||
| } | |||||
| } | |||||
| else { | |||||
| /* No active viewer node, change back to showing evaluated active object. */ | |||||
| sspreadsheet->object_eval_state = SPREADSHEET_OBJECT_EVAL_STATE_EVALUATED; | |||||
| view_active_object(C, sspreadsheet); | |||||
| } | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| Object *spreadsheet_get_object_eval(const SpaceSpreadsheet *sspreadsheet, | Object *spreadsheet_get_object_eval(const SpaceSpreadsheet *sspreadsheet, | ||||
| const Depsgraph *depsgraph) | const Depsgraph *depsgraph) | ||||
| { | { | ||||
| ID *used_id = ED_spreadsheet_get_current_id(sspreadsheet); | ID *used_id = ED_spreadsheet_get_current_id(sspreadsheet); | ||||
| if (used_id == nullptr) { | if (used_id == nullptr) { | ||||
| ▲ Show 20 Lines • Show All 125 Lines • ▼ Show 20 Lines | data_source.foreach_default_column_ids( | ||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| static void spreadsheet_main_region_draw(const bContext *C, ARegion *region) | static void spreadsheet_main_region_draw(const bContext *C, ARegion *region) | ||||
| { | { | ||||
| SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C); | SpaceSpreadsheet *sspreadsheet = CTX_wm_space_spreadsheet(C); | ||||
| sspreadsheet->runtime->cache.set_all_unused(); | sspreadsheet->runtime->cache.set_all_unused(); | ||||
| spreadsheet_update_context_path(C); | spreadsheet_update_context(C); | ||||
| std::unique_ptr<DataSource> data_source = get_data_source(C); | std::unique_ptr<DataSource> data_source = get_data_source(C); | ||||
| if (!data_source) { | if (!data_source) { | ||||
| data_source = std::make_unique<DataSource>(); | data_source = std::make_unique<DataSource>(); | ||||
| } | } | ||||
| update_visible_columns(sspreadsheet->columns, *data_source); | update_visible_columns(sspreadsheet->columns, *data_source); | ||||
| Show All 32 Lines | static void spreadsheet_main_region_draw(const bContext *C, ARegion *region) | ||||
| /* Free all cache items that have not been used. */ | /* Free all cache items that have not been used. */ | ||||
| sspreadsheet->runtime->cache.remove_all_unused(); | sspreadsheet->runtime->cache.remove_all_unused(); | ||||
| } | } | ||||
| static void spreadsheet_main_region_listener(const wmRegionListenerParams *params) | static void spreadsheet_main_region_listener(const wmRegionListenerParams *params) | ||||
| { | { | ||||
| ARegion *region = params->region; | ARegion *region = params->region; | ||||
| const wmNotifier *wmn = params->notifier; | const wmNotifier *wmn = params->notifier; | ||||
| SpaceSpreadsheet *sspreadsheet = static_cast<SpaceSpreadsheet *>(params->area->spacedata.first); | |||||
| switch (wmn->category) { | switch (wmn->category) { | ||||
| case NC_SCENE: { | case NC_SCENE: { | ||||
| switch (wmn->data) { | switch (wmn->data) { | ||||
| case ND_MODE: | case ND_MODE: | ||||
| case ND_FRAME: | case ND_FRAME: | ||||
| case ND_OB_ACTIVE: { | case ND_OB_ACTIVE: { | ||||
| ED_region_tag_redraw(region); | ED_region_tag_redraw(region); | ||||
| Show All 12 Lines | case NC_SPACE: { | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case NC_TEXTURE: | case NC_TEXTURE: | ||||
| case NC_GEOM: { | case NC_GEOM: { | ||||
| ED_region_tag_redraw(region); | ED_region_tag_redraw(region); | ||||
| break; | break; | ||||
| } | } | ||||
| case NC_VIEWER_PATH: { | |||||
| if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) { | |||||
| ED_region_tag_redraw(region); | |||||
| } | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| static void spreadsheet_header_region_init(wmWindowManager *UNUSED(wm), ARegion *region) | static void spreadsheet_header_region_init(wmWindowManager *UNUSED(wm), ARegion *region) | ||||
| { | { | ||||
| ED_region_header_init(region); | ED_region_header_init(region); | ||||
| } | } | ||||
| static void spreadsheet_header_region_draw(const bContext *C, ARegion *region) | static void spreadsheet_header_region_draw(const bContext *C, ARegion *region) | ||||
| { | { | ||||
| spreadsheet_update_context_path(C); | spreadsheet_update_context(C); | ||||
| ED_region_header(C, region); | ED_region_header(C, region); | ||||
| } | } | ||||
| static void spreadsheet_header_region_free(ARegion *UNUSED(region)) | static void spreadsheet_header_region_free(ARegion *UNUSED(region)) | ||||
| { | { | ||||
| } | } | ||||
| static void spreadsheet_header_region_listener(const wmRegionListenerParams *params) | static void spreadsheet_header_region_listener(const wmRegionListenerParams *params) | ||||
| { | { | ||||
| ARegion *region = params->region; | ARegion *region = params->region; | ||||
| const wmNotifier *wmn = params->notifier; | const wmNotifier *wmn = params->notifier; | ||||
| SpaceSpreadsheet *sspreadsheet = static_cast<SpaceSpreadsheet *>(params->area->spacedata.first); | |||||
| switch (wmn->category) { | switch (wmn->category) { | ||||
| case NC_SCENE: { | case NC_SCENE: { | ||||
| switch (wmn->data) { | switch (wmn->data) { | ||||
| case ND_MODE: | case ND_MODE: | ||||
| case ND_OB_ACTIVE: { | case ND_OB_ACTIVE: { | ||||
| ED_region_tag_redraw(region); | ED_region_tag_redraw(region); | ||||
| break; | break; | ||||
| Show All 10 Lines | case NC_SPACE: { | ||||
| ED_region_tag_redraw(region); | ED_region_tag_redraw(region); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| case NC_GEOM: { | case NC_GEOM: { | ||||
| ED_region_tag_redraw(region); | ED_region_tag_redraw(region); | ||||
| break; | break; | ||||
| } | } | ||||
| case NC_VIEWER_PATH: { | |||||
| if (sspreadsheet->object_eval_state == SPREADSHEET_OBJECT_EVAL_STATE_VIEWER_NODE) { | |||||
| ED_region_tag_redraw(region); | |||||
| } | |||||
| break; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| static void spreadsheet_footer_region_init(wmWindowManager *UNUSED(wm), ARegion *region) | static void spreadsheet_footer_region_init(wmWindowManager *UNUSED(wm), ARegion *region) | ||||
| { | { | ||||
| ED_region_header_init(region); | ED_region_header_init(region); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | case NC_TEXTURE: | ||||
| break; | break; | ||||
| } | } | ||||
| spreadsheet_header_region_listener(params); | spreadsheet_header_region_listener(params); | ||||
| } | } | ||||
| static void spreadsheet_dataset_region_draw(const bContext *C, ARegion *region) | static void spreadsheet_dataset_region_draw(const bContext *C, ARegion *region) | ||||
| { | { | ||||
| spreadsheet_update_context_path(C); | spreadsheet_update_context(C); | ||||
| ED_region_panels(C, region); | ED_region_panels(C, region); | ||||
| } | } | ||||
| static void spreadsheet_sidebar_init(wmWindowManager *wm, ARegion *region) | static void spreadsheet_sidebar_init(wmWindowManager *wm, ARegion *region) | ||||
| { | { | ||||
| UI_panel_category_active_set_default(region, "Filters"); | UI_panel_category_active_set_default(region, "Filters"); | ||||
| ED_region_panels_init(wm, region); | ED_region_panels_init(wm, region); | ||||
| wmKeyMap *keymap = WM_keymap_ensure( | wmKeyMap *keymap = WM_keymap_ensure( | ||||
| wm->defaultconf, "Spreadsheet Generic", SPACE_SPREADSHEET, 0); | wm->defaultconf, "Spreadsheet Generic", SPACE_SPREADSHEET, 0); | ||||
| WM_event_add_keymap_handler(®ion->handlers, keymap); | WM_event_add_keymap_handler(®ion->handlers, keymap); | ||||
| } | } | ||||
| static void spreadsheet_right_region_free(ARegion *UNUSED(region)) | static void spreadsheet_right_region_free(ARegion *UNUSED(region)) | ||||
| { | { | ||||
| } | } | ||||
| static void spreadsheet_right_region_listener(const wmRegionListenerParams *UNUSED(params)) | static void spreadsheet_right_region_listener(const wmRegionListenerParams *UNUSED(params)) | ||||
| { | { | ||||
| } | } | ||||
| static void spreadsheet_blend_read_data(BlendDataReader *reader, SpaceLink *sl) | |||||
| { | |||||
| SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl; | |||||
| sspreadsheet->runtime = nullptr; | |||||
| BLO_read_list(reader, &sspreadsheet->row_filters); | |||||
| LISTBASE_FOREACH (SpreadsheetRowFilter *, row_filter, &sspreadsheet->row_filters) { | |||||
| BLO_read_data_address(reader, &row_filter->value_string); | |||||
| } | |||||
| BLO_read_list(reader, &sspreadsheet->columns); | |||||
| LISTBASE_FOREACH (SpreadsheetColumn *, column, &sspreadsheet->columns) { | |||||
| BLO_read_data_address(reader, &column->id); | |||||
| BLO_read_data_address(reader, &column->id->name); | |||||
| /* While the display name is technically runtime data, it is loaded here, otherwise the row | |||||
| * filters might not now their type if their region draws before the main region. | |||||
| * This would ideally be cleared here. */ | |||||
| BLO_read_data_address(reader, &column->display_name); | |||||
| } | |||||
| BKE_viewer_path_blend_read_data(reader, &sspreadsheet->viewer_path); | |||||
| } | |||||
| static void spreadsheet_blend_read_lib(BlendLibReader *reader, ID *parent_id, SpaceLink *sl) | |||||
| { | |||||
| SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl; | |||||
| BKE_viewer_path_blend_read_lib(reader, parent_id->lib, &sspreadsheet->viewer_path); | |||||
| } | |||||
| static void spreadsheet_blend_write(BlendWriter *writer, SpaceLink *sl) | |||||
| { | |||||
| BLO_write_struct(writer, SpaceSpreadsheet, sl); | |||||
| SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl; | |||||
| LISTBASE_FOREACH (SpreadsheetRowFilter *, row_filter, &sspreadsheet->row_filters) { | |||||
| BLO_write_struct(writer, SpreadsheetRowFilter, row_filter); | |||||
| BLO_write_string(writer, row_filter->value_string); | |||||
| } | |||||
| LISTBASE_FOREACH (SpreadsheetColumn *, column, &sspreadsheet->columns) { | |||||
| BLO_write_struct(writer, SpreadsheetColumn, column); | |||||
| BLO_write_struct(writer, SpreadsheetColumnID, column->id); | |||||
| BLO_write_string(writer, column->id->name); | |||||
| /* While the display name is technically runtime data, we write it here, otherwise the row | |||||
| * filters might not now their type if their region draws before the main region. | |||||
| * This would ideally be cleared here. */ | |||||
| BLO_write_string(writer, column->display_name); | |||||
| } | |||||
| BKE_viewer_path_blend_write(writer, &sspreadsheet->viewer_path); | |||||
| } | |||||
| void ED_spacetype_spreadsheet() | void ED_spacetype_spreadsheet() | ||||
| { | { | ||||
| SpaceType *st = MEM_cnew<SpaceType>("spacetype spreadsheet"); | SpaceType *st = MEM_cnew<SpaceType>("spacetype spreadsheet"); | ||||
| ARegionType *art; | ARegionType *art; | ||||
| st->spaceid = SPACE_SPREADSHEET; | st->spaceid = SPACE_SPREADSHEET; | ||||
| STRNCPY(st->name, "Spreadsheet"); | STRNCPY(st->name, "Spreadsheet"); | ||||
| st->create = spreadsheet_create; | st->create = spreadsheet_create; | ||||
| st->free = spreadsheet_free; | st->free = spreadsheet_free; | ||||
| st->init = spreadsheet_init; | st->init = spreadsheet_init; | ||||
| st->duplicate = spreadsheet_duplicate; | st->duplicate = spreadsheet_duplicate; | ||||
| st->operatortypes = spreadsheet_operatortypes; | st->operatortypes = spreadsheet_operatortypes; | ||||
| st->keymap = spreadsheet_keymap; | st->keymap = spreadsheet_keymap; | ||||
| st->id_remap = spreadsheet_id_remap; | st->id_remap = spreadsheet_id_remap; | ||||
| st->blend_read_data = spreadsheet_blend_read_data; | |||||
| st->blend_read_lib = spreadsheet_blend_read_lib; | |||||
| st->blend_write = spreadsheet_blend_write; | |||||
| /* regions: main window */ | /* regions: main window */ | ||||
| art = MEM_cnew<ARegionType>("spacetype spreadsheet region"); | art = MEM_cnew<ARegionType>("spacetype spreadsheet region"); | ||||
| art->regionid = RGN_TYPE_WINDOW; | art->regionid = RGN_TYPE_WINDOW; | ||||
| art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D; | art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D; | ||||
| art->init = spreadsheet_main_region_init; | art->init = spreadsheet_main_region_init; | ||||
| art->draw = spreadsheet_main_region_draw; | art->draw = spreadsheet_main_region_draw; | ||||
| ▲ Show 20 Lines • Show All 57 Lines • Show Last 20 Lines | |||||