diff options
author | Nicholas Bishop <nicholasbishop@gmail.com> | 2015-02-11 14:57:44 +0300 |
---|---|---|
committer | Nicholas Bishop <nicholasbishop@gmail.com> | 2015-02-11 14:57:44 +0300 |
commit | 4bd1c1313ec2d08b843bb9e29c8668a781249548 (patch) | |
tree | 552ab7e761a78dd26a04e25df7f9fe89fc525a52 | |
parent | ad5f50079ac126d104728b4a702717a7bac608c6 (diff) | |
parent | 2d1e07268645b481dbbb924a5f638dc9fa870945 (diff) |
Merge remote-tracking branch 'origin/master' into cycles-ptex-49
53 files changed, 1490 insertions, 698 deletions
diff --git a/intern/cycles/util/util_system.cpp b/intern/cycles/util/util_system.cpp index 6d6bee209b4..7206455debd 100644 --- a/intern/cycles/util/util_system.cpp +++ b/intern/cycles/util/util_system.cpp @@ -164,18 +164,13 @@ static CPUCapabilities& system_cpu_capabilities() static bool caps_init = false; if(!caps_init) { - int result[4], num; //, num_ex; + int result[4], num; memset(&caps, 0, sizeof(caps)); __cpuid(result, 0); num = result[0]; -#if 0 - __cpuid(result, 0x80000000); - num_ex = result[0]; -#endif - if(num >= 1) { __cpuid(result, 0x00000001); caps.mmx = (result[3] & ((int)1 << 23)) != 0; @@ -213,16 +208,6 @@ static CPUCapabilities& system_cpu_capabilities() caps.avx2 = (result[1] & ((int)1 << 5)) != 0; } -#if 0 - if(num_ex >= 0x80000001) { - __cpuid(result, 0x80000001); - caps.x64 = (result[3] & ((int)1 << 29)) != 0; - caps.sse4a = (result[2] & ((int)1 << 6)) != 0; - caps.fma4 = (result[2] & ((int)1 << 16)) != 0; - caps.xop = (result[2] & ((int)1 << 11)) != 0; - } -#endif - system_cpu_capabilities_override(&caps); caps_init = true; diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py index 6fe50c7eeb5..cda3dfe499d 100644 --- a/release/scripts/startup/bl_ui/space_filebrowser.py +++ b/release/scripts/startup/bl_ui/space_filebrowser.py @@ -18,7 +18,7 @@ # <pep8 compliant> import bpy -from bpy.types import Header +from bpy.types import Header, Panel, Menu class FILEBROWSER_HT_header(Header): @@ -81,5 +81,128 @@ class FILEBROWSER_HT_header(Header): row.prop(params, "filter_search", text="", icon='VIEWZOOM') + +class FILEBROWSER_UL_dir(bpy.types.UIList): + def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index): + direntry = item + space = context.space_data + icon = 'NONE' + if active_propname == "system_folders_active": + icon = 'DISK_DRIVE' + if active_propname == "system_bookmarks_active": + icon = 'BOOKMARKS' + if active_propname == "bookmarks_active": + icon = 'BOOKMARKS' + if active_propname == "recent_folders_active": + icon = 'FILE_FOLDER' + + if self.layout_type in {'DEFAULT', 'COMPACT'}: + row = layout.row(align=True) + row.prop(direntry, "name", text="", emboss=False, icon=icon) + + elif self.layout_type in {'GRID'}: + layout.alignment = 'CENTER' + layout.prop(direntry, "path", text="") + + +class FILEBROWSER_PT_system_folders(Panel): + bl_space_type = 'FILE_BROWSER' + bl_region_type = 'TOOLS' + bl_category = "Bookmarks" + bl_label = "System" + + def draw(self, context): + layout = self.layout + space = context.space_data + + if space.system_folders: + row = layout.row() + row.template_list("FILEBROWSER_UL_dir", "system_folders", space, "system_folders", + space, "system_folders_active", item_dyntip_propname="path", rows=1, maxrows=6) + + +class FILEBROWSER_PT_system_bookmarks(Panel): + bl_space_type = 'FILE_BROWSER' + bl_region_type = 'TOOLS' + bl_category = "Bookmarks" + bl_label = "System Bookmarks" + + @classmethod + def poll(cls, context): + return not context.user_preferences.filepaths.hide_system_bookmarks + + def draw(self, context): + layout = self.layout + space = context.space_data + + if space.system_bookmarks: + row = layout.row() + row.template_list("FILEBROWSER_UL_dir", "system_bookmarks", space, "system_bookmarks", + space, "system_bookmarks_active", item_dyntip_propname="path", rows=1, maxrows=6) + + +class FILEBROWSER_MT_bookmarks_specials(Menu): + bl_label = "Bookmarks Specials" + + def draw(self, context): + layout = self.layout + + layout.operator("file.bookmark_move", icon='TRIA_UP_BAR', text="Move To Top").direction = 'TOP' + layout.operator("file.bookmark_move", icon='TRIA_DOWN_BAR', text="Move To Bottom").direction = 'BOTTOM' + + +class FILEBROWSER_PT_bookmarks(Panel): + bl_space_type = 'FILE_BROWSER' + bl_region_type = 'TOOLS' + bl_category = "Bookmarks" + bl_label = "Bookmarks" + + def draw(self, context): + layout = self.layout + space = context.space_data + + if space.bookmarks: + row = layout.row() + num_rows = len(space.bookmarks) + row.template_list("FILEBROWSER_UL_dir", "bookmarks", space, "bookmarks", + space, "bookmarks_active", item_dyntip_propname="path", + rows=(2 if num_rows < 2 else 4), maxrows=6) + + col = row.column(align=True) + col.operator("file.bookmark_add", icon='ZOOMIN', text="") + col.operator("file.bookmark_delete", icon='ZOOMOUT', text="") + col.menu("FILEBROWSER_MT_bookmarks_specials", icon='DOWNARROW_HLT', text="") + + if num_rows > 1: + col.separator() + col.operator("file.bookmark_move", icon='TRIA_UP', text="").direction = 'UP' + col.operator("file.bookmark_move", icon='TRIA_DOWN', text="").direction = 'DOWN' + else: + layout.operator("file.bookmark_add", icon='ZOOMIN') + + +class FILEBROWSER_PT_recent_folders(Panel): + bl_space_type = 'FILE_BROWSER' + bl_region_type = 'TOOLS' + bl_category = "Bookmarks" + bl_label = "Recent" + + @classmethod + def poll(cls, context): + return not context.user_preferences.filepaths.hide_recent_locations + + def draw(self, context): + layout = self.layout + space = context.space_data + + if space.recent_folders: + row = layout.row() + row.template_list("FILEBROWSER_UL_dir", "recent_folders", space, "recent_folders", + space, "recent_folders_active", item_dyntip_propname="path", rows=1, maxrows=6) + + col = row.column(align=True) + col.operator("file.reset_recent", icon='X', text="") + + if __name__ == "__main__": # only for live edit. bpy.utils.register_module(__name__) diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 2c53a247f6d..610a63cb954 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 273 -#define BLENDER_SUBVERSION 6 +#define BLENDER_SUBVERSION 7 /* 262 was the last editmesh release but it has compatibility code for bmesh data */ #define BLENDER_MINVERSION 270 #define BLENDER_MINSUBVERSION 5 diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 491fb46bd1f..73f75f4f96d 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -790,10 +790,10 @@ static ImBuf *postprocess_frame(MovieClip *clip, MovieClipUser *user, ImBuf *ibu } if (postprocess_flag) { - bool disable_red = (postprocess_flag & MOVIECLIP_DISABLE_RED) != 0, - disable_green = (postprocess_flag & MOVIECLIP_DISABLE_GREEN) != 0, - disable_blue = (postprocess_flag & MOVIECLIP_DISABLE_BLUE) != 0, - grayscale = (postprocess_flag & MOVIECLIP_PREVIEW_GRAYSCALE) != 0; + bool disable_red = (postprocess_flag & MOVIECLIP_DISABLE_RED) != 0; + bool disable_green = (postprocess_flag & MOVIECLIP_DISABLE_GREEN) != 0; + bool disable_blue = (postprocess_flag & MOVIECLIP_DISABLE_BLUE) != 0; + bool grayscale = (postprocess_flag & MOVIECLIP_PREVIEW_GRAYSCALE) != 0; if (disable_red || disable_green || disable_blue || grayscale) BKE_tracking_disable_channels(postproc_ibuf, disable_red, disable_green, disable_blue, 1); diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 11a6cb7acc3..6157d63047e 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -2670,8 +2670,8 @@ static void do_gaussian_blur_effect_byte(Sequence *seq, { #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4) GaussianBlurVars *data = seq->effectdata; - const int size_x = (int) (data->size_x + 0.5f), - size_y = (int) (data->size_y + 0.5f); + const int size_x = (int) (data->size_x + 0.5f); + const int size_y = (int) (data->size_y + 0.5f); int i, j; /* Make gaussian weight tabke. */ @@ -2754,8 +2754,8 @@ static void do_gaussian_blur_effect_float(Sequence *seq, { #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4) GaussianBlurVars *data = seq->effectdata; - const int size_x = (int) (data->size_x + 0.5f), - size_y = (int) (data->size_y + 0.5f); + const int size_x = (int) (data->size_x + 0.5f); + const int size_y = (int) (data->size_y + 0.5f); int i, j; /* Make gaussian weight tabke. */ diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 941344cf21e..06d0627fd2c 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -1945,7 +1945,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3], float dist; closest_to_line_segment_v3(ve, opco, nv1, nv2); - sub_v3_v3v3(ve, opco, ve); + sub_v3_v3v3(ve, opco, ve); dist = normalize_v3(ve); if ((dist < outerfacethickness)&&(dist < mindistedge )) { copy_v3_v3(coledge, ve); diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c index f002ea54b32..5febf720b30 100644 --- a/source/blender/blenlib/intern/noise.c +++ b/source/blender/blenlib/intern/noise.c @@ -278,8 +278,8 @@ static float npfade(float t) static float grad(int hash_val, float x, float y, float z) { int h = hash_val & 15; /* CONVERT LO 4 BITS OF HASH CODE */ - float u = h < 8 ? x : y, /* INTO 12 GRADIENT DIRECTIONS. */ - v = h < 4 ? y : h == 12 || h == 14 ? x : z; + float u = h < 8 ? x : y; /* INTO 12 GRADIENT DIRECTIONS. */ + float v = h < 4 ? y : h == 12 || h == 14 ? x : z; return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); } diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c index 4ca1a44d64e..572566df6a2 100644 --- a/source/blender/blenloader/intern/versioning_270.c +++ b/source/blender/blenloader/intern/versioning_270.c @@ -51,6 +51,7 @@ #include "BKE_main.h" #include "BKE_node.h" +#include "BKE_screen.h" #include "BLI_math.h" #include "BLI_listbase.h" @@ -60,6 +61,7 @@ #include "readfile.h" +#include "MEM_guardedalloc.h" static void do_version_constraints_radians_degrees_270_1(ListBase *lb) { @@ -561,4 +563,32 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main) FOREACH_NODETREE_END } } + + if (!MAIN_VERSION_ATLEAST(main, 273, 7)) { + bScreen *scr; + ScrArea *sa; + SpaceLink *sl; + ARegion *ar; + + for (scr = main->screen.first; scr; scr = scr->id.next) { + /* Remove old deprecated region from filebrowsers */ + for (sa = scr->areabase.first; sa; sa = sa->next) { + for (sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_FILE) { + for (ar = sl->regionbase.first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_CHANNELS) { + break; + } + } + + if (ar) { + /* Free old deprecated 'channel' region... */ + BKE_area_region_free(NULL, ar); + BLI_freelinkN(&sl->regionbase, ar); + } + } + } + } + } + } } diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index a32f28169f6..45da3ce85bc 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -40,6 +40,8 @@ #include "BKE_customdata.h" #include "BKE_multires.h" +#include "BLI_memarena.h" +#include "BLI_linklist.h" #include "bmesh.h" #include "intern/bmesh_private.h" @@ -893,3 +895,179 @@ void BM_elem_float_data_set(CustomData *cd, void *element, int type, const float float *f = CustomData_bmesh_get(cd, ((BMHeader *)element)->data, type); if (f) *f = val; } + +/** \name Loop interpolation functions: BM_vert_loop_groups_data_layer_*** + * + * Handling loop custom-data such as UV's, while keeping contiguous fans is rather tedious. + * Especially when a verts loops can have multiple CustomData layers, + * and each layer can have multiple (different) contiguous fans. + * Said differently, a single vertices loops may span multiple UV islands. + * + * These functions snapshot vertices loops, storing each contiguous fan in its own group. + * The caller can manipulate the loops, then re-combine the CustomData values. + * + * While these functions don't explicitly handle multiple layers at once, + * the caller can simply store its own list. + * + * \note Currently they are averaged back together (weighted by loop angle) + * but we could copy add other methods to re-combine CustomData-Loop-Fans. + * + * \{ */ + +struct LoopWalkCtx { + /* same for all groups */ + int type; + int cd_layer_offset; + MemArena *arena; + + /* --- Per loop fan vars --- */ + + /* reference for this contiguous fan */ + const void *data_ref; + int data_len; + /* both arrays the size of the 'BM_vert_face_count(v)' + * each contiguous fan gets a slide of these arrays */ + void **data_array; + float *weight_array; + /* accumulate 'LoopGroupCD.weight' to make unit length */ + float weight_accum; +}; + +/* Store vars to pass into 'CustomData_bmesh_interp' */ +struct LoopGroupCD { + /* direct customdata pointer array */ + void **data; + /* weights (aligned with 'data') */ + float *data_weights; + /* number of loops in the fan */ + int data_len; +}; + +static void bm_loop_walk_add(struct LoopWalkCtx *lwc, BMLoop *l) +{ + const float w = BM_loop_calc_face_angle(l); + BM_elem_flag_enable(l, BM_ELEM_INTERNAL_TAG); + lwc->data_array[lwc->data_len] = BM_ELEM_CD_GET_VOID_P(l, lwc->cd_layer_offset); + lwc->weight_array[lwc->data_len] = w; + lwc->weight_accum += w; + + lwc->data_len += 1; +} + +/** + * called recursively, keep stack-usage minimal. + * + * \note called for fan matching so we're pretty much safe not to break the stack + */ +static void bm_loop_walk_data(struct LoopWalkCtx *lwc, BMLoop *l_walk) +{ + BLI_assert(CustomData_data_equals(lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_walk, lwc->cd_layer_offset))); + BLI_assert(BM_elem_flag_test(l_walk, BM_ELEM_INTERNAL_TAG) == false); + + bm_loop_walk_add(lwc, l_walk); + +#define WALK_LOOP(l_test) \ +{ \ + BMLoop *l_other = l_test; \ + if (l_other->v != l_walk->v) { \ + l_other = l_other->next; \ + } \ + BLI_assert(l_other->v == l_walk->v); \ + if (!BM_elem_flag_test(l_other, BM_ELEM_INTERNAL_TAG)) { \ + if (CustomData_data_equals(lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_other, lwc->cd_layer_offset))) { \ + bm_loop_walk_data(lwc, l_other); \ + } \ + } \ +} (void)0 + + if (l_walk->radial_next != l_walk) { + WALK_LOOP(l_walk->radial_next); + } + + if (l_walk->prev->radial_next != l_walk->prev) { + WALK_LOOP(l_walk->prev->radial_next); + } +} + +LinkNode *BM_vert_loop_groups_data_layer_create(BMesh *bm, BMVert *v, int layer_n, MemArena *arena) +{ + struct LoopWalkCtx lwc; + LinkNode *groups = NULL; + BMLoop *l; + BMIter liter; + int loop_num; + + + lwc.type = bm->ldata.layers[layer_n].type; + lwc.cd_layer_offset = bm->ldata.layers[layer_n].offset; + lwc.arena = arena; + + loop_num = 0; + BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { + BM_elem_flag_disable(l, BM_ELEM_INTERNAL_TAG); + loop_num++; + } + + lwc.data_len = 0; + lwc.data_array = BLI_memarena_alloc(lwc.arena, sizeof(void *) * loop_num); + lwc.weight_array = BLI_memarena_alloc(lwc.arena, sizeof(float) * loop_num); + + BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { + if (!BM_elem_flag_test(l, BM_ELEM_INTERNAL_TAG)) { + struct LoopGroupCD *lf = BLI_memarena_alloc(lwc.arena, sizeof(*lf)); + int len_prev = lwc.data_len; + + lwc.data_ref = BM_ELEM_CD_GET_VOID_P(l, lwc.cd_layer_offset); + + /* assign len-last */ + lf->data = &lwc.data_array[lwc.data_len]; + lf->data_weights = &lwc.weight_array[lwc.data_len]; + lwc.weight_accum = 0.0f; + + /* new group */ + bm_loop_walk_data(&lwc, l); + lf->data_len = lwc.data_len - len_prev; + + if (LIKELY(lwc.weight_accum != 0.0f)) { + mul_vn_fl(lf->data_weights, lf->data_len, 1.0f / lwc.weight_accum); + } + else { + fill_vn_fl(lf->data_weights, lf->data_len, 1.0f / (float)lf->data_len); + } + + BLI_linklist_prepend_arena(&groups, lf, lwc.arena); + } + } + + BLI_assert(lwc.data_len == loop_num); + + return groups; +} + +static void bm_vert_loop_groups_data_layer_merge__single(BMesh *bm, void *lf_p, void *data, int type) +{ + struct LoopGroupCD *lf = lf_p; + int i; + + CustomData_bmesh_interp(&bm->ldata, lf->data, lf->data_weights, NULL, lf->data_len, data); + + for (i = 0; i < lf->data_len; i++) { + CustomData_copy_elements(type, data, lf->data[i], 1); + } +} + +/** + * Take existing custom data and merge each fan's data. + */ +void BM_vert_loop_groups_data_layer_merge(BMesh *bm, LinkNode *groups, int layer_n) +{ + int type = bm->ldata.layers[layer_n].type; + int size = CustomData_sizeof(type); + void *data = alloca(size); + + do { + bm_vert_loop_groups_data_layer_merge__single(bm, groups->link, data, type); + } while ((groups = groups->next)); +} + +/** \} */
\ No newline at end of file diff --git a/source/blender/bmesh/intern/bmesh_interp.h b/source/blender/bmesh/intern/bmesh_interp.h index c605ad31ae7..cd6d5e2731d 100644 --- a/source/blender/bmesh/intern/bmesh_interp.h +++ b/source/blender/bmesh/intern/bmesh_interp.h @@ -27,6 +27,9 @@ * \ingroup bmesh */ +struct LinkNode; +struct MemArena; + void BM_loop_interp_multires(BMesh *bm, BMLoop *target, BMFace *source); void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source); @@ -49,5 +52,7 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, const bool do_vertex, const bool do_multires); void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f); +struct LinkNode *BM_vert_loop_groups_data_layer_create(BMesh *bm, BMVert *v, int layer_n, struct MemArena *arena); +void BM_vert_loop_groups_data_layer_merge(BMesh *bm, struct LinkNode *groups, int layer_n); #endif /* __BMESH_INTERP_H__ */ diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index b25572ed8e2..a418ade6cc1 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -2896,8 +2896,9 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v) nwire++; /* If edge beveling, exclude wire edges from edges array. * Mark this edge as "chosen" so loop below won't choose it. */ - if (!bp->vertex_only) + if (!bp->vertex_only) { BM_BEVEL_EDGE_TAG_ENABLE(bme); + } } } if (!first_bme) diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp index 2aab9b6e7d3..38855013ee1 100644 --- a/source/blender/collada/collada_internal.cpp +++ b/source/blender/collada/collada_internal.cpp @@ -187,73 +187,77 @@ void TransformBase::decompose(float mat[4][4], float *loc, float eul[3], float q * must obviously be removed too, otherwise they would be heavily misinterpreted. */ const unsigned char translate_start_name_map[256] = { - 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 95, 95, 95, 95, 95, 95, - 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 192, - 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 95, 216, - 217, 218, 219, 220, 221, 222, 223, 224, - 225, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 95, 248, - 249, 250, 251, 252, 253, 254, 255 + + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 95, 95, 95, 95, 95, + 95, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 95, 95, 95, 95, 95, + + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255 }; const unsigned char translate_name_map[256] = { - 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 45, 95, 95, 48, - 49, 50, 51, 52, 53, 54, 55, 56, - 57, 95, 95, 95, 95, 95, 95, 95, - 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 95, 95, 95, 95, 95, 95, - 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 183, 95, - 95, 95, 95, 95, 95, 95, 95, 192, - 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 95, 216, - 217, 218, 219, 220, 221, 222, 223, 224, - 225, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 95, 248, - 249, 250, 251, 252, 253, 254, 255 + + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 95, 95, 95, 45, 95, 95, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 95, 95, 95, 95, 95, 95, + 95, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 90, 95, 95, 95, 95, 95, + 95, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 95, 95, 95, 95, 95, + + 128, 129, 130, 131, 132, 133, 134, 135, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255 }; typedef std::map< std::string, std::vector<std::string> > map_string_list; diff --git a/source/blender/compositor/intern/COM_MemoryBuffer.cpp b/source/blender/compositor/intern/COM_MemoryBuffer.cpp index 37035c50d2c..9e6e5a423f9 100644 --- a/source/blender/compositor/intern/COM_MemoryBuffer.cpp +++ b/source/blender/compositor/intern/COM_MemoryBuffer.cpp @@ -187,11 +187,11 @@ void MemoryBuffer::addPixel(int x, int y, const float color[4]) y >= this->m_rect.ymin && y < this->m_rect.ymax) { const int offset = (this->m_width * (y - this->m_rect.ymin) + x - this->m_rect.xmin) * this->m_num_channels; - float *dst = &this->m_buffer[offset]; - const float *src = color; - for (int i = 0; i < this->m_num_channels ; i++, dst++, src++) { - *dst += *src; - } + float *dst = &this->m_buffer[offset]; + const float *src = color; + for (int i = 0; i < this->m_num_channels ; i++, dst++, src++) { + *dst += *src; + } } } diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 895fc6608e2..20279caaf7c 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -1051,8 +1051,10 @@ static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy, /* turn on smooth lines (i.e. anti-aliasing) */ glEnable(GL_LINE_SMOOTH); - glEnable(GL_POLYGON_SMOOTH); - glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); + /* XXX: turn on some way of ensuring that the polygon edges get smoothed + * GL_POLYGON_SMOOTH is nasty and shouldn't be used, as it ends up + * creating internal white rays due to the ways it accumulates stuff + */ /* turn on alpha-blending */ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); @@ -1064,7 +1066,6 @@ static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy, /* turn off alpha blending, then smooth lines */ glDisable(GL_BLEND); // alpha blending glDisable(GL_LINE_SMOOTH); // smooth lines - glDisable(GL_POLYGON_SMOOTH); // smooth poly lines /* restore initial gl conditions */ glLineWidth(1.0); diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h index f2a6ce0b129..b81ea55cca8 100644 --- a/source/blender/editors/include/ED_fileselect.h +++ b/source/blender/editors/include/ED_fileselect.h @@ -108,5 +108,40 @@ int ED_file_extension_icon(const char *relname); void ED_file_read_bookmarks(void); +void ED_file_change_dir(struct bContext *C, const bool checkdir); + +/* File menu stuff */ + +typedef enum FSMenuCategory { + FS_CATEGORY_SYSTEM, + FS_CATEGORY_SYSTEM_BOOKMARKS, + FS_CATEGORY_BOOKMARKS, + FS_CATEGORY_RECENT +} FSMenuCategory; + +typedef enum FSMenuInsert { + FS_INSERT_SORTED = (1 << 0), + FS_INSERT_SAVE = (1 << 1), + FS_INSERT_FIRST = (1 << 2), /* moves the item to the front of the list when its not already there */ + FS_INSERT_LAST = (1 << 3), /* just append to preseve delivered order */ +} FSMenuInsert; + +struct FSMenu; +struct FSMenuEntry; + +struct FSMenu *ED_fsmenu_get(void); +struct FSMenuEntry *ED_fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory category); +void ED_fsmenu_set_category(struct FSMenu *fsmenu, FSMenuCategory category, struct FSMenuEntry *fsm_head); + +int ED_fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category); + +struct FSMenuEntry *ED_fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int index); + +char *ED_fsmenu_entry_get_path(struct FSMenuEntry *fsentry); +void ED_fsmenu_entry_set_path(struct FSMenuEntry *fsentry, const char *path); + +char *ED_fsmenu_entry_get_name(struct FSMenuEntry *fsentry); +void ED_fsmenu_entry_set_name(struct FSMenuEntry *fsentry, const char *name); + #endif /* __ED_FILESELECT_H__ */ diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 590ab1d694d..b1bb48b58ed 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -348,6 +348,9 @@ typedef void (*uiButHandleRenameFunc)(struct bContext *C, void *arg, char *origs typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2); typedef int (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg); typedef void (*uiButSearchFunc)(const struct bContext *C, void *arg, const char *str, uiSearchItems *items); +/* Must return allocated string. */ +typedef char *(*uiButToolTipFunc)(struct bContext *C, void *argN, const char *tip); + typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event); /* Menu Callbacks */ @@ -678,6 +681,8 @@ void UI_but_func_drawextra_set( void (*func)(const struct bContext *C, void *, void *, void *, struct rcti *rect), void *arg1, void *arg2); +void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *argN); + bool UI_textbutton_activate_rna(const struct bContext *C, struct ARegion *ar, const void *rna_poin_data, const char *rna_prop_id); bool UI_textbutton_activate_but(const struct bContext *C, uiBut *but); @@ -907,7 +912,8 @@ void uiTemplateNodeSocket(uiLayout *layout, struct bContext *C, float *color); #define UI_UL_DEFAULT_CLASS_NAME "UI_UL_list" void uiTemplateList(uiLayout *layout, struct bContext *C, const char *listtype_name, const char *list_id, struct PointerRNA *dataptr, const char *propname, struct PointerRNA *active_dataptr, - const char *active_propname, int rows, int maxrows, int layout_type, int columns); + const char *active_propname, const char *item_dyntip_propname, + int rows, int maxrows, int layout_type, int columns); void uiTemplateNodeLink(uiLayout *layout, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input); void uiTemplateNodeView(uiLayout *layout, struct bContext *C, struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *input); void uiTemplateTextureUser(uiLayout *layout, struct bContext *C); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 8fa604d57cb..bad09a7c441 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -716,6 +716,7 @@ static bool ui_but_update_from_old_block(const bContext *C, uiBlock *block, uiBu if (oldbut->poin != (char *)oldbut) { SWAP(char *, oldbut->poin, but->poin); SWAP(void *, oldbut->func_argN, but->func_argN); + SWAP(void *, oldbut->tip_argN, but->tip_argN); } oldbut->flag = (oldbut->flag & ~flag_copy) | (but->flag & flag_copy); @@ -2440,6 +2441,10 @@ static void ui_but_free(const bContext *C, uiBut *but) MEM_freeN(but->func_argN); } + if (but->tip_argN) { + MEM_freeN(but->tip_argN); + } + if (but->active) { /* XXX solve later, buttons should be free-able without context ideally, * however they may have open tooltips or popup windows, which need to @@ -4113,6 +4118,15 @@ void UI_but_func_complete_set(uiBut *but, uiButCompleteFunc func, void *arg) but->autofunc_arg = arg; } +void UI_but_func_tooltip_set(uiBut *but, uiButToolTipFunc func, void *argN) +{ + but->tip_func = func; + if (but->tip_argN) { + MEM_freeN(but->tip_argN); + } + but->tip_argN = argN; +} + uiBut *uiDefBlockBut(uiBlock *block, uiBlockCreateFunc func, void *arg, const char *str, int x, int y, short width, short height, const char *tip) { uiBut *but = ui_def_but(block, UI_BTYPE_BLOCK, 0, str, x, y, width, height, arg, 0.0, 0.0, 0.0, 0.0, tip); @@ -4383,7 +4397,10 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...) } } else if (type == BUT_GET_TIP) { - if (but->tip && but->tip[0]) + if (but->tip_func) { + tmp = but->tip_func(C, but->tip_argN, but->tip); + } + else if (but->tip && but->tip[0]) tmp = BLI_strdup(but->tip); else type = BUT_GET_RNA_TIP; /* Fail-safe solution... */ diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 458e268170f..03816a255ad 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -254,7 +254,11 @@ struct uiBut { uiLink *link; short linkto[2]; /* region relative coords */ - const char *tip, *lockstr; + const char *tip; + uiButToolTipFunc tip_func; + void *tip_argN; + + const char *lockstr; BIFIconID icon; bool lock; diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 5ac991cbd94..b3c31a1a644 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2833,9 +2833,27 @@ static void uilist_resize_update_cb(bContext *UNUSED(C), void *arg1, void *UNUSE } } +static void *uilist_item_use_dynamic_tooltip(PointerRNA *itemptr, const char *propname) +{ + if (propname && propname[0] && itemptr && itemptr->data) { + PropertyRNA *prop = RNA_struct_find_property(itemptr, propname); + + if (prop && (RNA_property_type(prop) == PROP_STRING)) { + return RNA_property_string_get_alloc(itemptr, prop, NULL, 0, NULL); + } + } + return NULL; +} + +static char *uilist_item_tooltip_func(bContext *UNUSED(C), void *argN, const char *tip) +{ + char *dyn_tooltip = argN; + return BLI_sprintfN("%s - %s", tip, dyn_tooltip); +} + void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, const char *list_id, PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname, - int rows, int maxrows, int layout_type, int columns) + const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns) { uiListType *ui_list_type; uiList *ui_list = NULL; @@ -3049,6 +3067,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co /* create list items */ for (i = layoutdata.start_idx; i < layoutdata.end_idx; i++) { PointerRNA *itemptr = &items_ptr[i].item; + void *dyntip_data; int org_i = items_ptr[i].org_idx; int flt_flag = items_ptr[i].flt_flag; subblock = uiLayoutGetBlock(col); @@ -3061,7 +3080,11 @@ void uiTemplateList(uiLayout *layout, bContext *C, const char *listtype_name, co sub = uiLayoutRow(overlap, false); but = uiDefButR_prop(subblock, UI_BTYPE_LISTROW, 0, "", 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, - active_dataptr, activeprop, 0, 0, org_i, 0, 0, TIP_("Double click to rename")); + active_dataptr, activeprop, 0, 0, org_i, 0, 0, + TIP_("Double click to rename")); + if ((dyntip_data = uilist_item_use_dynamic_tooltip(itemptr, item_dyntip_propname))) { + UI_but_func_tooltip_set(but, uilist_item_tooltip_func, dyntip_data); + } sub = uiLayoutRow(overlap, false); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 16b74c3bddd..512784437d6 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -2745,7 +2745,7 @@ static void mesh_separate_material_assign_mat_nr(Object *ob, const short mat_nr) } if (mat_nr < *totcolp) { - ma_obdata = (*matarar)[mat_nr]; + ma_obdata = (*matarar)[mat_nr]; } else { ma_obdata = NULL; diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index dee216d9c73..00d79b22e99 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -895,7 +895,7 @@ int ED_mesh_mirror_get_vert(Object *ob, int index) index_mirr = eve_mirr ? BM_elem_index_get(eve_mirr) : -1; } else { - index_mirr = mesh_get_x_mirror_vert(ob, index, use_topology); + index_mirr = mesh_get_x_mirror_vert(ob, index, use_topology); } return index_mirr; diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index b04f1d3e738..8fcd91b7791 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -1146,8 +1146,8 @@ BLI_INLINE void rcti_scale_coords(rcti *scaled_rect, const rcti *rect, static void render_update_resolution(Render *re, const RenderPreview *rp, bool use_border, const rcti *clip_rect) { - int winx = rp->ar->winx / rp->resolution_divider, - winy = rp->ar->winy / rp->resolution_divider; + int winx = rp->ar->winx / rp->resolution_divider; + int winy = rp->ar->winy / rp->resolution_divider; if (use_border) { rcti scaled_cliprct; rcti_scale_coords(&scaled_cliprct, clip_rect, @@ -1461,7 +1461,7 @@ static void render_view3d_do(RenderEngine *engine, const bContext *C) engine->flag &= ~RE_ENGINE_DO_UPDATE; } -/* callback for render engine , on changes */ +/* callback for render engine, on changes */ void render_view3d_update(RenderEngine *engine, const bContext *C) { /* this shouldn't be needed and causes too many database rebuilds, but we diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 83b22bb1a8a..4225b4bbd6e 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1478,7 +1478,7 @@ void region_toggle_hidden(bContext *C, ARegion *ar, const bool do_fade) /* exported to all editors, uses fading default */ void ED_region_toggle_hidden(bContext *C, ARegion *ar) { - region_toggle_hidden(C, ar, 1); + region_toggle_hidden(C, ar, true); } /** diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index f338fa160f5..deb6c7b4ab2 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -2093,7 +2093,7 @@ void ED_update_for_newframe(Main *bmain, Scene *scene, int UNUSED(mute)) /* this function applies the changes too */ BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, layers); - //if ( (CFRA>1) && (!mute) && (scene->r.audio.flag & AUDIO_SCRUB)) + //if ((CFRA > 1) && (!mute) && (scene->r.audio.flag & AUDIO_SCRUB)) // audiostream_scrub( CFRA ); /* 3d window, preview */ diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 5ce3517696e..f3c6781b0fa 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -242,7 +242,7 @@ static int sound_update_animation_flags_exec(bContext *C, wmOperator *UNUSED(op) } SEQ_END - fcu = id_data_find_fcurve(&scene->id, scene, &RNA_Scene, "audio_volume", 0, &driven); + fcu = id_data_find_fcurve(&scene->id, scene, &RNA_Scene, "audio_volume", 0, &driven); if (fcu || driven) scene->audio.flag |= AUDIO_VOLUME_ANIMATED; else diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 57611930e99..9fe6ed73205 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -119,7 +119,7 @@ void file_draw_buttons(const bContext *C, ARegion *ar) /* exception to make space for collapsed region icon */ for (artmp = CTX_wm_area(C)->regionbase.first; artmp; artmp = artmp->next) { - if (artmp->regiontype == RGN_TYPE_CHANNELS && artmp->flag & RGN_FLAG_HIDDEN) { + if (artmp->regiontype == RGN_TYPE_TOOLS && artmp->flag & RGN_FLAG_HIDDEN) { chan_offs = 16; min_x += chan_offs; available_w -= chan_offs; diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index 7147353b3f1..31d479b4617 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -38,7 +38,7 @@ struct ARegionType; struct SpaceFile; /* file_ops.c */ -struct ARegion *file_buttons_region(struct ScrArea *sa); +struct ARegion *file_tools_region(struct ScrArea *sa); /* file_draw.c */ #define TILE_BORDER_X (UI_UNIT_X / 4) @@ -66,6 +66,7 @@ void FILE_OT_select_border(struct wmOperatorType *ot); void FILE_OT_select_bookmark(struct wmOperatorType *ot); void FILE_OT_bookmark_add(struct wmOperatorType *ot); void FILE_OT_bookmark_delete(struct wmOperatorType *ot); +void FILE_OT_bookmark_move(struct wmOperatorType *ot); void FILE_OT_reset_recent(wmOperatorType *ot); void FILE_OT_hidedot(struct wmOperatorType *ot); void FILE_OT_execute(struct wmOperatorType *ot); @@ -103,7 +104,6 @@ float file_shorten_string(char *string, float w, int front); float file_string_width(const char *str); float file_font_pointsize(void); -void file_change_dir(bContext *C, int checkdir); int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file); int autocomplete_directory(struct bContext *C, char *str, void *arg_v); int autocomplete_file(struct bContext *C, char *str, void *arg_v); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index ba6f91e8301..a0e312e72ef 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -31,6 +31,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_fileops_types.h" +#include "BLI_linklist.h" #include "BLO_readfile.h" @@ -197,7 +198,7 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen) BLI_add_slash(params->dir); } - file_change_dir(C, 0); + ED_file_change_dir(C, false); retval = FILE_SELECT_DIR; } } @@ -453,6 +454,7 @@ void FILE_OT_select_all_toggle(wmOperatorType *ot) /* ---------- BOOKMARKS ----------- */ +/* Note we could get rid of this one, but it's used by some addon so... Does not hurt keeping it around for now. */ static int bookmark_select_exec(bContext *C, wmOperator *op) { SpaceFile *sfile = CTX_wm_space_file(C); @@ -464,7 +466,7 @@ static int bookmark_select_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "dir", entry); BLI_strncpy(params->dir, entry, sizeof(params->dir)); BLI_cleanup_dir(G.main->name, params->dir); - file_change_dir(C, 1); + ED_file_change_dir(C, true); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); } @@ -494,17 +496,18 @@ static int bookmark_add_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); SpaceFile *sfile = CTX_wm_space_file(C); - struct FSMenu *fsmenu = fsmenu_get(); + struct FSMenu *fsmenu = ED_fsmenu_get(); struct FileSelectParams *params = ED_fileselect_get_params(sfile); if (params->dir[0] != '\0') { char name[FILE_MAX]; - fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir, FS_INSERT_SAVE); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir, NULL, FS_INSERT_SAVE); BLI_make_file_string("/", name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); fsmenu_write_file(fsmenu, name); } + ED_area_tag_refresh(sa); ED_area_tag_redraw(sa); return OPERATOR_FINISHED; } @@ -524,17 +527,27 @@ void FILE_OT_bookmark_add(wmOperatorType *ot) static int bookmark_delete_exec(bContext *C, wmOperator *op) { ScrArea *sa = CTX_wm_area(C); - struct FSMenu *fsmenu = fsmenu_get(); - int nentries = fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS); - - if (RNA_struct_find_property(op->ptr, "index")) { - int index = RNA_int_get(op->ptr, "index"); + SpaceFile *sfile = CTX_wm_space_file(C); + struct FSMenu *fsmenu = ED_fsmenu_get(); + int nentries = ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS); + + PropertyRNA *prop = RNA_struct_find_property(op->ptr, "index"); + + if (prop) { + int index; + if (RNA_property_is_set(op->ptr, prop)) { + index = RNA_property_int_get(op->ptr, prop); + } + else { /* if index unset, use active bookmark... */ + index = sfile->bookmarknr; + } if ((index > -1) && (index < nentries)) { char name[FILE_MAX]; fsmenu_remove_entry(fsmenu, FS_CATEGORY_BOOKMARKS, index); BLI_make_file_string("/", name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); fsmenu_write_file(fsmenu, name); + ED_area_tag_refresh(sa); ED_area_tag_redraw(sa); } } @@ -560,19 +573,99 @@ void FILE_OT_bookmark_delete(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } +enum { + FILE_BOOKMARK_MOVE_TOP = -2, + FILE_BOOKMARK_MOVE_UP = -1, + FILE_BOOKMARK_MOVE_DOWN = 1, + FILE_BOOKMARK_MOVE_BOTTOM = 2, +}; + +static int bookmark_move_exec(bContext *C, wmOperator *op) +{ + ScrArea *sa = CTX_wm_area(C); + SpaceFile *sfile = CTX_wm_space_file(C); + struct FSMenu *fsmenu = ED_fsmenu_get(); + struct FSMenuEntry *fsmentry = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS); + const struct FSMenuEntry *fsmentry_org = fsmentry; + + char fname[FILE_MAX]; + + const int direction = RNA_enum_get(op->ptr, "direction"); + const int totitems = ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS); + const int act_index = sfile->bookmarknr; + int new_index; + + switch (direction) { + case FILE_BOOKMARK_MOVE_TOP: + new_index = 0; + break; + case FILE_BOOKMARK_MOVE_BOTTOM: + new_index = totitems - 1; + break; + case FILE_BOOKMARK_MOVE_UP: + case FILE_BOOKMARK_MOVE_DOWN: + default: + new_index = (totitems + act_index + direction) % totitems; + break; + } + + if (new_index == act_index) { + return OPERATOR_CANCELLED; + } + + BLI_linklist_move_item((LinkNode **)&fsmentry, act_index, new_index); + if (fsmentry != fsmentry_org) { + ED_fsmenu_set_category(fsmenu, FS_CATEGORY_BOOKMARKS, fsmentry); + } + + /* Need to update active bookmark number. */ + sfile->bookmarknr = new_index; + + BLI_make_file_string("/", fname, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); + fsmenu_write_file(fsmenu, fname); + + ED_area_tag_redraw(sa); + return OPERATOR_FINISHED; +} + +void FILE_OT_bookmark_move(wmOperatorType *ot) +{ + static EnumPropertyItem slot_move[] = { + {FILE_BOOKMARK_MOVE_TOP, "TOP", 0, "Top", "Top of the list"}, + {FILE_BOOKMARK_MOVE_UP, "UP", 0, "Up", ""}, + {FILE_BOOKMARK_MOVE_DOWN, "DOWN", 0, "Down", ""}, + {FILE_BOOKMARK_MOVE_BOTTOM, "BOTTOM", 0, "Bottom", "Bottom of the list"}, + { 0, NULL, 0, NULL, NULL } + }; + + /* identifiers */ + ot->name = "Move Bookmark"; + ot->idname = "FILE_OT_bookmark_move"; + ot->description = "Move the active bookmark up/down in the list"; + + /* api callbacks */ + ot->poll = ED_operator_file_active; + ot->exec = bookmark_move_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER; /* No undo! */ + + RNA_def_enum(ot->srna, "direction", slot_move, 0, "Direction", "Direction to move, UP or DOWN"); +} + static int reset_recent_exec(bContext *C, wmOperator *UNUSED(op)) { ScrArea *sa = CTX_wm_area(C); char name[FILE_MAX]; - struct FSMenu *fsmenu = fsmenu_get(); + struct FSMenu *fsmenu = ED_fsmenu_get(); - while (fsmenu_get_entry(fsmenu, FS_CATEGORY_RECENT, 0) != NULL) { + while (ED_fsmenu_get_entry(fsmenu, FS_CATEGORY_RECENT, 0) != NULL) { fsmenu_remove_entry(fsmenu, FS_CATEGORY_RECENT, 0); } BLI_make_file_string("/", name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); fsmenu_write_file(fsmenu, name); ED_area_tag_redraw(sa); - + return OPERATOR_FINISHED; } @@ -847,11 +940,13 @@ int file_exec(bContext *C, wmOperator *exec_op) file_sfile_to_operator(op, sfile, filepath); if (BLI_exists(sfile->params->dir)) { - fsmenu_insert_entry(fsmenu_get(), FS_CATEGORY_RECENT, sfile->params->dir, FS_INSERT_SAVE | FS_INSERT_FIRST); + fsmenu_insert_entry(ED_fsmenu_get(), FS_CATEGORY_RECENT, sfile->params->dir, NULL, + FS_INSERT_SAVE | FS_INSERT_FIRST); } - BLI_make_file_string(G.main->name, filepath, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); - fsmenu_write_file(fsmenu_get(), filepath); + BLI_make_file_string(G.main->name, filepath, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), + BLENDER_BOOKMARK_FILE); + fsmenu_write_file(ED_fsmenu_get(), filepath); WM_event_fileselect_event(wm, op, EVT_FILESELECT_EXEC); } @@ -890,14 +985,14 @@ int file_parent_exec(bContext *C, wmOperator *UNUSED(unused)) if (sfile->params->type == FILE_LOADLIB) { char tdir[FILE_MAX], tgroup[FILE_MAX]; if (BLO_is_a_library(sfile->params->dir, tdir, tgroup)) { - file_change_dir(C, 0); + ED_file_change_dir(C, false); } else { - file_change_dir(C, 1); + ED_file_change_dir(C, true); } } else { - file_change_dir(C, 1); + ED_file_change_dir(C, true); } WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); } @@ -925,7 +1020,7 @@ static int file_refresh_exec(bContext *C, wmOperator *UNUSED(unused)) { wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = CTX_wm_space_file(C); - struct FSMenu *fsmenu = fsmenu_get(); + struct FSMenu *fsmenu = ED_fsmenu_get(); ED_fileselect_clear(wm, sfile); @@ -962,7 +1057,7 @@ int file_previous_exec(bContext *C, wmOperator *UNUSED(unused)) folderlist_popdir(sfile->folders_prev, sfile->params->dir); folderlist_pushdir(sfile->folders_next, sfile->params->dir); - file_change_dir(C, 1); + ED_file_change_dir(C, true); } WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); @@ -994,7 +1089,7 @@ int file_next_exec(bContext *C, wmOperator *UNUSED(unused)) // update folders_prev so we can check for it in folderlist_clear_next() folderlist_pushdir(sfile->folders_prev, sfile->params->dir); - file_change_dir(C, 1); + ED_file_change_dir(C, true); } WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); @@ -1184,7 +1279,7 @@ int file_directory_new_exec(bContext *C, wmOperator *op) if (RNA_boolean_get(op->ptr, "open")) { BLI_strncpy(sfile->params->dir, path, sizeof(sfile->params->dir)); - file_change_dir(C, 1); + ED_file_change_dir(C, true); } WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); @@ -1289,7 +1384,7 @@ void file_directory_enter_handle(bContext *C, void *UNUSED(arg_unused), void *UN if (BLI_exists(sfile->params->dir)) { /* if directory exists, enter it immediately */ - file_change_dir(C, 1); + ED_file_change_dir(C, true); /* don't do for now because it selects entire text instead of * placing cursor at the end */ @@ -1358,7 +1453,7 @@ void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg BLI_cleanup_dir(G.main->name, filepath); BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir)); sfile->params->file[0] = '\0'; - file_change_dir(C, 1); + ED_file_change_dir(C, true); UI_textbutton_activate_but(C, but); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL); } @@ -1369,7 +1464,7 @@ void file_filename_enter_handle(bContext *C, void *UNUSED(arg_unused), void *arg BLI_cleanup_dir(G.main->name, filepath); BLI_strncpy(sfile->params->dir, filepath, sizeof(sfile->params->dir)); sfile->params->file[0] = '\0'; - file_change_dir(C, 0); + ED_file_change_dir(C, false); UI_textbutton_activate_but(C, but); WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL); } @@ -1417,37 +1512,37 @@ void FILE_OT_hidedot(struct wmOperatorType *ot) ot->poll = ED_operator_file_active; /* <- important, handler is on window level */ } -ARegion *file_buttons_region(ScrArea *sa) +ARegion *file_tools_region(ScrArea *sa) { ARegion *ar, *arnew; - - for (ar = sa->regionbase.first; ar; ar = ar->next) - if (ar->regiontype == RGN_TYPE_CHANNELS) - return ar; + + if ((ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS)) != NULL) + return ar; /* add subdiv level; after header */ - for (ar = sa->regionbase.first; ar; ar = ar->next) - if (ar->regiontype == RGN_TYPE_HEADER) - break; + ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER); /* is error! */ - if (ar == NULL) return NULL; - - arnew = MEM_callocN(sizeof(ARegion), "buttons for file panels"); + if (ar == NULL) + return NULL; + arnew = MEM_callocN(sizeof(ARegion), "tools for file"); BLI_insertlinkafter(&sa->regionbase, ar, arnew); - arnew->regiontype = RGN_TYPE_CHANNELS; + arnew->regiontype = RGN_TYPE_TOOLS; arnew->alignment = RGN_ALIGN_LEFT; - - arnew->flag = RGN_FLAG_HIDDEN; - + + ar = MEM_callocN(sizeof(ARegion), "tool props for file"); + BLI_insertlinkafter(&sa->regionbase, arnew, ar); + ar->regiontype = RGN_TYPE_TOOL_PROPS; + ar->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV; + return arnew; } static int file_bookmark_toggle_exec(bContext *C, wmOperator *UNUSED(unused)) { ScrArea *sa = CTX_wm_area(C); - ARegion *ar = file_buttons_region(sa); + ARegion *ar = file_tools_region(sa); if (ar) ED_region_toggle_hidden(C, ar); diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c index c224da721fa..3da83aa6028 100644 --- a/source/blender/editors/space_file/file_panels.c +++ b/source/blender/editors/space_file/file_panels.c @@ -44,6 +44,8 @@ #include "RNA_access.h" +#include "ED_fileselect.h" + #include "UI_interface.h" #include "UI_resources.h" @@ -55,140 +57,6 @@ #include <string.h> -static void file_panel_cb(bContext *C, void *arg_entry, void *UNUSED(arg_v)) -{ - wmOperatorType *ot = WM_operatortype_find("FILE_OT_select_bookmark", false); - PointerRNA ptr; - const char *entry = (char *)arg_entry; - - WM_operator_properties_create_ptr(&ptr, ot); - RNA_string_set(&ptr, "dir", entry); - WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_REGION_WIN, &ptr); - WM_operator_properties_free(&ptr); -} - -static void file_panel_category(const bContext *C, Panel *pa, FSMenuCategory category, short *nr, int icon, int allow_delete) -{ - SpaceFile *sfile = CTX_wm_space_file(C); - uiBlock *block; - uiBut *but; - uiLayout *box, *col; - struct FSMenu *fsmenu = fsmenu_get(); - int i, nentries = fsmenu_get_nentries(fsmenu, category); - - /* reset each time */ - *nr = -1; - - /* hide if no entries */ - if (nentries == 0) - return; - - /* layout */ - uiLayoutSetAlignment(pa->layout, UI_LAYOUT_ALIGN_LEFT); - block = uiLayoutGetBlock(pa->layout); - box = uiLayoutBox(pa->layout); - col = uiLayoutColumn(box, true); - - for (i = 0; i < nentries; ++i) { - char dir[FILE_MAX]; - char temp[FILE_MAX]; - uiLayout *layout = uiLayoutRow(col, false); - char *entry; - - entry = fsmenu_get_entry(fsmenu, category, i); - - /* set this list item as active if we have a match */ - if (sfile->params) { - if (BLI_path_cmp(sfile->params->dir, entry) == 0) { - *nr = i; - } - } - - /* create nice bookmark name, shows last directory in the full path currently */ - BLI_strncpy(temp, entry, FILE_MAX); - BLI_add_slash(temp); - BLI_getlastdir(temp, dir, FILE_MAX); - BLI_del_slash(dir); - - if (dir[0] == 0) - BLI_strncpy(dir, entry, FILE_MAX); - - /* create list item */ - but = uiDefIconTextButS(block, UI_BTYPE_LISTROW, 0, icon, dir, 0, 0, UI_UNIT_X * 10, UI_UNIT_Y, nr, 0, i, 0, 0, entry); - UI_but_func_set(but, file_panel_cb, entry, NULL); - UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */ - UI_but_drawflag_enable(but, UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT); - - /* create delete button */ - if (allow_delete && fsmenu_can_save(fsmenu, category, i)) { - UI_block_emboss_set(block, UI_EMBOSS_NONE); - uiItemIntO(layout, "", ICON_X, "FILE_OT_bookmark_delete", "index", i); - UI_block_emboss_set(block, UI_EMBOSS); - } - } -} - -static void file_panel_system(const bContext *C, Panel *pa) -{ - SpaceFile *sfile = CTX_wm_space_file(C); - - if (sfile) - file_panel_category(C, pa, FS_CATEGORY_SYSTEM, &sfile->systemnr, ICON_DISK_DRIVE, 0); -} - -static int file_panel_system_bookmarks_poll(const bContext *C, PanelType *UNUSED(pt)) -{ - SpaceFile *sfile = CTX_wm_space_file(C); - return (sfile && !(U.uiflag & USER_HIDE_SYSTEM_BOOKMARKS)); -} - -static void file_panel_system_bookmarks(const bContext *C, Panel *pa) -{ - SpaceFile *sfile = CTX_wm_space_file(C); - - if (sfile && !(U.uiflag & USER_HIDE_SYSTEM_BOOKMARKS)) { - file_panel_category(C, pa, FS_CATEGORY_SYSTEM_BOOKMARKS, &sfile->systemnr, ICON_BOOKMARKS, 0); - } - -} - -static void file_panel_bookmarks(const bContext *C, Panel *pa) -{ - SpaceFile *sfile = CTX_wm_space_file(C); - uiLayout *row; - - if (sfile) { - row = uiLayoutRow(pa->layout, false); - uiItemO(row, IFACE_("Add"), ICON_ZOOMIN, "file.bookmark_add"); - uiItemL(row, NULL, ICON_NONE); - - file_panel_category(C, pa, FS_CATEGORY_BOOKMARKS, &sfile->bookmarknr, ICON_BOOKMARKS, 1); - } -} - -static int file_panel_recent_poll(const bContext *C, PanelType *UNUSED(pt)) -{ - SpaceFile *sfile = CTX_wm_space_file(C); - return (sfile && !(U.uiflag & USER_HIDE_RECENT)); -} - -static void file_panel_recent(const bContext *C, Panel *pa) -{ - SpaceFile *sfile = CTX_wm_space_file(C); - uiLayout *row; - - if (sfile) { - if (!(U.uiflag & USER_HIDE_RECENT)) { - row = uiLayoutRow(pa->layout, false); - uiItemO(row, IFACE_("Reset"), ICON_X, "file.reset_recent"); - uiItemL(row, NULL, ICON_NONE); - - file_panel_category(C, pa, FS_CATEGORY_RECENT, &sfile->recentnr, ICON_FILE_FOLDER, 0); - } - } -} - - static int file_panel_operator_poll(const bContext *C, PanelType *UNUSED(pt)) { SpaceFile *sfile = CTX_wm_space_file(C); @@ -217,7 +85,7 @@ static void file_panel_operator(const bContext *C, Panel *pa) SpaceFile *sfile = CTX_wm_space_file(C); wmOperator *op = sfile->op; // int empty = 1, flag; - + UI_block_func_set(uiLayoutGetBlock(pa->layout), file_draw_check_cb, NULL, NULL); uiLayoutOperatorButs(C, pa->layout, op, file_panel_check_prop, '\0', UI_LAYOUT_OP_SHOW_EMPTY); @@ -229,36 +97,6 @@ void file_panels_register(ARegionType *art) { PanelType *pt; - pt = MEM_callocN(sizeof(PanelType), "spacetype file system directories"); - strcpy(pt->idname, "FILE_PT_system"); - strcpy(pt->label, N_("System")); - strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA); - pt->draw = file_panel_system; - BLI_addtail(&art->paneltypes, pt); - - pt = MEM_callocN(sizeof(PanelType), "spacetype file system bookmarks"); - strcpy(pt->idname, "FILE_PT_system_bookmarks"); - strcpy(pt->label, N_("System Bookmarks")); - strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA); - pt->draw = file_panel_system_bookmarks; - pt->poll = file_panel_system_bookmarks_poll; - BLI_addtail(&art->paneltypes, pt); - - pt = MEM_callocN(sizeof(PanelType), "spacetype file bookmarks"); - strcpy(pt->idname, "FILE_PT_bookmarks"); - strcpy(pt->label, N_("Bookmarks")); - strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA); - pt->draw = file_panel_bookmarks; - BLI_addtail(&art->paneltypes, pt); - - pt = MEM_callocN(sizeof(PanelType), "spacetype file recent directories"); - strcpy(pt->idname, "FILE_PT_recent"); - strcpy(pt->label, N_("Recent")); - strcpy(pt->translation_context, BLF_I18NCONTEXT_DEFAULT_BPYRNA); - pt->draw = file_panel_recent; - pt->poll = file_panel_recent_poll; - BLI_addtail(&art->paneltypes, pt); - pt = MEM_callocN(sizeof(PanelType), "spacetype file operator properties"); strcpy(pt->idname, "FILE_PT_operator"); strcpy(pt->label, N_("Operator")); diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index c452f2e1ff4..317573fe252 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -597,7 +597,7 @@ FileLayout *ED_fileselect_get_layout(struct SpaceFile *sfile, ARegion *ar) return sfile->layout; } -void file_change_dir(bContext *C, int checkdir) +void ED_file_change_dir(bContext *C, const bool checkdir) { wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = CTX_wm_space_file(C); diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c index 05dfdf66ab6..8d4384acba6 100644 --- a/source/blender/editors/space_file/fsmenu.c +++ b/source/blender/editors/space_file/fsmenu.c @@ -40,6 +40,12 @@ #include "BLI_utildefines.h" #include "BLI_blenlib.h" +#include "BKE_appdir.h" + +#include "DNA_space_types.h" + +#include "ED_fileselect.h" + #ifdef WIN32 # include <windows.h> /* need to include windows.h so _WIN32_IE is defined */ # ifndef _WIN32_IE @@ -63,15 +69,6 @@ /* FSMENU HANDLING */ -/* FSMenuEntry's without paths indicate seperators */ -typedef struct _FSMenuEntry FSMenuEntry; -struct _FSMenuEntry { - FSMenuEntry *next; - - char *path; - short save; -}; - typedef struct FSMenu { FSMenuEntry *fsmenu_system; FSMenuEntry *fsmenu_system_bookmarks; @@ -81,7 +78,7 @@ typedef struct FSMenu { static FSMenu *g_fsmenu = NULL; -FSMenu *fsmenu_get(void) +FSMenu *ED_fsmenu_get(void) { if (!g_fsmenu) { g_fsmenu = MEM_callocN(sizeof(struct FSMenu), "fsmenu"); @@ -89,7 +86,7 @@ FSMenu *fsmenu_get(void) return g_fsmenu; } -static FSMenuEntry *fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory category) +struct FSMenuEntry *ED_fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory category) { FSMenuEntry *fsm_head = NULL; @@ -110,7 +107,7 @@ static FSMenuEntry *fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory ca return fsm_head; } -static void fsmenu_set_category(struct FSMenu *fsmenu, FSMenuCategory category, FSMenuEntry *fsm_head) +void ED_fsmenu_set_category(struct FSMenu *fsmenu, FSMenuCategory category, FSMenuEntry *fsm_head) { switch (category) { case FS_CATEGORY_SYSTEM: @@ -128,47 +125,115 @@ static void fsmenu_set_category(struct FSMenu *fsmenu, FSMenuCategory category, } } -int fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category) +int ED_fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category) { FSMenuEntry *fsm_iter; int count = 0; - for (fsm_iter = fsmenu_get_category(fsmenu, category); fsm_iter; fsm_iter = fsm_iter->next) { + for (fsm_iter = ED_fsmenu_get_category(fsmenu, category); fsm_iter; fsm_iter = fsm_iter->next) { count++; } return count; } -char *fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx) +FSMenuEntry *ED_fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int index) { FSMenuEntry *fsm_iter; - for (fsm_iter = fsmenu_get_category(fsmenu, category); fsm_iter && idx; fsm_iter = fsm_iter->next) { - idx--; + for (fsm_iter = ED_fsmenu_get_category(fsmenu, category); fsm_iter && index; fsm_iter = fsm_iter->next) { + index--; + } + + return fsm_iter; +} + +char *ED_fsmenu_entry_get_path(struct FSMenuEntry *fsentry) +{ + return fsentry->path; +} + +void ED_fsmenu_entry_set_path(struct FSMenuEntry *fsentry, const char *path) +{ + if ((!fsentry->path || !path || !STREQ(path, fsentry->path)) && (fsentry->path != path)) { + char tmp_name[FILE_MAXFILE]; + + MEM_SAFE_FREE(fsentry->path); + + fsentry->path = (path && path[0]) ? BLI_strdup(path) : NULL; + + BLI_make_file_string("/", tmp_name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); + fsmenu_write_file(ED_fsmenu_get(), tmp_name); + } +} + +static void fsmenu_entry_generate_name(struct FSMenuEntry *fsentry, char *name, size_t name_size) +{ + char temp[FILE_MAX]; + + BLI_strncpy(temp, fsentry->path, FILE_MAX); + BLI_add_slash(temp); + BLI_getlastdir(temp, name, name_size); + BLI_del_slash(name); + if (!name[0]) { + name[0] = '/'; + name[1] = '\0'; } +} - return fsm_iter ? fsm_iter->path : NULL; +char *ED_fsmenu_entry_get_name(struct FSMenuEntry *fsentry) +{ + if (fsentry->name[0]) { + return fsentry->name; + } + else { + /* Here we abuse fsm_iter->name, keeping first char NULL. */ + char *name = fsentry->name + 1; + size_t name_size = sizeof(fsentry->name) - 1; + + fsmenu_entry_generate_name(fsentry, name, name_size); + return name; + } +} + +void ED_fsmenu_entry_set_name(struct FSMenuEntry *fsentry, const char *name) +{ + if (!STREQ(name, fsentry->name)) { + char tmp_name[FILE_MAXFILE]; + size_t tmp_name_size = sizeof(tmp_name); + + fsmenu_entry_generate_name(fsentry, tmp_name, tmp_name_size); + if (!name[0] || STREQ(tmp_name, name)) { + /* reset name to default behavior. */ + fsentry->name[0] = '\0'; + } + else { + BLI_strncpy(fsentry->name, name, sizeof(fsentry->name)); + } + + BLI_make_file_string("/", tmp_name, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE); + fsmenu_write_file(ED_fsmenu_get(), tmp_name); + } } short fsmenu_can_save(struct FSMenu *fsmenu, FSMenuCategory category, int idx) { FSMenuEntry *fsm_iter; - for (fsm_iter = fsmenu_get_category(fsmenu, category); fsm_iter && idx; fsm_iter = fsm_iter->next) { + for (fsm_iter = ED_fsmenu_get_category(fsmenu, category); fsm_iter && idx; fsm_iter = fsm_iter->next) { idx--; } return fsm_iter ? fsm_iter->save : 0; } -void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const char *path, FSMenuInsert flag) +void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const char *path, const char *name, FSMenuInsert flag) { FSMenuEntry *fsm_prev; FSMenuEntry *fsm_iter; FSMenuEntry *fsm_head; - fsm_head = fsmenu_get_category(fsmenu, category); + fsm_head = ED_fsmenu_get_category(fsmenu, category); fsm_prev = fsm_head; /* this is odd and not really correct? */ for (fsm_iter = fsm_head; fsm_iter; fsm_prev = fsm_iter, fsm_iter = fsm_iter->next) { @@ -179,7 +244,7 @@ void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const c if (fsm_iter != fsm_head) { fsm_prev->next = fsm_iter->next; fsm_iter->next = fsm_head; - fsmenu_set_category(fsmenu, category, fsm_iter); + ED_fsmenu_set_category(fsmenu, category, fsm_iter); } } return; @@ -201,11 +266,17 @@ void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const c fsm_iter = MEM_mallocN(sizeof(*fsm_iter), "fsme"); fsm_iter->path = BLI_strdup(path); fsm_iter->save = (flag & FS_INSERT_SAVE) != 0; + if (name && name[0]) { + BLI_strncpy(fsm_iter->name, name, sizeof(fsm_iter->name)); + } + else { + fsm_iter->name[0] = '\0'; + } if (fsm_prev) { if (flag & FS_INSERT_FIRST) { fsm_iter->next = fsm_head; - fsmenu_set_category(fsmenu, category, fsm_iter); + ED_fsmenu_set_category(fsmenu, category, fsm_iter); } else { fsm_iter->next = fsm_prev->next; @@ -214,7 +285,7 @@ void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const c } else { fsm_iter->next = fsm_head; - fsmenu_set_category(fsmenu, category, fsm_iter); + ED_fsmenu_set_category(fsmenu, category, fsm_iter); } } @@ -224,7 +295,7 @@ void fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx FSMenuEntry *fsm_iter; FSMenuEntry *fsm_head; - fsm_head = fsmenu_get_category(fsmenu, category); + fsm_head = ED_fsmenu_get_category(fsmenu, category); for (fsm_iter = fsm_head; fsm_iter && idx; fsm_prev = fsm_iter, fsm_iter = fsm_iter->next) idx--; @@ -241,7 +312,7 @@ void fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx } else { fsm_head = fsm_iter->next; - fsmenu_set_category(fsmenu, category, fsm_head); + ED_fsmenu_set_category(fsmenu, category, fsm_head); } /* free entry */ MEM_freeN(fsm_iter->path); @@ -253,20 +324,29 @@ void fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int idx void fsmenu_write_file(struct FSMenu *fsmenu, const char *filename) { FSMenuEntry *fsm_iter = NULL; + char fsm_name[FILE_MAX]; int nwritten = 0; FILE *fp = BLI_fopen(filename, "w"); if (!fp) return; - + fprintf(fp, "[Bookmarks]\n"); - for (fsm_iter = fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS); fsm_iter; fsm_iter = fsm_iter->next) { + for (fsm_iter = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_BOOKMARKS); fsm_iter; fsm_iter = fsm_iter->next) { if (fsm_iter->path && fsm_iter->save) { + fsmenu_entry_generate_name(fsm_iter, fsm_name, sizeof(fsm_name)); + if (fsm_iter->name[0] && !STREQ(fsm_iter->name, fsm_name)) { + fprintf(fp, "!%s\n", fsm_iter->name); + } fprintf(fp, "%s\n", fsm_iter->path); } } fprintf(fp, "[Recent]\n"); - for (fsm_iter = fsmenu_get_category(fsmenu, FS_CATEGORY_RECENT); fsm_iter && (nwritten < FSMENU_RECENT_MAX); fsm_iter = fsm_iter->next, ++nwritten) { + for (fsm_iter = ED_fsmenu_get_category(fsmenu, FS_CATEGORY_RECENT); fsm_iter && (nwritten < FSMENU_RECENT_MAX); fsm_iter = fsm_iter->next, ++nwritten) { if (fsm_iter->path && fsm_iter->save) { + fsmenu_entry_generate_name(fsm_iter, fsm_name, sizeof(fsm_name)); + if (fsm_iter->name[0] && !STREQ(fsm_iter->name, fsm_name)) { + fprintf(fp, "!%s\n", fsm_iter->name); + } fprintf(fp, "%s\n", fsm_iter->path); } } @@ -276,12 +356,15 @@ void fsmenu_write_file(struct FSMenu *fsmenu, const char *filename) void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename) { char line[FILE_MAXDIR]; + char name[FILE_MAXFILE]; FSMenuCategory category = FS_CATEGORY_BOOKMARKS; FILE *fp; fp = BLI_fopen(filename, "r"); if (!fp) return; + name[0] = '\0'; + while (fgets(line, sizeof(line), fp) != NULL) { /* read a line */ if (STREQLEN(line, "[Bookmarks]", 11)) { category = FS_CATEGORY_BOOKMARKS; @@ -289,6 +372,15 @@ void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename) else if (STREQLEN(line, "[Recent]", 8)) { category = FS_CATEGORY_RECENT; } + else if (line[0] == '!') { + int len = strlen(line); + if (len > 0) { + if (line[len - 1] == '\n') { + line[len - 1] = '\0'; + } + BLI_strncpy(name, line + 1, sizeof(name)); + } + } else { int len = strlen(line); if (len > 0) { @@ -302,9 +394,11 @@ void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename) if (BLI_exists(line)) #endif { - fsmenu_insert_entry(fsmenu, category, line, FS_INSERT_SAVE); + fsmenu_insert_entry(fsmenu, category, line, name, FS_INSERT_SAVE); } } + /* always reset name. */ + name[0] = '\0'; } } fclose(fp); @@ -329,16 +423,16 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) tmps[2] = '\\'; tmps[3] = 0; - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, tmps, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, tmps, NULL, FS_INSERT_SORTED); } } /* Adding Desktop and My Documents */ if (read_bookmarks) { SHGetSpecialFolderPath(0, line, CSIDL_PERSONAL, 0); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); SHGetSpecialFolderPath(0, line, CSIDL_DESKTOPDIRECTORY, 0); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } } #else @@ -361,7 +455,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) FSRefMakePath(&dir, path, FILE_MAX); if (!STREQ((char *)path, "/home") && !STREQ((char *)path, "/net")) { /* /net and /home are meaningless on OSX, home folders are stored in /Users */ - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)path, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)path, NULL, FS_INSERT_SORTED); } } @@ -371,26 +465,26 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) home = getenv("HOME"); if (read_bookmarks && home) { BLI_snprintf(line, sizeof(line), "%s/", home); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); BLI_snprintf(line, sizeof(line), "%s/Desktop/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } BLI_snprintf(line, sizeof(line), "%s/Documents/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } BLI_snprintf(line, sizeof(line), "%s/Pictures/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } BLI_snprintf(line, sizeof(line), "%s/Music/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } BLI_snprintf(line, sizeof(line), "%s/Movies/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } } #else /* OSX 10.6+ */ @@ -410,7 +504,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) continue; CFURLGetFileSystemRepresentation(cfURL, false, (UInt8 *)defPath, FILE_MAX); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)defPath, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, (char *)defPath, NULL, FS_INSERT_SORTED); } CFRelease(volEnum); @@ -447,7 +541,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) /* Exclude "all my files" as it makes no sense in blender fileselector */ /* Exclude "airdrop" if wlan not active as it would show "" ) */ if (!strstr(line, "myDocuments.cannedSearch") && (*line != '\0')) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_APPEND_LAST); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_LAST); } CFRelease(pathString); @@ -466,10 +560,10 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) if (read_bookmarks && home) { BLI_snprintf(line, sizeof(line), "%s/", home); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); BLI_snprintf(line, sizeof(line), "%s/Desktop/", home); if (BLI_exists(line)) { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL, FS_INSERT_SORTED); } } @@ -494,10 +588,10 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) len = strlen(mnt->mnt_dir); if (len && mnt->mnt_dir[len - 1] != '/') { BLI_snprintf(line, sizeof(line), "%s/", mnt->mnt_dir); - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, NULL, FS_INSERT_SORTED); } else { - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, mnt->mnt_dir, FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, mnt->mnt_dir, NULL, FS_INSERT_SORTED); } found = 1; @@ -510,7 +604,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) /* fallback */ if (!found) - fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, "/", FS_INSERT_SORTED); + fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, "/", NULL, FS_INSERT_SORTED); } } #endif @@ -520,7 +614,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) static void fsmenu_free_category(struct FSMenu *fsmenu, FSMenuCategory category) { - FSMenuEntry *fsm_iter = fsmenu_get_category(fsmenu, category); + FSMenuEntry *fsm_iter = ED_fsmenu_get_category(fsmenu, category); while (fsm_iter) { FSMenuEntry *fsm_next = fsm_iter->next; @@ -537,10 +631,10 @@ static void fsmenu_free_category(struct FSMenu *fsmenu, FSMenuCategory category) void fsmenu_refresh_system_category(struct FSMenu *fsmenu) { fsmenu_free_category(fsmenu, FS_CATEGORY_SYSTEM); - fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM, NULL); + ED_fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM, NULL); fsmenu_free_category(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS); - fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, NULL); + ED_fsmenu_set_category(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, NULL); /* Add all entries to system category */ fsmenu_read_system(fsmenu, true); @@ -559,3 +653,16 @@ void fsmenu_free(void) g_fsmenu = NULL; } +int fsmenu_get_active_indices(struct FSMenu *fsmenu, enum FSMenuCategory category, const char *dir) +{ + FSMenuEntry *fsm_iter = ED_fsmenu_get_category(fsmenu, category); + int i; + + for (i = 0; fsm_iter; fsm_iter = fsm_iter->next, i++) { + if (BLI_path_cmp(dir, fsm_iter->path) == 0) { + return i; + } + } + + return -1; +} diff --git a/source/blender/editors/space_file/fsmenu.h b/source/blender/editors/space_file/fsmenu.h index 831ec138474..fa925310c2b 100644 --- a/source/blender/editors/space_file/fsmenu.h +++ b/source/blender/editors/space_file/fsmenu.h @@ -37,43 +37,23 @@ /* XXX could become UserPref */ #define FSMENU_RECENT_MAX 10 -typedef enum FSMenuCategory { - FS_CATEGORY_SYSTEM, - FS_CATEGORY_SYSTEM_BOOKMARKS, - FS_CATEGORY_BOOKMARKS, - FS_CATEGORY_RECENT -} FSMenuCategory; - -typedef enum FSMenuInsert { - FS_INSERT_SORTED = (1 << 0), - FS_INSERT_SAVE = (1 << 1), - FS_INSERT_FIRST = (1 << 2), /* moves the item to the front of the list when its not already there */ - FS_APPEND_LAST = (1 << 3) /* just append to preseve delivered order */ -} FSMenuInsert; +enum FSMenuCategory; +enum FSMenuInsert; struct FSMenu; - -struct FSMenu *fsmenu_get(void); - -/** Returns the number of entries in the Fileselect Menu */ -int fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category); - -/** Returns the fsmenu entry at \a index (or NULL if a bad index) - * or a separator. - */ -char *fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int index); +struct FSMenuEntry; /** Inserts a new fsmenu entry with the given \a path. * Duplicate entries are not added. * \param flag Options for inserting the entry. */ -void fsmenu_insert_entry(struct FSMenu *fsmenu, FSMenuCategory category, const char *path, const FSMenuInsert flag); +void fsmenu_insert_entry(struct FSMenu *fsmenu, enum FSMenuCategory category, const char *path, const char *name, const enum FSMenuInsert flag); /** Return whether the entry was created by the user and can be saved and deleted */ -short fsmenu_can_save(struct FSMenu *fsmenu, FSMenuCategory category, int index); +short fsmenu_can_save(struct FSMenu *fsmenu, enum FSMenuCategory category, int index); /** Removes the fsmenu entry at the given \a index. */ -void fsmenu_remove_entry(struct FSMenu *fsmenu, FSMenuCategory category, int index); +void fsmenu_remove_entry(struct FSMenu *fsmenu, enum FSMenuCategory category, int index); /** saves the 'bookmarks' to the specified file */ void fsmenu_write_file(struct FSMenu *fsmenu, const char *filename); @@ -90,5 +70,8 @@ void fsmenu_free(void); /** Refresh system directory menu */ void fsmenu_refresh_system_category(struct FSMenu *fsmenu); +/** Get active index based on given directory. */ +int fsmenu_get_active_indices(struct FSMenu *fsmenu, enum FSMenuCategory category, const char *dir); + #endif diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index f0555933146..3c60233d0a9 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -71,7 +71,7 @@ static SpaceLink *file_new(const bContext *UNUSED(C)) { ARegion *ar; SpaceFile *sfile; - + sfile = MEM_callocN(sizeof(SpaceFile), "initfile"); sfile->spacetype = SPACE_FILE; @@ -81,12 +81,18 @@ static SpaceLink *file_new(const bContext *UNUSED(C)) ar->regiontype = RGN_TYPE_HEADER; ar->alignment = RGN_ALIGN_TOP; - /* channel list region */ - ar = MEM_callocN(sizeof(ARegion), "channel area for file"); + /* Tools region */ + ar = MEM_callocN(sizeof(ARegion), "tools area for file"); BLI_addtail(&sfile->regionbase, ar); - ar->regiontype = RGN_TYPE_CHANNELS; + ar->regiontype = RGN_TYPE_TOOLS; ar->alignment = RGN_ALIGN_LEFT; + /* Tool props (aka operator) region */ + ar = MEM_callocN(sizeof(ARegion), "tool props area for file"); + BLI_addtail(&sfile->regionbase, ar); + ar->regiontype = RGN_TYPE_TOOL_PROPS; + ar->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV; + /* ui list region */ ar = MEM_callocN(sizeof(ARegion), "ui area for file"); BLI_addtail(&sfile->regionbase, ar); @@ -149,7 +155,7 @@ static void file_init(wmWindowManager *UNUSED(wm), ScrArea *sa) SpaceFile *sfile = (SpaceFile *)sa->spacedata.first; /* refresh system directory list */ - fsmenu_refresh_system_category(fsmenu_get()); + fsmenu_refresh_system_category(ED_fsmenu_get()); if (sfile->layout) sfile->layout->dirty = true; } @@ -187,11 +193,12 @@ static SpaceLink *file_duplicate(SpaceLink *sl) return (SpaceLink *)sfilen; } -static void file_refresh(const bContext *C, ScrArea *UNUSED(sa)) +static void file_refresh(const bContext *C, ScrArea *sa) { wmWindowManager *wm = CTX_wm_manager(C); SpaceFile *sfile = CTX_wm_space_file(C); FileSelectParams *params = ED_fileselect_get_params(sfile); + struct FSMenu *fsmenu = ED_fsmenu_get(); if (!sfile->folders_prev) { sfile->folders_prev = folderlist_new(); @@ -208,6 +215,12 @@ static void file_refresh(const bContext *C, ScrArea *UNUSED(sa)) params->filter_glob, params->filter_search); + /* Update the active indices of bookmarks & co. */ + sfile->systemnr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_SYSTEM, params->dir); + sfile->system_bookmarknr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, params->dir); + sfile->bookmarknr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_BOOKMARKS, params->dir); + sfile->recentnr = fsmenu_get_active_indices(fsmenu, FS_CATEGORY_RECENT, params->dir); + if (filelist_empty(sfile->files)) { thumbnails_stop(wm, sfile->files); filelist_readdir(sfile->files); @@ -246,6 +259,15 @@ static void file_refresh(const bContext *C, ScrArea *UNUSED(sa)) if (sfile->layout) { sfile->layout->dirty = true; } + + /* Might be called with NULL sa, see file_main_area_draw() below. */ + if (sa && BKE_area_find_region_type(sa, RGN_TYPE_TOOLS) == NULL) { + /* Create TOOLS/TOOL_PROPS regions. */ + file_tools_region(sa); + + ED_area_initialize(wm, CTX_wm_window(C), sa); + ED_area_tag_redraw(sa); + } } static void file_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn) @@ -382,6 +404,7 @@ static void file_operatortypes(void) WM_operatortype_append(FILE_OT_bookmark_toggle); WM_operatortype_append(FILE_OT_bookmark_add); WM_operatortype_append(FILE_OT_bookmark_delete); + WM_operatortype_append(FILE_OT_bookmark_move); WM_operatortype_append(FILE_OT_reset_recent); WM_operatortype_append(FILE_OT_hidedot); WM_operatortype_append(FILE_OT_filenum); @@ -473,7 +496,7 @@ static void file_keymap(struct wmKeyConfig *keyconf) } -static void file_channel_area_init(wmWindowManager *wm, ARegion *ar) +static void file_tools_area_init(wmWindowManager *wm, ARegion *ar) { wmKeyMap *keymap; @@ -485,12 +508,12 @@ static void file_channel_area_init(wmWindowManager *wm, ARegion *ar) WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); } -static void file_channel_area_draw(const bContext *C, ARegion *ar) +static void file_tools_area_draw(const bContext *C, ARegion *ar) { ED_region_panels(C, ar, 1, NULL, -1); } -static void file_channel_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn)) +static void file_tools_area_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn)) { #if 0 /* context changes */ @@ -616,12 +639,24 @@ void ED_spacetype_file(void) /* regions: channels (directories) */ art = MEM_callocN(sizeof(ARegionType), "spacetype file region"); - art->regionid = RGN_TYPE_CHANNELS; + art->regionid = RGN_TYPE_TOOLS; art->prefsizex = 240; + art->prefsizey = 60; + art->keymapflag = ED_KEYMAP_UI; + art->listener = file_tools_area_listener; + art->init = file_tools_area_init; + art->draw = file_tools_area_draw; + BLI_addhead(&st->regiontypes, art); + + /* regions: tool properties */ + art = MEM_callocN(sizeof(ARegionType), "spacetype file operator region"); + art->regionid = RGN_TYPE_TOOL_PROPS; + art->prefsizex = 0; + art->prefsizey = 240; art->keymapflag = ED_KEYMAP_UI; - art->listener = file_channel_area_listener; - art->init = file_channel_area_init; - art->draw = file_channel_area_draw; + art->listener = file_tools_area_listener; + art->init = file_tools_area_init; + art->draw = file_tools_area_draw; BLI_addhead(&st->regiontypes, art); file_panels_register(art); @@ -655,12 +690,12 @@ void ED_file_read_bookmarks(void) fsmenu_free(); - fsmenu_read_system(fsmenu_get(), true); + fsmenu_read_system(ED_fsmenu_get(), true); if (cfgdir) { char name[FILE_MAX]; BLI_make_file_string("/", name, cfgdir, BLENDER_BOOKMARK_FILE); - fsmenu_read_bookmarks(fsmenu_get(), name); + fsmenu_read_bookmarks(ED_fsmenu_get(), name); } } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index e10ecd8c613..5815817f839 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1760,13 +1760,13 @@ static void node_composit_buts_file_output_ex(uiLayout *layout, bContext *C, Poi /* using different collection properties if multilayer format is enabled */ if (multilayer) { uiTemplateList(col, C, "UI_UL_list", "file_output_node", ptr, "layer_slots", ptr, "active_input_index", - 0, 0, 0, 0); + NULL, 0, 0, 0, 0); RNA_property_collection_lookup_int(ptr, RNA_struct_find_property(ptr, "layer_slots"), active_index, &active_input_ptr); } else { uiTemplateList(col, C, "UI_UL_list", "file_output_node", ptr, "file_slots", ptr, "active_input_index", - 0, 0, 0, 0); + NULL, 0, 0, 0, 0); RNA_property_collection_lookup_int(ptr, RNA_struct_find_property(ptr, "file_slots"), active_index, &active_input_ptr); } diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c index 76a096b8471..5b478d8bde3 100644 --- a/source/blender/editors/space_node/node_buttons.c +++ b/source/blender/editors/space_node/node_buttons.c @@ -148,14 +148,14 @@ static void node_tree_interface_panel(const bContext *C, Panel *pa) col = uiLayoutColumn(split, true); uiItemL(col, IFACE_("Inputs:"), ICON_NONE); uiTemplateList(col, (bContext *)C, "NODE_UL_interface_sockets", "inputs", &ptr, "inputs", &ptr, "active_input", - 0, 0, 0, 0); + NULL, 0, 0, 0, 0); opptr = uiItemFullO(col, "NODE_OT_tree_socket_add", "", ICON_PLUS, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); RNA_enum_set(&opptr, "in_out", SOCK_IN); col = uiLayoutColumn(split, true); uiItemL(col, IFACE_("Outputs:"), ICON_NONE); uiTemplateList(col, (bContext *)C, "NODE_UL_interface_sockets", "outputs", &ptr, "outputs", &ptr, "active_output", - 0, 0, 0, 0); + NULL, 0, 0, 0, 0); opptr = uiItemFullO(col, "NODE_OT_tree_socket_add", "", ICON_PLUS, NULL, WM_OP_EXEC_DEFAULT, UI_ITEM_O_RETURN_PROPS); RNA_enum_set(&opptr, "in_out", SOCK_OUT); diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index abc82775c8d..c956d77d64a 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -828,6 +828,7 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor outliner_add_element(soops, &te->subtree, gpl, te, TSE_GP_LAYER, a); a++; } + break; } } } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 2cf8031e439..7044b75fefd 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -50,6 +50,7 @@ #include "BLI_listbase.h" #include "BLI_string.h" #include "BLI_ghash.h" +#include "BLI_memarena.h" #include "BKE_nla.h" #include "BKE_editmesh_bvh.h" @@ -1503,7 +1504,7 @@ int transformEvent(TransInfo *t, const wmEvent *event) if ((t->modifiers & (MOD_SNAP | MOD_SNAP_INVERT)) != (modifiers_prev & (MOD_SNAP | MOD_SNAP_INVERT))) { - applyMouseInput(t, &t->mouse, t->mval, t->values); + applyMouseInput(t, &t->mouse, t->mval, t->values); } /* Per transform event, if present */ @@ -5132,7 +5133,8 @@ static void slide_origdata_init_flag( if ((t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT) && /* don't do this at all for non-basis shape keys, too easy to * accidentally break uv maps or vertex colors then */ - (bm->shapenr <= 1)) + (bm->shapenr <= 1) && + CustomData_has_math(&bm->ldata)) { sod->use_origfaces = true; } @@ -5155,26 +5157,89 @@ static void slide_origdata_init_data( } } -static void slide_origdata_create_date( +static void slide_origdata_create_data( TransInfo *t, SlideOrigData *sod, - BMVert **v_pt, unsigned int v_stride, unsigned int v_num) + TransDataGenericSlideVert *sv, unsigned int v_stride, unsigned int v_num) { if (sod->use_origfaces) { BMEditMesh *em = BKE_editmesh_from_object(t->obedit); BMesh *bm = em->bm; - unsigned int i; - for (i = 0; i < v_num; i++, v_pt = (void *)(((char *)v_pt) + v_stride)) { + + const int *layer_math_map; + int layer_index_dst; + int layer_groups_array_size; + int j; + + /* over alloc, only 'math' layers are indexed */ + sod->layer_math_map = MEM_mallocN(bm->ldata.totlayer * sizeof(int), __func__); + layer_index_dst = 0; + for (j = 0; j < bm->ldata.totlayer; j++) { + if (CustomData_layer_has_math(&bm->ldata, j)) { + sod->layer_math_map[layer_index_dst++] = j; + } + } + BLI_assert(layer_index_dst != 0); + layer_math_map = sod->layer_math_map; + layer_groups_array_size = layer_index_dst * sizeof(void *); + sod->layer_math_map_num = layer_index_dst; + + sod->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); + + for (i = 0; i < v_num; i++, sv = (void *)(((char *)sv) + v_stride)) { BMIter fiter; BMFace *f; - BMVert *v = *v_pt; - BM_ITER_ELEM (f, &fiter, v, BM_FACES_OF_VERT) { + /* copy face data */ + BM_ITER_ELEM (f, &fiter, sv->v, BM_FACES_OF_VERT) { if (!BLI_ghash_haskey(sod->origfaces, f)) { BMFace *f_copy = BM_face_copy(sod->bm_origfaces, bm, f, true, true); BLI_ghash_insert(sod->origfaces, f, f_copy); } } + + /* store cd_loop_groups */ + sv->cd_loop_groups = BLI_memarena_alloc(sod->arena, layer_groups_array_size); + for (j = 0; j < layer_index_dst; j++) { + const int layer_nr = layer_math_map[j]; + sv->cd_loop_groups[j] = BM_vert_loop_groups_data_layer_create(bm, sv->v, layer_nr, sod->arena); + } + } + } +} + +static void slide_origdata_interp_data( + TransInfo *t, SlideOrigData *sod, + TransDataGenericSlideVert *sv, unsigned int v_stride, unsigned int v_num, + bool is_final) +{ + if (sod->use_origfaces) { + BMEditMesh *em = BKE_editmesh_from_object(t->obedit); + unsigned int i; + + const int *layer_math_map = sod->layer_math_map; + + for (i = 0; i < v_num; i++, sv = (void *)(((char *)sv) + v_stride)) { + BMIter fiter; + BMLoop *l; + int j; + + BM_ITER_ELEM (l, &fiter, sv->v, BM_LOOPS_OF_VERT) { + BMFace *f_copy; /* the copy of 'f' */ + + f_copy = BLI_ghash_lookup(sod->origfaces, l->f); + + /* only loop data, no vertex data since that contains shape keys, + * and we do not want to mess up other shape keys */ + BM_loop_interp_from_face(em->bm, l, f_copy, false, is_final); + + /* make sure face-attributes are correct (e.g. MTexPoly) */ + BM_elem_attrs_copy(sod->bm_origfaces, em->bm, f_copy, l->f); + } + + for (j = 0; j < sod->layer_math_map_num; j++) { + BM_vert_loop_groups_data_layer_merge(em->bm, sv->cd_loop_groups[j], layer_math_map[j]); + } } } } @@ -5192,6 +5257,13 @@ static void slide_origdata_free_date( BLI_ghash_free(sod->origfaces, NULL, NULL); sod->origfaces = NULL; } + + if (sod->arena) { + BLI_memarena_free(sod->arena); + sod->arena = NULL; + } + + MEM_SAFE_FREE(sod->layer_math_map); } } @@ -5847,7 +5919,7 @@ static bool createEdgeSlideVerts(TransInfo *t) bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES); slide_origdata_init_data(t, &sld->orig_data); - slide_origdata_create_date(t, &sld->orig_data, &sld->sv->v, sizeof(*sld->sv), sld->totsv); + slide_origdata_create_data(t, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv); /*create copies of faces for customdata projection*/ sv_array = sld->sv; @@ -5896,147 +5968,12 @@ void projectEdgeSlideData(TransInfo *t, bool is_final) { EdgeSlideData *sld = t->customData; SlideOrigData *sod = &sld->orig_data; - TransDataEdgeSlideVert *sv; - BMEditMesh *em = sld->em; - int i; if (sod->use_origfaces == false) { return; } - for (i = 0, sv = sld->sv; i < sld->totsv; sv++, i++) { - BMIter fiter; - BMLoop *l; - - BM_ITER_ELEM (l, &fiter, sv->v, BM_LOOPS_OF_VERT) { - BMFace *f_copy; /* the copy of 'f' */ - BMFace *f_copy_flip; /* the copy of 'f' or detect if we need to flip to the shorter side. */ - - f_copy = BLI_ghash_lookup(sod->origfaces, l->f); - - /* project onto copied projection face */ - f_copy_flip = f_copy; - - if (BM_elem_flag_test(l->e, BM_ELEM_SELECT) || BM_elem_flag_test(l->prev->e, BM_ELEM_SELECT)) { - /* the loop is attached of the selected edges that are sliding */ - BMLoop *l_ed_sel = l; - - if (!BM_elem_flag_test(l->e, BM_ELEM_SELECT)) - l_ed_sel = l_ed_sel->prev; - - if (sld->perc < 0.0f) { - if (BM_vert_in_face(sv->v_b, l_ed_sel->radial_next->f)) { - f_copy_flip = BLI_ghash_lookup(sod->origfaces, l_ed_sel->radial_next->f); - } - } - else if (sld->perc > 0.0f) { - if (BM_vert_in_face(sv->v_a, l_ed_sel->radial_next->f)) { - f_copy_flip = BLI_ghash_lookup(sod->origfaces, l_ed_sel->radial_next->f); - } - } - - BLI_assert(f_copy_flip != NULL); - if (!f_copy_flip) { - continue; /* shouldn't happen, but protection */ - } - } - else { - /* the loop is attached to only one vertex and not a selected edge, - * this means we have to find a selected edges face going in the right direction - * to copy from else we get bad distortion see: [#31080] */ - BMIter eiter; - BMEdge *e_sel; - - BLI_assert(l->v == sv->v); - BM_ITER_ELEM (e_sel, &eiter, sv->v, BM_EDGES_OF_VERT) { - if (BM_elem_flag_test(e_sel, BM_ELEM_SELECT)) { - break; - } - } - - if (e_sel) { - /* warning if the UV's are not contiguous, this will copy from the _wrong_ UVs - * in fact whenever the face being copied is not 'f_copy' this can happen, - * we could be a lot smarter about this but would need to deal with every UV channel or - * add a way to mask out lauers when calling #BM_loop_interp_from_face() */ - - /* - * + +----------------+ - * \ | | - * (this) l_adj| | - * \ | | - * \| e_sel | - * +----------+----------------+ <- the edge we are sliding. - * /|sv->v | - * / | | - * (or) l_adj| | - * / | | - * + +----------------+ - * (above) - * 'other connected loops', attached to sv->v slide faces. - * - * NOTE: The faces connected to the edge may not have contiguous UV's - * so step around the loops to find l_adj. - * However if the 'other loops' are not cotiguous it will still give problems. - * - * A full solution to this would have to store - * per-customdata-layer map of which loops are contiguous - * and take this into account when interpolating. - * - * NOTE: If l_adj's edge isnt manifold then use then - * interpolate the loop from its own face. - * Can happen when 'other connected loops' are disconnected from the face-fan. - */ - - BMLoop *l_adj = NULL; - if (sld->perc < 0.0f) { - if (BM_vert_in_face(sv->v_b, e_sel->l->f)) { - l_adj = e_sel->l; - } - else if (BM_vert_in_face(sv->v_b, e_sel->l->radial_next->f)) { - l_adj = e_sel->l->radial_next; - } - } - else if (sld->perc > 0.0f) { - if (BM_vert_in_face(sv->v_a, e_sel->l->f)) { - l_adj = e_sel->l; - } - else if (BM_vert_in_face(sv->v_a, e_sel->l->radial_next->f)) { - l_adj = e_sel->l->radial_next; - } - } - - /* step across to the face */ - if (l_adj) { - l_adj = BM_loop_other_edge_loop(l_adj, sv->v); - if (!BM_edge_is_boundary(l_adj->e)) { - l_adj = l_adj->radial_next; - } - else { - /* disconnected face-fan, fallback to self */ - l_adj = l; - } - - f_copy_flip = BLI_ghash_lookup(sod->origfaces, l_adj->f); - } - } - } - - /* only loop data, no vertex data since that contains shape keys, - * and we do not want to mess up other shape keys */ - BM_loop_interp_from_face(em->bm, l, f_copy_flip, false, false); - - if (is_final) { - BM_loop_interp_multires(em->bm, l, f_copy_flip); - if (f_copy != f_copy_flip) { - BM_loop_interp_multires(em->bm, l, f_copy); - } - } - - /* make sure face-attributes are correct (e.g. MTexPoly) */ - BM_elem_attrs_copy(sod->bm_origfaces, em->bm, f_copy, l->f); - } - } + slide_origdata_interp_data(t, sod, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv, is_final); } void freeEdgeSlideTempFaces(EdgeSlideData *sld) @@ -6544,7 +6481,7 @@ static bool createVertSlideVerts(TransInfo *t) bmesh_edit_begin(bm, BMO_OPTYPE_FLAG_UNTAN_MULTIRES); slide_origdata_init_data(t, &sld->orig_data); - slide_origdata_create_date(t, &sld->orig_data, &sld->sv->v, sizeof(*sld->sv), sld->totsv); + slide_origdata_create_data(t, &sld->orig_data, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv); sld->em = em; @@ -6564,42 +6501,12 @@ void projectVertSlideData(TransInfo *t, bool is_final) { VertSlideData *sld = t->customData; SlideOrigData *sod = &sld->orig_data; - TransDataVertSlideVert *sv; - BMEditMesh *em = sld->em; - int i; if (sod->use_origfaces == false) { return; } - for (i = 0, sv = sld->sv; i < sld->totsv; sv++, i++) { - BMIter fiter; - BMLoop *l; - - BM_ITER_ELEM (l, &fiter, sv->v, BM_LOOPS_OF_VERT) { - BMFace *f_copy; /* the copy of 'f' */ - BMFace *f_copy_flip; /* the copy of 'f' or detect if we need to flip to the shorter side. */ - - f_copy = BLI_ghash_lookup(sod->origfaces, l->f); - - /* project onto copied projection face */ - f_copy_flip = f_copy; - - /* only loop data, no vertex data since that contains shape keys, - * and we do not want to mess up other shape keys */ - BM_loop_interp_from_face(em->bm, l, f_copy_flip, false, false); - - if (is_final) { - BM_loop_interp_multires(em->bm, l, f_copy_flip); - if (f_copy != f_copy_flip) { - BM_loop_interp_multires(em->bm, l, f_copy); - } - } - - /* make sure face-attributes are correct (e.g. MTexPoly) */ - BM_elem_attrs_copy(sod->bm_origfaces, em->bm, f_copy, l->f); - } - } + slide_origdata_interp_data(t, sod, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv, is_final); } void freeVertSlideTempFaces(VertSlideData *sld) diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 2330ec6e79e..84a81e8b3d8 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -200,9 +200,19 @@ typedef struct TransDataNla { struct LinkNode; struct GHash; +/* header of TransDataEdgeSlideVert, TransDataEdgeSlideEdge */ +typedef struct TransDataGenericSlideVert { + struct BMVert *v; + struct LinkNode **cd_loop_groups; +} TransDataGenericSlideVert; + typedef struct TransDataEdgeSlideVert { - struct BMVert *v_a, *v_b; + /* TransDataGenericSlideVert */ struct BMVert *v; + struct LinkNode **cd_loop_groups; + /* end generic */ + + struct BMVert *v_a, *v_b; float v_co_orig[3]; float edge_len; @@ -220,6 +230,13 @@ typedef struct SlideOrigData { bool use_origfaces; struct GHash *origfaces; struct BMesh *bm_origfaces; + + struct MemArena *arena; + /* number of math BMLoop layers */ + int layer_math_map_num; + /* array size of 'layer_math_map_num' + * maps TransDataVertSlideVert.cd_group index to absolute CustomData layer index */ + int *layer_math_map; } SlideOrigData; typedef struct EdgeSlideData { @@ -241,7 +258,11 @@ typedef struct EdgeSlideData { typedef struct TransDataVertSlideVert { + /* TransDataGenericSlideVert */ BMVert *v; + struct LinkNode **cd_loop_groups; + /* end generic */ + float co_orig_3d[3]; float co_orig_2d[2]; float (*co_link_orig_3d)[3]; diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 4cb1f8943f9..f7a8735ccca 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -574,11 +574,11 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchStat edgecos = dot_v2v2(normal, state->normals + index_tmp1 * 2); edgesin = cross_v2v2(normal, state->normals + index_tmp1 * 2); if (edgesin > 0.0f) { - rotation += acosf(max_ff(-1.0f, min_ff(1.0f, edgecos))); + rotation += acosf(max_ff(-1.0f, min_ff(1.0f, edgecos))); rot_elem++; } else { - rotation_neg += acosf(max_ff(-1.0f, min_ff(1.0f, edgecos))); + rotation_neg += acosf(max_ff(-1.0f, min_ff(1.0f, edgecos))); rot_elem_neg++; } } diff --git a/source/blender/freestyle/intern/winged_edge/Curvature.cpp b/source/blender/freestyle/intern/winged_edge/Curvature.cpp index 31396688422..97dcc86cf31 100644 --- a/source/blender/freestyle/intern/winged_edge/Curvature.cpp +++ b/source/blender/freestyle/intern/winged_edge/Curvature.cpp @@ -211,8 +211,9 @@ bool gts_vertex_gaussian_curvature(WVertex *v, real *Kg) } WVertex::incoming_edge_iterator itE; - for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) - area += (*itE)->GetaFace()->getArea(); + for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) { + area += (*itE)->GetaFace()->getArea(); + } for (itE = v->incoming_edges_begin(); itE != v->incoming_edges_end(); itE++) { WOEdge *e = (*itE)->getPrevOnFace(); diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index d1102b03e9a..56167d466f1 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -247,8 +247,9 @@ static GPUBuffer *gpu_buffer_alloc_intern(int size, bool use_VBO) bufsize = pool->buffers[i]->size; /* only return a buffer that matches the VBO preference */ - if (pool->buffers[i]->use_vbo != use_VBO) + if (pool->buffers[i]->use_vbo != use_VBO) { continue; + } /* check for an exact size match */ if (bufsize == size) { @@ -653,8 +654,8 @@ static GPUBuffer *gpu_buffer_setup(DerivedMesh *dm, GPUDrawObject *object, /* attempt to map the buffer */ if (!(varray = glMapBufferARB(target, GL_WRITE_ONLY_ARB))) { - buffer = gpu_try_realloc(pool, buffer, size, true); - + buffer = gpu_try_realloc(pool, buffer, size, true); + /* allocation still failed; fall back * to legacy mode */ if (!buffer) { diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 5de5dfe50c9..27c9e3f7d9e 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -2129,18 +2129,18 @@ GPUNodeLink *GPU_lamp_get_data(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **co if (lamp->la->shadowmap_type == LA_SHADMAP_VARIANCE) { GPU_link(mat, "shadows_only_vsm", - GPU_builtin(GPU_VIEW_POSITION), - GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), - GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), - GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias), - GPU_uniform(lamp->shadow_color), inp, shadow); + GPU_builtin(GPU_VIEW_POSITION), + GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), + GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), + GPU_uniform(&lamp->bias), GPU_uniform(&lamp->la->bleedbias), + GPU_uniform(lamp->shadow_color), inp, shadow); } else { GPU_link(mat, "shadows_only", - GPU_builtin(GPU_VIEW_POSITION), - GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), - GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), - GPU_uniform(&lamp->bias), GPU_uniform(lamp->shadow_color), inp, shadow); + GPU_builtin(GPU_VIEW_POSITION), + GPU_dynamic_texture(lamp->tex, GPU_DYNAMIC_SAMPLER_2DSHADOW, lamp->ob), + GPU_dynamic_uniform((float*)lamp->dynpersmat, GPU_DYNAMIC_LAMP_DYNPERSMAT, lamp->ob), + GPU_uniform(&lamp->bias), GPU_uniform(lamp->shadow_color), inp, shadow); } } else { diff --git a/source/blender/imbuf/intern/divers.c b/source/blender/imbuf/intern/divers.c index 59d08128e5f..65abf22ff2c 100644 --- a/source/blender/imbuf/intern/divers.c +++ b/source/blender/imbuf/intern/divers.c @@ -169,8 +169,8 @@ void IMB_buffer_byte_from_float(uchar *rect_to, const float *rect_from, float tmp[4]; int x, y; DitherContext *di = NULL; - float inv_width = 1.0f / width, - inv_height = 1.0f / height; + float inv_width = 1.0f / width; + float inv_height = 1.0f / height; /* we need valid profiles */ BLI_assert(profile_to != IB_PROFILE_NONE); diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h index 3fb047ebbe7..beffbc4c017 100644 --- a/source/blender/makesdna/DNA_gpencil_types.h +++ b/source/blender/makesdna/DNA_gpencil_types.h @@ -188,7 +188,7 @@ typedef enum eGPdata_Flag { GP_DATA_EXPAND = (1 << 2), /* is the block overriding all clicks? */ - /* GP_DATA_EDITPAINT = (1 << 3), */ + /* GP_DATA_EDITPAINT = (1 << 3), */ /* new strokes are added in viewport space */ GP_DATA_VIEWALIGN = (1 << 4), diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 165f6113b6d..e530841789b 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -638,9 +638,18 @@ typedef struct SpaceFile { struct FileLayout *layout; short recentnr, bookmarknr; - short systemnr, pad2; + short systemnr, system_bookmarknr; } SpaceFile; +/* FSMenuEntry's without paths indicate seperators */ +typedef struct FSMenuEntry { + struct FSMenuEntry *next; + + char *path; + char name[256]; /* FILE_MAXFILE */ + short save; + short pad[3]; +} FSMenuEntry; /* FileSelectParams.display */ enum FileDisplayTypeE { diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 7b33b2ec2b6..503124d94f1 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -240,6 +240,7 @@ extern StructRNA RNA_FModifierNoise; extern StructRNA RNA_FModifierPython; extern StructRNA RNA_FModifierStepped; extern StructRNA RNA_FieldSettings; +extern StructRNA RNA_FileBrowserFSMenuEntry; extern StructRNA RNA_FileSelectParams; extern StructRNA RNA_FloatProperty; extern StructRNA RNA_FloorConstraint; diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 382ed358e12..fc2b2d72ac9 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -56,6 +56,8 @@ #include "RE_engine.h" #include "RE_pipeline.h" +#include "ED_fileselect.h" + #include "RNA_enum_types.h" @@ -204,6 +206,7 @@ static EnumPropertyItem buttons_texture_context_items[] = { #include "BKE_icons.h" #include "ED_buttons.h" +#include "ED_fileselect.h" #include "ED_image.h" #include "ED_node.h" #include "ED_screen.h" @@ -1368,6 +1371,271 @@ static void rna_SpaceClipEditor_view_type_update(Main *UNUSED(bmain), Scene *UNU ED_area_tag_refresh(sa); } +/* File browser. */ + +static void rna_FileBrowser_FSMenuEntry_path_get(PointerRNA *ptr, char *value) +{ + char *path = ED_fsmenu_entry_get_path(ptr->data); + + strcpy(value, path ? path : ""); +} + +static int rna_FileBrowser_FSMenuEntry_path_length(PointerRNA *ptr) +{ + char *path = ED_fsmenu_entry_get_path(ptr->data); + + return (int)(path ? strlen(path) : 0); +} + +static void rna_FileBrowser_FSMenuEntry_path_set(PointerRNA *ptr, const char *value) +{ + FSMenuEntry *fsm = ptr->data; + + /* Note: this will write to file immediately. + * Not nice (and to be fixed ultimately), but acceptable in this case for now. */ + ED_fsmenu_entry_set_path(fsm, value); +} + +static void rna_FileBrowser_FSMenuEntry_name_get(PointerRNA *ptr, char *value) +{ + strcpy(value, ED_fsmenu_entry_get_name(ptr->data)); +} + +static int rna_FileBrowser_FSMenuEntry_name_length(PointerRNA *ptr) +{ + return (int)strlen(ED_fsmenu_entry_get_name(ptr->data)); +} + +static void rna_FileBrowser_FSMenuEntry_name_set(PointerRNA *ptr, const char *value) +{ + FSMenuEntry *fsm = ptr->data; + + /* Note: this will write to file immediately. + * Not nice (and to be fixed ultimately), but acceptable in this case for now. */ + ED_fsmenu_entry_set_name(fsm, value); +} + +static int rna_FileBrowser_FSMenuEntry_name_get_editable(PointerRNA *ptr) +{ + FSMenuEntry *fsm = ptr->data; + + return fsm->save; +} + +static void rna_FileBrowser_FSMenu_next(CollectionPropertyIterator *iter) +{ + ListBaseIterator *internal = &iter->internal.listbase; + + if (internal->skip) { + do { + internal->link = (Link *)(((FSMenuEntry *)(internal->link))->next); + iter->valid = (internal->link != NULL); + } while (iter->valid && internal->skip(iter, internal->link)); + } + else { + internal->link = (Link *)(((FSMenuEntry *)(internal->link))->next); + iter->valid = (internal->link != NULL); + } +} + +static void rna_FileBrowser_FSMenu_begin(CollectionPropertyIterator *iter, FSMenuCategory category) +{ + ListBaseIterator *internal = &iter->internal.listbase; + + struct FSMenu *fsmenu = ED_fsmenu_get(); + struct FSMenuEntry *fsmentry = ED_fsmenu_get_category(fsmenu, category); + + internal->link = (fsmentry) ? (Link *)fsmentry : NULL; + internal->skip = NULL; + + iter->valid = (internal->link != NULL); +} + +static PointerRNA rna_FileBrowser_FSMenu_get(CollectionPropertyIterator *iter) +{ + ListBaseIterator *internal = &iter->internal.listbase; + PointerRNA r_ptr; + + RNA_pointer_create(NULL, &RNA_FileBrowserFSMenuEntry, internal->link, &r_ptr); + + return r_ptr; +} + +static void rna_FileBrowser_FSMenu_end(CollectionPropertyIterator *UNUSED(iter)) +{ +} + +static void rna_FileBrowser_FSMenuSystem_data_begin(CollectionPropertyIterator *iter, PointerRNA *UNUSED(ptr)) +{ + rna_FileBrowser_FSMenu_begin(iter, FS_CATEGORY_SYSTEM); +} + +static int rna_FileBrowser_FSMenuSystem_data_length(PointerRNA *UNUSED(ptr)) +{ + struct FSMenu *fsmenu = ED_fsmenu_get(); + + return ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_SYSTEM); +} + +static void rna_FileBrowser_FSMenuSystemBookmark_data_begin(CollectionPropertyIterator *iter, PointerRNA *UNUSED(ptr)) +{ + rna_FileBrowser_FSMenu_begin(iter, FS_CATEGORY_SYSTEM_BOOKMARKS); +} + +static int rna_FileBrowser_FSMenuSystemBookmark_data_length(PointerRNA *UNUSED(ptr)) +{ + struct FSMenu *fsmenu = ED_fsmenu_get(); + + return ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS); +} + +static void rna_FileBrowser_FSMenuBookmark_data_begin(CollectionPropertyIterator *iter, PointerRNA *UNUSED(ptr)) +{ + rna_FileBrowser_FSMenu_begin(iter, FS_CATEGORY_BOOKMARKS); +} + +static int rna_FileBrowser_FSMenuBookmark_data_length(PointerRNA *UNUSED(ptr)) +{ + struct FSMenu *fsmenu = ED_fsmenu_get(); + + return ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_BOOKMARKS); +} + +static void rna_FileBrowser_FSMenuRecent_data_begin(CollectionPropertyIterator *iter, PointerRNA *UNUSED(ptr)) +{ + rna_FileBrowser_FSMenu_begin(iter, FS_CATEGORY_RECENT); +} + +static int rna_FileBrowser_FSMenuRecent_data_length(PointerRNA *UNUSED(ptr)) +{ + struct FSMenu *fsmenu = ED_fsmenu_get(); + + return ED_fsmenu_get_nentries(fsmenu, FS_CATEGORY_RECENT); +} + +static int rna_FileBrowser_FSMenu_active_get(PointerRNA *ptr, const FSMenuCategory category) +{ + SpaceFile *sf = ptr->data; + int actnr = -1; + + switch (category) { + case FS_CATEGORY_SYSTEM: + actnr = sf->systemnr; + break; + case FS_CATEGORY_SYSTEM_BOOKMARKS: + actnr = sf->system_bookmarknr; + break; + case FS_CATEGORY_BOOKMARKS: + actnr = sf->bookmarknr; + break; + case FS_CATEGORY_RECENT: + actnr = sf->recentnr; + break; + } + + return actnr; +} + +static void rna_FileBrowser_FSMenu_active_set(PointerRNA *ptr, int value, const FSMenuCategory category) +{ + SpaceFile *sf = ptr->data; + struct FSMenu *fsmenu = ED_fsmenu_get(); + FSMenuEntry *fsm = ED_fsmenu_get_entry(fsmenu, category, value); + + if (fsm && sf->params) { + switch (category) { + case FS_CATEGORY_SYSTEM: + sf->systemnr = value; + break; + case FS_CATEGORY_SYSTEM_BOOKMARKS: + sf->system_bookmarknr = value; + break; + case FS_CATEGORY_BOOKMARKS: + sf->bookmarknr = value; + break; + case FS_CATEGORY_RECENT: + sf->recentnr = value; + break; + } + + BLI_strncpy(sf->params->dir, fsm->path, sizeof(sf->params->dir)); + } +} + +static void rna_FileBrowser_FSMenu_active_range( + PointerRNA *UNUSED(ptr), int *min, int *max, int *softmin, int *softmax, const FSMenuCategory category) +{ + struct FSMenu *fsmenu = ED_fsmenu_get(); + + *min = *softmin = -1; + *max = *softmax = ED_fsmenu_get_nentries(fsmenu, category) - 1; +} + +static void rna_FileBrowser_FSMenu_active_update(struct bContext *C, PointerRNA *UNUSED(ptr)) +{ + ED_file_change_dir(C, true); +} + +static int rna_FileBrowser_FSMenuSystem_active_get(PointerRNA *ptr) +{ + return rna_FileBrowser_FSMenu_active_get(ptr, FS_CATEGORY_SYSTEM); +} + +static void rna_FileBrowser_FSMenuSystem_active_set(PointerRNA *ptr, int value) +{ + rna_FileBrowser_FSMenu_active_set(ptr, value, FS_CATEGORY_SYSTEM); +} + +static void rna_FileBrowser_FSMenuSystem_active_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax) +{ + rna_FileBrowser_FSMenu_active_range(ptr, min, max, softmin, softmax, FS_CATEGORY_SYSTEM); +} + +static int rna_FileBrowser_FSMenuSystemBookmark_active_get(PointerRNA *ptr) +{ + return rna_FileBrowser_FSMenu_active_get(ptr, FS_CATEGORY_SYSTEM_BOOKMARKS); +} + +static void rna_FileBrowser_FSMenuSystemBookmark_active_set(PointerRNA *ptr, int value) +{ + rna_FileBrowser_FSMenu_active_set(ptr, value, FS_CATEGORY_SYSTEM_BOOKMARKS); +} + +static void rna_FileBrowser_FSMenuSystemBookmark_active_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax) +{ + rna_FileBrowser_FSMenu_active_range(ptr, min, max, softmin, softmax, FS_CATEGORY_SYSTEM_BOOKMARKS); +} + +static int rna_FileBrowser_FSMenuBookmark_active_get(PointerRNA *ptr) +{ + return rna_FileBrowser_FSMenu_active_get(ptr, FS_CATEGORY_BOOKMARKS); +} + +static void rna_FileBrowser_FSMenuBookmark_active_set(PointerRNA *ptr, int value) +{ + rna_FileBrowser_FSMenu_active_set(ptr, value, FS_CATEGORY_BOOKMARKS); +} + +static void rna_FileBrowser_FSMenuBookmark_active_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax) +{ + rna_FileBrowser_FSMenu_active_range(ptr, min, max, softmin, softmax, FS_CATEGORY_BOOKMARKS); +} + +static int rna_FileBrowser_FSMenuRecent_active_get(PointerRNA *ptr) +{ + return rna_FileBrowser_FSMenu_active_get(ptr, FS_CATEGORY_RECENT); +} + +static void rna_FileBrowser_FSMenuRecent_active_set(PointerRNA *ptr, int value) +{ + rna_FileBrowser_FSMenu_active_set(ptr, value, FS_CATEGORY_RECENT); +} + +static void rna_FileBrowser_FSMenuRecent_active_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax) +{ + rna_FileBrowser_FSMenu_active_range(ptr, min, max, softmin, softmax, FS_CATEGORY_RECENT); +} + #else static EnumPropertyItem dt_uv_items[] = { @@ -3332,6 +3600,37 @@ static void rna_def_fileselect_params(BlenderRNA *brna) RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_LIST, NULL); } +static void rna_def_filemenu_entry(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "FileBrowserFSMenuEntry", NULL); + RNA_def_struct_sdna(srna, "FSMenuEntry"); + RNA_def_struct_ui_text(srna, "File Select Parameters", "File Select Parameters"); + + prop = RNA_def_property(srna, "path", PROP_STRING, PROP_FILEPATH); + RNA_def_property_string_sdna(prop, NULL, "path"); + RNA_def_property_string_funcs(prop, "rna_FileBrowser_FSMenuEntry_path_get", + "rna_FileBrowser_FSMenuEntry_path_length", + "rna_FileBrowser_FSMenuEntry_path_set"); + RNA_def_property_ui_text(prop, "Path", ""); + + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "name"); + RNA_def_property_string_funcs(prop, "rna_FileBrowser_FSMenuEntry_name_get", + "rna_FileBrowser_FSMenuEntry_name_length", + "rna_FileBrowser_FSMenuEntry_name_set"); + RNA_def_property_editable_func(prop, "rna_FileBrowser_FSMenuEntry_name_get_editable"); + RNA_def_property_ui_text(prop, "Name", ""); + RNA_def_struct_name_property(srna, prop); + + prop = RNA_def_property(srna, "use_save", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "save", 1); + RNA_def_property_ui_text(prop, "Save", "Whether this path is saved in bookmarks, or generated from OS"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); +} + static void rna_def_space_filebrowser(BlenderRNA *brna) { StructRNA *srna; @@ -3354,6 +3653,67 @@ static void rna_def_space_filebrowser(BlenderRNA *brna) prop = RNA_def_property(srna, "operator", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "op"); RNA_def_property_ui_text(prop, "Active Operator", ""); + + /* bookmarks, recent files etc. */ + prop = RNA_def_collection(srna, "system_folders", "FileBrowserFSMenuEntry", "System Folders", + "System's folders (usually root, available hard drives, etc)"); + RNA_def_property_collection_funcs(prop, "rna_FileBrowser_FSMenuSystem_data_begin", "rna_FileBrowser_FSMenu_next", + "rna_FileBrowser_FSMenu_end", "rna_FileBrowser_FSMenu_get", + "rna_FileBrowser_FSMenuSystem_data_length", NULL, NULL, NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop = RNA_def_int(srna, "system_folders_active", -1, -1, INT_MAX, "Active System Folder", + "Index of active system folder (-1 if none)", -1, INT_MAX); + RNA_def_property_int_sdna(prop, NULL, "systemnr"); + RNA_def_property_int_funcs(prop, "rna_FileBrowser_FSMenuSystem_active_get", + "rna_FileBrowser_FSMenuSystem_active_set", "rna_FileBrowser_FSMenuSystem_active_range"); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, "rna_FileBrowser_FSMenu_active_update"); + + prop = RNA_def_collection(srna, "system_bookmarks", "FileBrowserFSMenuEntry", "System Bookmarks", + "System's bookmarks"); + RNA_def_property_collection_funcs(prop, "rna_FileBrowser_FSMenuSystemBookmark_data_begin", "rna_FileBrowser_FSMenu_next", + "rna_FileBrowser_FSMenu_end", "rna_FileBrowser_FSMenu_get", + "rna_FileBrowser_FSMenuSystemBookmark_data_length", NULL, NULL, NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop = RNA_def_int(srna, "system_bookmarks_active", -1, -1, INT_MAX, "Active System Bookmark", + "Index of active system bookmark (-1 if none)", -1, INT_MAX); + RNA_def_property_int_sdna(prop, NULL, "system_bookmarknr"); + RNA_def_property_int_funcs(prop, "rna_FileBrowser_FSMenuSystemBookmark_active_get", + "rna_FileBrowser_FSMenuSystemBookmark_active_set", "rna_FileBrowser_FSMenuSystemBookmark_active_range"); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, "rna_FileBrowser_FSMenu_active_update"); + + prop = RNA_def_collection(srna, "bookmarks", "FileBrowserFSMenuEntry", "Bookmarks", + "User's bookmarks"); + RNA_def_property_collection_funcs(prop, "rna_FileBrowser_FSMenuBookmark_data_begin", "rna_FileBrowser_FSMenu_next", + "rna_FileBrowser_FSMenu_end", "rna_FileBrowser_FSMenu_get", + "rna_FileBrowser_FSMenuBookmark_data_length", NULL, NULL, NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop = RNA_def_int(srna, "bookmarks_active", -1, -1, INT_MAX, "Active Bookmark", + "Index of active bookmark (-1 if none)", -1, INT_MAX); + RNA_def_property_int_sdna(prop, NULL, "bookmarknr"); + RNA_def_property_int_funcs(prop, "rna_FileBrowser_FSMenuBookmark_active_get", + "rna_FileBrowser_FSMenuBookmark_active_set", "rna_FileBrowser_FSMenuBookmark_active_range"); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, "rna_FileBrowser_FSMenu_active_update"); + + prop = RNA_def_collection(srna, "recent_folders", "FileBrowserFSMenuEntry", "Recent Folders", + ""); + RNA_def_property_collection_funcs(prop, "rna_FileBrowser_FSMenuRecent_data_begin", "rna_FileBrowser_FSMenu_next", + "rna_FileBrowser_FSMenu_end", "rna_FileBrowser_FSMenu_get", + "rna_FileBrowser_FSMenuRecent_data_length", NULL, NULL, NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + + prop = RNA_def_int(srna, "recent_folders_active", -1, -1, INT_MAX, "Active Recent Folder", + "Index of active recent folder (-1 if none)", -1, INT_MAX); + RNA_def_property_int_sdna(prop, NULL, "recentnr"); + RNA_def_property_int_funcs(prop, "rna_FileBrowser_FSMenuRecent_active_get", + "rna_FileBrowser_FSMenuRecent_active_set", "rna_FileBrowser_FSMenuRecent_active_range"); + RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, "rna_FileBrowser_FSMenu_active_update"); } static void rna_def_space_info(BlenderRNA *brna) @@ -3957,6 +4317,7 @@ void RNA_def_space(BlenderRNA *brna) rna_def_space_sequencer(brna); rna_def_space_text(brna); rna_def_fileselect_params(brna); + rna_def_filemenu_entry(brna); rna_def_space_filebrowser(brna); rna_def_space_outliner(brna); rna_def_background_image(brna); diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index b5eeebae664..fea8b630af6 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -682,14 +682,14 @@ void RNA_api_ui_layout(StructRNA *srna) func = RNA_def_function(srna, "template_modifier", "uiTemplateModifier"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); - RNA_def_function_ui_description(func, "Layout . Generates the UI layout for modifiers"); + RNA_def_function_ui_description(func, "Generates the UI layout for modifiers"); parm = RNA_def_pointer(func, "data", "Modifier", "", "Modifier data"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL); parm = RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in"); RNA_def_function_return(func, parm); func = RNA_def_function(srna, "template_constraint", "uiTemplateConstraint"); - RNA_def_function_ui_description(func, "Layout . Generates the UI layout for constraints"); + RNA_def_function_ui_description(func, "Generates the UI layout for constraints"); parm = RNA_def_pointer(func, "data", "Constraint", "", "Constraint data"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR | PROP_NEVER_NULL); parm = RNA_def_pointer(func, "layout", "UILayout", "", "Sub-layout to put items in"); @@ -826,6 +826,8 @@ void RNA_api_ui_layout(StructRNA *srna) parm = RNA_def_string(func, "active_propname", NULL, 0, "", "Identifier of the integer property in active_data, index of the active item"); RNA_def_property_flag(parm, PROP_REQUIRED); + RNA_def_string(func, "item_dyntip_propname", NULL, 0, "", + "Identifier of a string property in items, to use as tooltip content"); RNA_def_int(func, "rows", 5, 0, INT_MAX, "", "Default and minimum number of rows to display", 0, INT_MAX); RNA_def_int(func, "maxrows", 5, 0, INT_MAX, "", "Default maximum number of rows to display", 0, INT_MAX); RNA_def_enum(func, "type", uilist_layout_type_items, UILST_LAYOUT_DEFAULT, "Type", "Type of layout to use"); diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c index 174f3df73d4..59348c5a5ae 100644 --- a/source/blender/modifiers/intern/MOD_mask.c +++ b/source/blender/modifiers/intern/MOD_mask.c @@ -51,6 +51,8 @@ #include "depsgraph_private.h" +#include "BLI_strict_flags.h" + static void copyData(ModifierData *md, ModifierData *target) { #if 0 @@ -105,14 +107,15 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, int maxVerts, maxEdges, maxPolys; int i; - MPoly *mpoly; - MLoop *mloop; - - MPoly *mpoly_new; - MLoop *mloop_new; - MEdge *medge_new; - MVert *mvert_new; + const MVert *mvert_src; + const MEdge *medge_src; + const MPoly *mpoly_src; + const MLoop *mloop_src; + MPoly *mpoly_dst; + MLoop *mloop_dst; + MEdge *medge_dst; + MVert *mvert_dst; int *loop_mapping; @@ -158,7 +161,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, * - each cell is a boolean saying whether bone corresponding to the ith group is selected * - groups that don't match a bone are treated as not existing (along with the corresponding ungrouped verts) */ - bone_select_array = MEM_mallocN(defbase_tot * sizeof(char), "mask array"); + bone_select_array = MEM_mallocN((size_t)defbase_tot * sizeof(char), "mask array"); for (i = 0, def = ob->defbase.first; def; def = def->next, i++) { pchan = BKE_pose_channel_find_name(oba->pose, def->name); @@ -174,7 +177,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, /* verthash gives mapping from original vertex indices to the new indices (including selected matches only) * key = oldindex, value = newindex */ - vertHash = BLI_ghash_int_new("mask vert gh"); + vertHash = BLI_ghash_int_new_ex("mask vert gh", (unsigned int)maxVerts); /* add vertices which exist in vertexgroups into vertHash for filtering * - dv = for each vertex, what vertexgroups does it belong to @@ -217,7 +220,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, return dm; /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */ - vertHash = BLI_ghash_int_new("mask vert2 bh"); + vertHash = BLI_ghash_int_new_ex("mask vert2 bh", (unsigned int)maxVerts); /* add vertices which exist in vertexgroup into ghash for filtering */ for (i = 0, dv = dvert; i < maxVerts; i++, dv++) { @@ -233,37 +236,39 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } /* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */ - edgeHash = BLI_ghash_int_new("mask ed2 gh"); - polyHash = BLI_ghash_int_new("mask fa2 gh"); - - mpoly = dm->getPolyArray(dm); - mloop = dm->getLoopArray(dm); + edgeHash = BLI_ghash_int_new_ex("mask ed2 gh", (unsigned int)maxEdges); + polyHash = BLI_ghash_int_new_ex("mask fa2 gh", (unsigned int)maxPolys); - loop_mapping = MEM_callocN(sizeof(int) * maxPolys, "mask loopmap"); /* overalloc, assume all polys are seen */ + mvert_src = dm->getVertArray(dm); + medge_src = dm->getEdgeArray(dm); + mpoly_src = dm->getPolyArray(dm); + mloop_src = dm->getLoopArray(dm); + + /* overalloc, assume all polys are seen */ + loop_mapping = MEM_mallocN(sizeof(int) * (size_t)maxPolys, "mask loopmap"); /* loop over edges and faces, and do the same thing to * ensure that they only reference existing verts */ for (i = 0; i < maxEdges; i++) { - MEdge me; - dm->getEdge(dm, i, &me); + const MEdge *me = &medge_src[i]; /* only add if both verts will be in new mesh */ - if (BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) && - BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2))) + if (BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v1)) && + BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v2))) { BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numEdges)); numEdges++; } } for (i = 0; i < maxPolys; i++) { - MPoly *mp = &mpoly[i]; - MLoop *ml = mloop + mp->loopstart; + const MPoly *mp_src = &mpoly_src[i]; + const MLoop *ml_src = &mloop_src[mp_src->loopstart]; bool ok = true; int j; - for (j = 0; j < mp->totloop; j++, ml++) { - if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(ml->v))) { + for (j = 0; j < mp_src->totloop; j++, ml_src++) { + if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(ml_src->v))) { ok = false; break; } @@ -274,7 +279,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, BLI_ghash_insert(polyHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numPolys)); loop_mapping[numPolys] = numLoops; numPolys++; - numLoops += mp->totloop; + numLoops += mp_src->totloop; } } @@ -284,62 +289,62 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, */ result = CDDM_from_template(dm, numVerts, numEdges, 0, numLoops, numPolys); - mpoly_new = CDDM_get_polys(result); - mloop_new = CDDM_get_loops(result); - medge_new = CDDM_get_edges(result); - mvert_new = CDDM_get_verts(result); + mpoly_dst = CDDM_get_polys(result); + mloop_dst = CDDM_get_loops(result); + medge_dst = CDDM_get_edges(result); + mvert_dst = CDDM_get_verts(result); /* using ghash-iterators, map data into new mesh */ /* vertices */ GHASH_ITER (gh_iter, vertHash) { - MVert source; - MVert *dest; - int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&gh_iter)); - int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)); - - dm->getVert(dm, oldIndex, &source); - dest = &mvert_new[newIndex]; + const MVert *v_src; + MVert *v_dst; + const int i_src = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&gh_iter)); + const int i_dst = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)); - DM_copy_vert_data(dm, result, oldIndex, newIndex, 1); - *dest = source; + v_src = &mvert_src[i_src]; + v_dst = &mvert_dst[i_dst]; + + *v_dst = *v_src; + DM_copy_vert_data(dm, result, i_src, i_dst, 1); } /* edges */ GHASH_ITER (gh_iter, edgeHash) { - MEdge source; - MEdge *dest; - int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&gh_iter)); - int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)); + const MEdge *e_src; + MEdge *e_dst; + const int i_src = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&gh_iter)); + const int i_dst = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)); - dm->getEdge(dm, oldIndex, &source); - dest = &medge_new[newIndex]; + e_src = &medge_src[i_src]; + e_dst = &medge_dst[i_dst]; - source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1))); - source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2))); + *e_dst = *e_src; + e_dst->v1 = GET_UINT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_UINT_IN_POINTER(e_src->v1))); + e_dst->v2 = GET_UINT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_UINT_IN_POINTER(e_src->v2))); - DM_copy_edge_data(dm, result, oldIndex, newIndex, 1); - *dest = source; + DM_copy_edge_data(dm, result, i_src, i_dst, 1); } /* faces */ GHASH_ITER (gh_iter, polyHash) { - int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&gh_iter)); - int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)); - MPoly *source = &mpoly[oldIndex]; - MPoly *dest = &mpoly_new[newIndex]; - int oldLoopIndex = source->loopstart; - int newLoopIndex = loop_mapping[newIndex]; - MLoop *source_loop = &mloop[oldLoopIndex]; - MLoop *dest_loop = &mloop_new[newLoopIndex]; + const int i_src = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&gh_iter)); + const int i_dst = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)); + const MPoly *mp_src = &mpoly_src[i_src]; + MPoly *mp_dst = &mpoly_dst[i_dst]; + const int i_ml_src = mp_src->loopstart; + const int i_ml_dst = loop_mapping[i_dst]; + const MLoop *ml_src = &mloop_src[i_ml_src]; + MLoop *ml_dst = &mloop_dst[i_ml_dst]; - DM_copy_poly_data(dm, result, oldIndex, newIndex, 1); - DM_copy_loop_data(dm, result, oldLoopIndex, newLoopIndex, source->totloop); - - *dest = *source; - dest->loopstart = newLoopIndex; - for (i = 0; i < source->totloop; i++) { - dest_loop[i].v = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source_loop[i].v))); - dest_loop[i].e = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(source_loop[i].e))); + DM_copy_poly_data(dm, result, i_src, i_dst, 1); + DM_copy_loop_data(dm, result, i_ml_src, i_ml_dst, mp_src->totloop); + + *mp_dst = *mp_src; + mp_dst->loopstart = i_ml_dst; + for (i = 0; i < mp_src->totloop; i++) { + ml_dst[i].v = GET_UINT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_UINT_IN_POINTER(ml_src[i].v))); + ml_dst[i].e = GET_UINT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_UINT_IN_POINTER(ml_src[i].e))); } } diff --git a/source/blender/quicktime/apple/qtkit_export.m b/source/blender/quicktime/apple/qtkit_export.m index 0c193df3861..cbc76e26aa9 100644 --- a/source/blender/quicktime/apple/qtkit_export.m +++ b/source/blender/quicktime/apple/qtkit_export.m @@ -814,22 +814,26 @@ void free_qtcomponentdata(void) void quicktime_verify_image_type(RenderData *rd, ImageFormatData *imf) { if (imf->imtype == R_IMF_IMTYPE_QUICKTIME) { - if ((rd->qtcodecsettings.codecType<= 0) || - (rd->qtcodecsettings.codecSpatialQuality <0) || - (rd->qtcodecsettings.codecSpatialQuality > 100)) { - + if ((rd->qtcodecsettings.codecType <= 0) || + (rd->qtcodecsettings.codecSpatialQuality < 0) || + (rd->qtcodecsettings.codecSpatialQuality > 100)) + { rd->qtcodecsettings.codecType = kJPEGCodecType; - rd->qtcodecsettings.codecSpatialQuality = (codecHighQuality*100)/codecLosslessQuality; + rd->qtcodecsettings.codecSpatialQuality = (codecHighQuality * 100) / codecLosslessQuality; } if ((rd->qtcodecsettings.audioSampleRate < 21000) || - (rd->qtcodecsettings.audioSampleRate > 193000)) + (rd->qtcodecsettings.audioSampleRate > 193000)) + { rd->qtcodecsettings.audioSampleRate = 48000; + } - if (rd->qtcodecsettings.audioBitDepth == 0) + if (rd->qtcodecsettings.audioBitDepth == 0) { rd->qtcodecsettings.audioBitDepth = AUD_FORMAT_S16; + } - if (rd->qtcodecsettings.audioBitRate == 0) + if (rd->qtcodecsettings.audioBitRate == 0) { rd->qtcodecsettings.audioBitRate = 256000; + } } } diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 1e30e05fe1a..21ca7924fa0 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -718,10 +718,10 @@ static void render_result_rescale(Render *re) scale_y = (float) result->recty / re->result->recty; for (x = 0; x < re->result->rectx; ++x) { for (y = 0; y < re->result->recty; ++y) { - int src_x = x * scale_x, - src_y = y * scale_y; - int dst_index = y * re->result->rectx + x, - src_index = src_y * result->rectx + src_x; + int src_x = x * scale_x; + int src_y = y * scale_y; + int dst_index = y * re->result->rectx + x; + int src_index = src_y * result->rectx + src_x; copy_v4_v4(dst_rectf + dst_index * 4, src_rectf + src_index * 4); } diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 21c69ac6203..e4319632797 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -355,7 +355,16 @@ void ED_area_tag_redraw_regiontype(struct ScrArea *sa, int regiontype) RET_NONE void ED_render_engine_changed(struct Main *bmain) RET_NONE void ED_file_read_bookmarks(void) RET_NONE +void ED_file_change_dir(struct bContext *C, const bool checkdir) RET_NONE void ED_preview_kill_jobs(struct wmWindowManager *wm, struct Main *bmain) RET_NONE +struct FSMenu *ED_fsmenu_get(void) RET_NULL +struct FSMenuEntry *ED_fsmenu_get_category(struct FSMenu *fsmenu, FSMenuCategory category) RET_NULL +int ED_fsmenu_get_nentries(struct FSMenu *fsmenu, FSMenuCategory category) RET_ZERO +struct FSMenuEntry *ED_fsmenu_get_entry(struct FSMenu *fsmenu, FSMenuCategory category, int index) RET_NULL +char *ED_fsmenu_entry_get_path(struct FSMenuEntry *fsentry) RET_NULL +void ED_fsmenu_entry_set_path(struct FSMenuEntry *fsentry, const char *name) RET_NONE +char *ED_fsmenu_entry_get_name(struct FSMenuEntry *fsentry) RET_NULL +void ED_fsmenu_entry_set_name(struct FSMenuEntry *fsentry, const char *name) RET_NONE struct PTCacheEdit *PE_get_current(struct Scene *scene, struct Object *ob) RET_NULL void PE_current_changed(struct Scene *scene, struct Object *ob) RET_NONE @@ -547,7 +556,7 @@ void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, const char *prop void uiTemplateImageLayers(struct uiLayout *layout, struct bContext *C, struct Image *ima, struct ImageUser *iuser) RET_NONE void uiTemplateList(struct uiLayout *layout, struct bContext *C, const char *listtype_name, const char *list_id, PointerRNA *dataptr, const char *propname, PointerRNA *active_dataptr, const char *active_propname, - int rows, int maxrows, int layout_type, int columns) RET_NONE + const char *item_dyntip_propname, int rows, int maxrows, int layout_type, int columns) RET_NONE void uiTemplateRunningJobs(struct uiLayout *layout, struct bContext *C) RET_NONE void uiTemplateOperatorSearch(struct uiLayout *layout) RET_NONE void uiTemplateHeader3D(struct uiLayout *layout, struct bContext *C) RET_NONE diff --git a/source/gameengine/Ketsji/KX_MouseActuator.cpp b/source/gameengine/Ketsji/KX_MouseActuator.cpp index 8774abe04b2..4afa1818536 100644 --- a/source/gameengine/Ketsji/KX_MouseActuator.cpp +++ b/source/gameengine/Ketsji/KX_MouseActuator.cpp @@ -138,7 +138,7 @@ bool KX_MouseActuator::Update() center_x = ((m_canvas->GetWidth() - 1.0) / 2.0) / (m_canvas->GetWidth()); } if ((m_canvas->GetHeight() % 2) != 0) { - center_y = ((m_canvas->GetHeight() - 1.0) / 2.0) / (m_canvas->GetHeight()); + center_y = ((m_canvas->GetHeight() - 1.0) / 2.0) / (m_canvas->GetHeight()); } //preventing initial skipping. |