Compare commits
124 Commits
temp-attri
...
filebrowse
Author | SHA1 | Date | |
---|---|---|---|
![]() |
37590a6a11 | ||
![]() |
d35efde181 | ||
![]() |
82bc196736 | ||
![]() |
99acf30edd | ||
![]() |
aa0db0038e | ||
![]() |
337ba032e4 | ||
![]() |
cbe7143589 | ||
![]() |
bee91a5a5a | ||
![]() |
e859086b18 | ||
![]() |
2f7718aa23 | ||
![]() |
3b78360a46 | ||
![]() |
e2dbf96fd4 | ||
![]() |
04e4852a99 | ||
![]() |
b78b8cc17e | ||
![]() |
8f6894a6ad | ||
![]() |
c3453e1667 | ||
![]() |
ea94cade29 | ||
![]() |
54d156288d | ||
![]() |
64f43d5367 | ||
![]() |
b95d371a83 | ||
![]() |
c081ebb9a5 | ||
![]() |
02b18d7353 | ||
![]() |
8b08f487b2 | ||
![]() |
15bc4143fc | ||
![]() |
adccfb33e5 | ||
![]() |
4e2be2f39e | ||
![]() |
20278a3776 | ||
854ea231c4 | |||
![]() |
bb5b98e770 | ||
![]() |
86db4b0c3f | ||
![]() |
de0bfa1d6a | ||
![]() |
0a3866dc83 | ||
![]() |
fcc54d06ce | ||
![]() |
935d622458 | ||
![]() |
8209f25c3b | ||
4befee9e62 | |||
04e445ccfb | |||
dfd6bcf500 | |||
![]() |
98c0c32769 | ||
35f985fcd5 | |||
![]() |
2360168b03 | ||
![]() |
f1b48a2957 | ||
![]() |
ec498e00e5 | ||
![]() |
eb1ae3b788 | ||
fdd32d8a15 | |||
e6065ee240 | |||
c1015a13af | |||
3c034eab5a | |||
![]() |
d0a8796e34 | ||
![]() |
ea96913ed5 | ||
![]() |
bc5e7a2e49 | ||
![]() |
1290e63e7e | ||
7ed7955c25 | |||
5d99a8c083 | |||
![]() |
1cfbd0e476 | ||
![]() |
d37464461d | ||
![]() |
7b4f7592e3 | ||
![]() |
d64b275153 | ||
![]() |
b9898ebde4 | ||
b17380971a | |||
4b8e4c9dfb | |||
354da16b7b | |||
02b00e4cf2 | |||
02557510bf | |||
df79abdae8 | |||
909a48e382 | |||
8d804f5d2b | |||
![]() |
5c531c7f31 | ||
![]() |
8aba00a673 | ||
![]() |
33371915c9 | ||
![]() |
2f6831e691 | ||
![]() |
b2bc426c00 | ||
![]() |
d9cf9c659c | ||
![]() |
5909e31087 | ||
![]() |
f8a39ae0e4 | ||
![]() |
c5b872c060 | ||
![]() |
109cd4640b | ||
![]() |
15fb122008 | ||
![]() |
3a09e34eb1 | ||
![]() |
321e1cba4a | ||
![]() |
ef7c697932 | ||
![]() |
c9e7c6bef8 | ||
![]() |
d400714a9a | ||
![]() |
c3483c765b | ||
![]() |
27f1d88382 | ||
![]() |
768091dd0a | ||
![]() |
6f67257ee0 | ||
![]() |
d191cbe1d6 | ||
![]() |
f7d848bfd5 | ||
![]() |
43e3dd87a5 | ||
![]() |
7b361c60b0 | ||
![]() |
498bb3202f | ||
![]() |
d395d84c66 | ||
![]() |
b84bcc314f | ||
![]() |
4dbaa1bab3 | ||
![]() |
18e1132c72 | ||
![]() |
2e2dde7448 | ||
![]() |
03d2dcec7d | ||
![]() |
6ad2056282 | ||
![]() |
b9ebb9014f | ||
![]() |
51117a044b | ||
![]() |
ce6e34e131 | ||
![]() |
cb44212073 | ||
![]() |
e4053cc785 | ||
![]() |
d2269cfe6b | ||
![]() |
965d4683c0 | ||
![]() |
acadc67e07 | ||
![]() |
d271955a92 | ||
![]() |
d50091024c | ||
![]() |
9eb667b76d | ||
![]() |
9a2c45a3b1 | ||
![]() |
84012c2119 | ||
![]() |
56cf28f427 | ||
![]() |
f40a7b41ae | ||
![]() |
2729290e36 | ||
![]() |
e78d9946b8 | ||
![]() |
23cfdc948f | ||
![]() |
9dc25744b3 | ||
![]() |
903d0a35b3 | ||
![]() |
1be01b3d5b | ||
![]() |
da2e53c9e7 | ||
![]() |
bf7e9f6691 | ||
![]() |
4376965a2e | ||
![]() |
d069dc9859 |
Binary file not shown.
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 10 KiB |
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 562 KiB After Width: | Height: | Size: 543 KiB |
48
release/datafiles/prvicons_update.py
Executable file → Normal file
48
release/datafiles/prvicons_update.py
Executable file → Normal file
@@ -1,23 +1,25 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# This script updates icons from the SVG file
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
BASEDIR = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
inkscape_path = 'inkscape'
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
inkscape_app_path = '/Applications/Inkscape.app/Contents/Resources/script'
|
||||
if os.path.exists(inkscape_app_path):
|
||||
inkscape_path = inkscape_app_path
|
||||
|
||||
cmd = (
|
||||
inkscape_path,
|
||||
os.path.join(BASEDIR, "prvicons.svg"),
|
||||
"--without-gui",
|
||||
"--export-png=" + os.path.join(BASEDIR, "prvicons.png"),
|
||||
)
|
||||
subprocess.check_call(cmd)
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# This script updates icons from the SVG file
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
BASEDIR = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
inkscape_path = 'inkscape'
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
inkscape_app_path = '/Applications/Inkscape.app/Contents/Resources/script'
|
||||
if os.path.exists(inkscape_app_path):
|
||||
inkscape_path = inkscape_app_path
|
||||
|
||||
cmd = (
|
||||
inkscape_path,
|
||||
os.path.join(BASEDIR, "prvicons.svg"),
|
||||
"--export-width=1536",
|
||||
"--export-height=256",
|
||||
"--without-gui",
|
||||
"--export-png=" + os.path.join(BASEDIR, "prvicons.png"),
|
||||
)
|
||||
subprocess.check_call(cmd)
|
||||
|
@@ -370,7 +370,7 @@ const bTheme U_theme_default = {
|
||||
.paint_curve_handle = RGBA(0x7fff7f7f),
|
||||
},
|
||||
.space_file = {
|
||||
.back = RGBA(0x35353500),
|
||||
.back = RGBA(0x33333300),
|
||||
.title = RGBA(0xffffffff),
|
||||
.text = RGBA(0xe6e6e6ff),
|
||||
.text_hi = RGBA(0xffffffff),
|
||||
@@ -381,13 +381,14 @@ const bTheme U_theme_default = {
|
||||
.tab_inactive = RGBA(0x2b2b2bff),
|
||||
.tab_back = RGBA(0x232323ff),
|
||||
.tab_outline = RGBA(0x232323ff),
|
||||
.button = RGBA(0x424242ff),
|
||||
.button = RGBA(0x4b4b4bff),
|
||||
.button_title = RGBA(0xffffffff),
|
||||
.button_text = RGBA(0xe5e5e5ff),
|
||||
.button_text_hi = RGBA(0xffffffff),
|
||||
.execution_buts = RGBA(0x444444ff),
|
||||
.panelcolors = {
|
||||
.header = RGBA(0x424242cc),
|
||||
.back = RGBA(0x333333b3),
|
||||
.header = RGBA(0x4b4b4bff),
|
||||
.back = RGBA(0x404040ff),
|
||||
.sub_back = RGBA(0x0000003e),
|
||||
},
|
||||
.hilite = RGBA(0x4f76b3ff),
|
||||
|
@@ -1771,6 +1771,11 @@ def km_file_browser(_params):
|
||||
)
|
||||
|
||||
items.extend([
|
||||
*_template_space_region_type_toggle(
|
||||
toolbar_key={"type": 'T', "value": 'PRESS'},
|
||||
),
|
||||
("screen.region_toggle", {"type": 'N', "value": 'PRESS'},
|
||||
{"properties": [("region_type", 'TOOL_PROPS')]}),
|
||||
("file.parent", {"type": 'UP_ARROW', "value": 'PRESS', "alt": True}, None),
|
||||
("file.previous", {"type": 'LEFT_ARROW', "value": 'PRESS', "alt": True}, None),
|
||||
("file.next", {"type": 'RIGHT_ARROW', "value": 'PRESS', "alt": True}, None),
|
||||
@@ -1782,7 +1787,6 @@ def km_file_browser(_params):
|
||||
{"properties": [("data_path", 'space_data.params.show_hidden')]}),
|
||||
("file.directory_new", {"type": 'I', "value": 'PRESS'}, None),
|
||||
("file.smoothscroll", {"type": 'TIMER1', "value": 'ANY', "any": True}, None),
|
||||
("file.bookmark_toggle", {"type": 'T', "value": 'PRESS'}, None),
|
||||
("file.bookmark_add", {"type": 'B', "value": 'PRESS', "ctrl": True}, None),
|
||||
])
|
||||
|
||||
@@ -1801,17 +1805,13 @@ def km_file_browser_main(params):
|
||||
("file.execute", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'},
|
||||
{"properties": [("need_active", True)]}),
|
||||
("file.refresh", {"type": 'NUMPAD_PERIOD', "value": 'PRESS'}, None),
|
||||
("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK'}, None),
|
||||
("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK', "shift": True},
|
||||
{"properties": [("extend", True)]}),
|
||||
("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK', "shift": True, "ctrl": True},
|
||||
{"properties": [("extend", True), ("fill", True)]}),
|
||||
("file.select", {"type": 'RIGHTMOUSE', "value": 'CLICK'},
|
||||
("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK'},
|
||||
{"properties": [("open", False)]}),
|
||||
("file.select", {"type": 'RIGHTMOUSE', "value": 'CLICK', "shift": True},
|
||||
{"properties": [("extend", True), ("open", False)]}),
|
||||
("file.select", {"type": 'RIGHTMOUSE', "value": 'CLICK', "alt": True},
|
||||
{"properties": [("extend", True), ("fill", True), ("open", False)]}),
|
||||
("file.select", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None),
|
||||
("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK', "ctrl": True},
|
||||
{"properties": [("extend", True)]}),
|
||||
("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK', "shift": True},
|
||||
{"properties": [("extend", True), ("fill", True)]}),
|
||||
("file.select_walk", {"type": 'UP_ARROW', "value": 'PRESS'},
|
||||
{"properties": [("direction", 'UP')]}),
|
||||
("file.select_walk", {"type": 'UP_ARROW', "value": 'PRESS', "shift": True},
|
||||
@@ -1843,8 +1843,11 @@ def km_file_browser_main(params):
|
||||
("file.select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY'}, None),
|
||||
("file.select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY', "shift": True},
|
||||
{"properties": [("mode", 'ADD')]}),
|
||||
("file.rename", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, None),
|
||||
("file.select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY', "ctrl": True},
|
||||
{"properties": [("mode", 'SUB')]}),
|
||||
("file.highlight", {"type": 'MOUSEMOVE', "value": 'ANY', "any": True}, None),
|
||||
("file.sort_column_ui_context", {"type": 'LEFTMOUSE', "value": 'PRESS', "any": True}, None),
|
||||
op_menu("FILEBROWSER_MT_context_menu", params.context_menu_event),
|
||||
("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS'},
|
||||
{"properties": [("increment", 1)]}),
|
||||
("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "shift": True},
|
||||
|
@@ -1196,10 +1196,11 @@ def km_file_browser_main(params):
|
||||
("file.execute", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'},
|
||||
{"properties": [("need_active", True)]}),
|
||||
("file.refresh", {"type": 'R', "value": 'PRESS', "ctrl": True}, None),
|
||||
("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK'}, None),
|
||||
("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK', "shift": True},
|
||||
("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK'},
|
||||
{"properties": [("open", False)]}),
|
||||
("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK', "ctrl": True},
|
||||
{"properties": [("extend", True)]}),
|
||||
("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK', "shift": True, "ctrl": True},
|
||||
("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK', "shift": True,},
|
||||
{"properties": [("extend", True), ("fill", True)]}),
|
||||
("file.select", {"type": 'RIGHTMOUSE', "value": 'CLICK'},
|
||||
{"properties": [("open", False)]}),
|
||||
@@ -1239,6 +1240,8 @@ def km_file_browser_main(params):
|
||||
("file.select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY', "shift": True},
|
||||
{"properties": [("mode", 'ADD')]}),
|
||||
("file.highlight", {"type": 'MOUSEMOVE', "value": 'ANY', "any": True}, None),
|
||||
("file.sort_column_ui_context", {"type": 'LEFTMOUSE', "value": 'PRESS', "any": True}, None),
|
||||
op_menu("FILEBROWSER_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}),
|
||||
("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS'},
|
||||
{"properties": [("increment", 1)]}),
|
||||
("file.filenum", {"type": 'NUMPAD_PLUS', "value": 'PRESS', "shift": True},
|
||||
|
@@ -34,58 +34,131 @@ class FILEBROWSER_HT_header(Header):
|
||||
|
||||
layout.menu("FILEBROWSER_MT_view")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.operator("file.previous", text="", icon='BACK')
|
||||
row.operator("file.next", text="", icon='FORWARD')
|
||||
row.operator("file.parent", text="", icon='FILE_PARENT')
|
||||
row.operator("file.refresh", text="", icon='FILE_REFRESH')
|
||||
|
||||
layout.operator_context = 'EXEC_DEFAULT'
|
||||
layout.operator("file.directory_new", icon='NEWFOLDER', text="")
|
||||
|
||||
layout.operator_context = 'INVOKE_DEFAULT'
|
||||
|
||||
# can be None when save/reload with a file selector open
|
||||
if params:
|
||||
is_lib_browser = params.use_library_browsing
|
||||
|
||||
layout.prop(params, "display_type", expand=True, text="")
|
||||
layout.prop(params, "sort_method", expand=True, text="")
|
||||
layout.prop(params, "show_hidden", text="", icon='FILE_HIDDEN')
|
||||
|
||||
layout.separator_spacer()
|
||||
|
||||
layout.template_running_jobs()
|
||||
|
||||
if params:
|
||||
layout.prop(params, "use_filter", text="", icon='FILTER')
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.active = params.use_filter
|
||||
row.prop(params, "use_filter_folder", text="")
|
||||
class FILEBROWSER_PT_display(Panel):
|
||||
bl_space_type = 'FILE_BROWSER'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "Display"
|
||||
|
||||
if params.filter_glob:
|
||||
# if st.active_operator and hasattr(st.active_operator, "filter_glob"):
|
||||
# row.prop(params, "filter_glob", text="")
|
||||
row.label(text=params.filter_glob)
|
||||
else:
|
||||
row.prop(params, "use_filter_blender", text="")
|
||||
row.prop(params, "use_filter_backup", text="")
|
||||
row.prop(params, "use_filter_image", text="")
|
||||
row.prop(params, "use_filter_movie", text="")
|
||||
row.prop(params, "use_filter_script", text="")
|
||||
row.prop(params, "use_filter_font", text="")
|
||||
row.prop(params, "use_filter_sound", text="")
|
||||
row.prop(params, "use_filter_text", text="")
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
# can be None when save/reload with a file selector open
|
||||
return context.space_data.params is not None
|
||||
|
||||
if is_lib_browser:
|
||||
row.prop(params, "use_filter_blendid", text="")
|
||||
if params.use_filter_blendid:
|
||||
row.separator()
|
||||
row.prop(params, "filter_id_category", text="")
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
row.separator()
|
||||
row.prop(params, "filter_search", text="", icon='VIEWZOOM')
|
||||
space = context.space_data
|
||||
params = space.params
|
||||
is_lib_browser = params.use_library_browsing
|
||||
|
||||
layout.label(text="Display as")
|
||||
layout.column().prop(params, "display_type", expand=True)
|
||||
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False # No animation.
|
||||
|
||||
if params.display_type == 'THUMBNAIL':
|
||||
layout.prop(params, "display_size", text="Size")
|
||||
else:
|
||||
layout.prop(params, "show_details_size", text="Size")
|
||||
layout.prop(params, "show_details_datetime", text="Date")
|
||||
|
||||
layout.prop(params, "recursion_level", text="Recursions")
|
||||
|
||||
layout.use_property_split = False
|
||||
layout.separator()
|
||||
|
||||
layout.label(text="Sort by")
|
||||
layout.column().prop(params, "sort_method", expand=True)
|
||||
layout.prop(params, "use_sort_invert")
|
||||
|
||||
|
||||
class FILEBROWSER_PT_filter(Panel):
|
||||
bl_space_type = 'FILE_BROWSER'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = "Filter"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
# can be None when save/reload with a file selector open
|
||||
return context.space_data.params is not None
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
space = context.space_data
|
||||
params = space.params
|
||||
is_lib_browser = params.use_library_browsing
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(params, "use_filter", text="", toggle=0)
|
||||
row.label(text="Filter")
|
||||
|
||||
col = layout.column()
|
||||
col.active = params.use_filter
|
||||
|
||||
row = col.row()
|
||||
row.label(icon='FILE_FOLDER')
|
||||
row.prop(params, "use_filter_folder", text="Folders", toggle=0)
|
||||
|
||||
if params.filter_glob:
|
||||
col.label(text=params.filter_glob)
|
||||
else:
|
||||
row = col.row()
|
||||
row.label(icon='FILE_BLEND')
|
||||
row.prop(params, "use_filter_blender",
|
||||
text=".blend Files", toggle=0)
|
||||
row = col.row()
|
||||
row.label(icon='FILE_BACKUP')
|
||||
row.prop(params, "use_filter_backup",
|
||||
text="Backup .blend Files", toggle=0)
|
||||
row = col.row()
|
||||
row.label(icon='FILE_IMAGE')
|
||||
row.prop(params, "use_filter_image", text="Image Files", toggle=0)
|
||||
row = col.row()
|
||||
row.label(icon='FILE_MOVIE')
|
||||
row.prop(params, "use_filter_movie", text="Movie Files", toggle=0)
|
||||
row = col.row()
|
||||
row.label(icon='FILE_SCRIPT')
|
||||
row.prop(params, "use_filter_script",
|
||||
text="Script Files", toggle=0)
|
||||
row = col.row()
|
||||
row.label(icon='FILE_FONT')
|
||||
row.prop(params, "use_filter_font", text="Font Files", toggle=0)
|
||||
row = col.row()
|
||||
row.label(icon='FILE_SOUND')
|
||||
row.prop(params, "use_filter_sound", text="Sound Files", toggle=0)
|
||||
row = col.row()
|
||||
row.label(icon='FILE_TEXT')
|
||||
row.prop(params, "use_filter_text", text="Text Files", toggle=0)
|
||||
|
||||
col.separator()
|
||||
|
||||
if is_lib_browser:
|
||||
row = col.row()
|
||||
row.label(icon='BLANK1') # Indentation
|
||||
row.prop(params, "use_filter_blendid",
|
||||
text="Blender IDs", toggle=0)
|
||||
if params.use_filter_blendid:
|
||||
row = col.row()
|
||||
row.label(icon='BLANK1') # Indentation
|
||||
row.prop(params, "filter_id_category", text="")
|
||||
|
||||
col.separator()
|
||||
|
||||
layout.prop(params, "show_hidden")
|
||||
|
||||
|
||||
def panel_poll_is_upper_region(region):
|
||||
# The upper region is left-aligned, the lower is split into it then.
|
||||
return region.alignment == 'LEFT'
|
||||
|
||||
|
||||
class FILEBROWSER_UL_dir(UIList):
|
||||
@@ -119,10 +192,13 @@ class FILEBROWSER_UL_dir(UIList):
|
||||
class FILEBROWSER_PT_bookmarks_volumes(Panel):
|
||||
bl_space_type = 'FILE_BROWSER'
|
||||
bl_region_type = 'TOOLS'
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
bl_category = "Bookmarks"
|
||||
bl_label = "Volumes"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return panel_poll_is_upper_region(context.region)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
space = context.space_data
|
||||
@@ -141,7 +217,7 @@ class FILEBROWSER_PT_bookmarks_system(Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return not context.preferences.filepaths.hide_system_bookmarks
|
||||
return not context.preferences.filepaths.hide_system_bookmarks and panel_poll_is_upper_region(context.region)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -161,8 +237,10 @@ class FILEBROWSER_MT_bookmarks_context_menu(Menu):
|
||||
layout.operator("file.bookmark_cleanup", icon='X', text="Cleanup")
|
||||
|
||||
layout.separator()
|
||||
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'
|
||||
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_favorites(Panel):
|
||||
@@ -171,6 +249,10 @@ class FILEBROWSER_PT_bookmarks_favorites(Panel):
|
||||
bl_category = "Bookmarks"
|
||||
bl_label = "Favorites"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return panel_poll_is_upper_region(context.region)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
space = context.space_data
|
||||
@@ -185,12 +267,15 @@ class FILEBROWSER_PT_bookmarks_favorites(Panel):
|
||||
col = row.column(align=True)
|
||||
col.operator("file.bookmark_add", icon='ADD', text="")
|
||||
col.operator("file.bookmark_delete", icon='REMOVE', text="")
|
||||
col.menu("FILEBROWSER_MT_bookmarks_context_menu", icon='DOWNARROW_HLT', text="")
|
||||
col.menu("FILEBROWSER_MT_bookmarks_context_menu",
|
||||
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'
|
||||
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='ADD')
|
||||
|
||||
@@ -203,7 +288,7 @@ class FILEBROWSER_PT_bookmarks_recents(Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return not context.preferences.filepaths.hide_recent_locations
|
||||
return not context.preferences.filepaths.hide_recent_locations and panel_poll_is_upper_region(context.region)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -227,7 +312,7 @@ class FILEBROWSER_PT_advanced_filter(Panel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
# only useful in append/link (library) context currently...
|
||||
return context.space_data.params.use_library_browsing
|
||||
return context.space_data.params.use_library_browsing and panel_poll_is_upper_region(context.region)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
@@ -242,6 +327,133 @@ class FILEBROWSER_PT_advanced_filter(Panel):
|
||||
col.prop(params, "filter_id")
|
||||
|
||||
|
||||
class FILEBROWSER_PT_options_toggle(Panel):
|
||||
bl_space_type = 'FILE_BROWSER'
|
||||
bl_region_type = 'TOOLS'
|
||||
bl_label = "Options Toggle"
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
sfile = context.space_data
|
||||
return context.region.alignment == 'BOTTOM' and sfile.active_operator
|
||||
|
||||
def is_option_region_visible(self, context):
|
||||
for region in context.area.regions:
|
||||
if region.type == 'TOOL_PROPS' and region.width <= 1:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
label = "Hide Options" if self.is_option_region_visible(
|
||||
context) else "Options"
|
||||
|
||||
layout.scale_x = 1.3
|
||||
layout.scale_y = 1.3
|
||||
|
||||
layout.operator("screen.region_toggle",
|
||||
text=label).region_type = 'TOOL_PROPS'
|
||||
|
||||
|
||||
class FILEBROWSER_PT_directory_path(Panel):
|
||||
bl_space_type = 'FILE_BROWSER'
|
||||
bl_region_type = 'UI'
|
||||
bl_label = "Directory Path"
|
||||
bl_category = "Attributes"
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
|
||||
def is_header_visible(self, context):
|
||||
for region in context.area.regions:
|
||||
if region.type == 'HEADER' and region.height <= 1:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
space = context.space_data
|
||||
params = space.params
|
||||
|
||||
layout.scale_x = 1.3
|
||||
layout.scale_y = 1.3
|
||||
|
||||
row = layout.row()
|
||||
|
||||
subrow = row.row(align=True)
|
||||
subrow.operator("file.previous", text="", icon='BACK')
|
||||
subrow.operator("file.next", text="", icon='FORWARD')
|
||||
subrow.operator("file.parent", text="", icon='FILE_PARENT')
|
||||
subrow.operator("file.refresh", text="", icon='FILE_REFRESH')
|
||||
|
||||
row.operator("file.directory_new", icon='NEWFOLDER', text="")
|
||||
|
||||
subrow = row.row()
|
||||
subrow.prop(params, "directory", text="")
|
||||
|
||||
subrow = row.row()
|
||||
subrow.scale_x = 0.5
|
||||
subrow.prop(params, "filter_search", text="", icon='VIEWZOOM')
|
||||
|
||||
# Uses prop_with_popover() as popover() only adds the triangle icon in headers.
|
||||
row.prop_with_popover(
|
||||
params,
|
||||
"display_type",
|
||||
panel="FILEBROWSER_PT_display",
|
||||
text="",
|
||||
icon_only=True,
|
||||
)
|
||||
row.prop_with_popover(
|
||||
params,
|
||||
"display_type",
|
||||
panel="FILEBROWSER_PT_filter",
|
||||
text="",
|
||||
icon='FILTER',
|
||||
icon_only=True,
|
||||
)
|
||||
|
||||
|
||||
class FILEBROWSER_PT_file_operation(Panel):
|
||||
bl_space_type = 'FILE_BROWSER'
|
||||
bl_region_type = 'EXECUTE'
|
||||
bl_label = "Execute File Operation"
|
||||
bl_options = {'HIDE_HEADER'}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.space_data.active_operator
|
||||
|
||||
def draw(self, context):
|
||||
import sys
|
||||
|
||||
layout = self.layout
|
||||
space = context.space_data
|
||||
params = space.params
|
||||
|
||||
layout.scale_x = 1.3
|
||||
layout.scale_y = 1.3
|
||||
|
||||
row = layout.row()
|
||||
sub = row.row()
|
||||
sub.prop(params, "filename", text="")
|
||||
sub = row.row()
|
||||
sub.ui_units_x = 5
|
||||
|
||||
# subsub = sub.row(align=True)
|
||||
# subsub.operator("file.filenum", text="", icon='ADD').increment = 1
|
||||
# subsub.operator("file.filenum", text="", icon='REMOVE').increment = -1
|
||||
|
||||
# organize buttons according to the OS standard
|
||||
if sys.platform != "win":
|
||||
sub.operator("FILE_OT_cancel", text="Cancel")
|
||||
subsub = sub.row()
|
||||
subsub.active_default = True
|
||||
subsub.operator("FILE_OT_execute", text=params.title)
|
||||
if sys.platform == "win":
|
||||
sub.operator("FILE_OT_cancel", text="Cancel")
|
||||
|
||||
|
||||
class FILEBROWSER_MT_view(Menu):
|
||||
bl_label = "View"
|
||||
|
||||
@@ -250,7 +462,7 @@ class FILEBROWSER_MT_view(Menu):
|
||||
st = context.space_data
|
||||
params = st.params
|
||||
|
||||
layout.prop(st, "show_region_toolbar")
|
||||
layout.prop(st, "show_region_toolbar", text="Source List")
|
||||
layout.prop(st, "show_region_ui", text="File Path")
|
||||
|
||||
layout.separator()
|
||||
@@ -263,8 +475,46 @@ class FILEBROWSER_MT_view(Menu):
|
||||
layout.menu("INFO_MT_area")
|
||||
|
||||
|
||||
class FILEBROWSER_MT_context_menu(Menu):
|
||||
bl_label = "Files Context Menu"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
st = context.space_data
|
||||
params = st.params
|
||||
|
||||
layout.operator("file.previous", text="Back")
|
||||
layout.operator("file.next", text="Forward")
|
||||
layout.operator("file.parent", text="Go to Parent")
|
||||
layout.operator("file.refresh", text="Refresh")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("file.filenum", text="Increase Number",
|
||||
icon='ADD').increment = 1
|
||||
layout.operator("file.filenum", text="Decrease Number",
|
||||
icon='REMOVE').increment = -1
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("file.rename", text="Rename")
|
||||
# layout.operator("file.delete")
|
||||
layout.operator("file.directory_new", text="New Folder")
|
||||
layout.operator("file.bookmark_add", text="Add Bookmark")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.prop_menu_enum(params, "display_type")
|
||||
if params.display_type == 'THUMBNAIL':
|
||||
layout.prop_menu_enum(params, "display_size")
|
||||
layout.prop_menu_enum(params, "recursion_level", text="Recursions")
|
||||
layout.prop_menu_enum(params, "sort_method")
|
||||
|
||||
|
||||
classes = (
|
||||
FILEBROWSER_HT_header,
|
||||
FILEBROWSER_PT_display,
|
||||
FILEBROWSER_PT_filter,
|
||||
FILEBROWSER_UL_dir,
|
||||
FILEBROWSER_PT_bookmarks_volumes,
|
||||
FILEBROWSER_PT_bookmarks_system,
|
||||
@@ -272,7 +522,11 @@ classes = (
|
||||
FILEBROWSER_PT_bookmarks_favorites,
|
||||
FILEBROWSER_PT_bookmarks_recents,
|
||||
FILEBROWSER_PT_advanced_filter,
|
||||
FILEBROWSER_PT_directory_path,
|
||||
FILEBROWSER_PT_file_operation,
|
||||
FILEBROWSER_PT_options_toggle,
|
||||
FILEBROWSER_MT_view,
|
||||
FILEBROWSER_MT_context_menu,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
|
@@ -99,8 +99,13 @@ void BLI_filelist_entry_size_to_string(const struct stat *st,
|
||||
void BLI_filelist_entry_mode_to_string(
|
||||
const struct stat *st, const bool compact, char r_mode1[], char r_mode2[], char r_mode3[]);
|
||||
void BLI_filelist_entry_owner_to_string(const struct stat *st, const bool compact, char r_owner[]);
|
||||
void BLI_filelist_entry_datetime_to_string(
|
||||
const struct stat *st, const int64_t ts, const bool compact, char r_time[], char r_date[]);
|
||||
void BLI_filelist_entry_datetime_to_string(const struct stat *st,
|
||||
const int64_t ts,
|
||||
const bool compact,
|
||||
char r_time[],
|
||||
char r_date[],
|
||||
bool *r_is_today,
|
||||
bool *r_is_yesterday);
|
||||
|
||||
/* Files */
|
||||
|
||||
|
@@ -261,36 +261,17 @@ unsigned int BLI_filelist_dir_contents(const char *dirname, struct direntry **r_
|
||||
*/
|
||||
void BLI_filelist_entry_size_to_string(const struct stat *st,
|
||||
const uint64_t sz,
|
||||
const bool compact,
|
||||
/* Used to change MB -> M, etc. - is that really useful? */
|
||||
const bool UNUSED(compact),
|
||||
char r_size[FILELIST_DIRENTRY_SIZE_LEN])
|
||||
{
|
||||
double size;
|
||||
const char *fmt;
|
||||
const char *units[] = {"KiB", "MiB", "GiB", "TiB", NULL};
|
||||
const char *units_compact[] = {"K", "M", "G", "T", NULL};
|
||||
const char *unit = "B";
|
||||
|
||||
/*
|
||||
* Seems st_size is signed 32-bit value in *nix and Windows. This
|
||||
* will buy us some time until files get bigger than 4GB or until
|
||||
* everyone starts using __USE_FILE_OFFSET64 or equivalent.
|
||||
*/
|
||||
size = (double)(st ? st->st_size : sz);
|
||||
|
||||
if (size > 1024.0) {
|
||||
const char **u;
|
||||
for (u = compact ? units_compact : units, size /= 1024.0; size > 1024.0 && *(u + 1);
|
||||
u++, size /= 1024.0) {
|
||||
/* pass */
|
||||
}
|
||||
fmt = size > 100.0 ? "%.0f %s" : (size > 10.0 ? "%.1f %s" : "%.2f %s");
|
||||
unit = *u;
|
||||
}
|
||||
else {
|
||||
fmt = "%.0f %s";
|
||||
}
|
||||
|
||||
BLI_snprintf(r_size, sizeof(*r_size) * FILELIST_DIRENTRY_SIZE_LEN, fmt, size, unit);
|
||||
double size = (double)(st ? st->st_size : sz);
|
||||
BLI_str_format_byte_unit(r_size, size, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -366,14 +347,45 @@ void BLI_filelist_entry_owner_to_string(const struct stat *st,
|
||||
|
||||
/**
|
||||
* Convert given entry's time into human-readable strings.
|
||||
*
|
||||
* \param r_is_today: optional, returns true if the date matches today's.
|
||||
* \param r_is_yesterday: optional, returns true if the date matches yesterday's.
|
||||
*/
|
||||
void BLI_filelist_entry_datetime_to_string(const struct stat *st,
|
||||
const int64_t ts,
|
||||
const bool compact,
|
||||
char r_time[FILELIST_DIRENTRY_TIME_LEN],
|
||||
char r_date[FILELIST_DIRENTRY_DATE_LEN])
|
||||
char r_date[FILELIST_DIRENTRY_DATE_LEN],
|
||||
bool *r_is_today,
|
||||
bool *r_is_yesterday)
|
||||
{
|
||||
time_t ts_mtime = ts;
|
||||
int today_year = 0;
|
||||
int today_yday = 0;
|
||||
int yesterday_year = 0;
|
||||
int yesterday_yday = 0;
|
||||
|
||||
if (r_is_today || r_is_yesterday) {
|
||||
/* Localtime() has only one buffer so need to get data out before called again. */
|
||||
const time_t ts_now = time(NULL);
|
||||
struct tm *today = localtime(&ts_now);
|
||||
|
||||
today_year = today->tm_year;
|
||||
today_yday = today->tm_yday;
|
||||
/* Handle a yesterday that spans a year */
|
||||
today->tm_mday--;
|
||||
mktime(today);
|
||||
yesterday_year = today->tm_year;
|
||||
yesterday_yday = today->tm_yday;
|
||||
|
||||
if (r_is_today) {
|
||||
*r_is_today = false;
|
||||
}
|
||||
if (r_is_yesterday) {
|
||||
*r_is_yesterday = false;
|
||||
}
|
||||
}
|
||||
|
||||
const time_t ts_mtime = ts;
|
||||
const struct tm *tm = localtime(st ? &st->st_mtime : &ts_mtime);
|
||||
const time_t zero = 0;
|
||||
|
||||
@@ -385,12 +397,20 @@ void BLI_filelist_entry_datetime_to_string(const struct stat *st,
|
||||
if (r_time) {
|
||||
strftime(r_time, sizeof(*r_time) * FILELIST_DIRENTRY_TIME_LEN, "%H:%M", tm);
|
||||
}
|
||||
|
||||
if (r_date) {
|
||||
strftime(r_date,
|
||||
sizeof(*r_date) * FILELIST_DIRENTRY_DATE_LEN,
|
||||
compact ? "%d/%m/%y" : "%d-%b-%y",
|
||||
compact ? "%d/%m/%y" : "%d %b %Y",
|
||||
tm);
|
||||
}
|
||||
|
||||
if (r_is_today && (tm->tm_year == today_year) && (tm->tm_yday == today_yday)) {
|
||||
*r_is_today = true;
|
||||
}
|
||||
else if (r_is_yesterday && (tm->tm_year == yesterday_year) && (tm->tm_yday == yesterday_yday)) {
|
||||
*r_is_yesterday = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -3722,5 +3722,39 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
||||
|
||||
{
|
||||
/* Versioning code until next subversion bump goes here. */
|
||||
|
||||
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
|
||||
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
|
||||
for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
|
||||
if (sl->spacetype == SPACE_FILE) {
|
||||
SpaceFile *sfile = (SpaceFile *)sl;
|
||||
ListBase *regionbase = (sl == sa->spacedata.first) ? &sa->regionbase : &sl->regionbase;
|
||||
ARegion *ar_ui = do_versions_find_region(regionbase, RGN_TYPE_UI);
|
||||
ARegion *ar_header = do_versions_find_region(regionbase, RGN_TYPE_HEADER);
|
||||
ARegion *ar_toolprops = do_versions_find_region_or_null(regionbase,
|
||||
RGN_TYPE_TOOL_PROPS);
|
||||
|
||||
/* Reinsert UI region so that it spawns entire area width */
|
||||
BLI_remlink(regionbase, ar_ui);
|
||||
BLI_insertlinkafter(regionbase, ar_header, ar_ui);
|
||||
|
||||
ar_ui->flag |= RGN_FLAG_DYNAMIC_SIZE;
|
||||
|
||||
if (ar_toolprops && (ar_toolprops->alignment == (RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV))) {
|
||||
SpaceType *stype = BKE_spacetype_from_id(sl->spacetype);
|
||||
|
||||
/* Remove empty region at old location. */
|
||||
BLI_assert(sfile->op == NULL);
|
||||
BKE_area_region_free(stype, ar_toolprops);
|
||||
BLI_freelinkN(regionbase, ar_toolprops);
|
||||
}
|
||||
|
||||
if (sfile->params) {
|
||||
sfile->params->details_flags |= FILE_DETAILS_SIZE | FILE_DETAILS_DATETIME;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -150,6 +150,7 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme)
|
||||
* Include next version bump.
|
||||
*/
|
||||
{
|
||||
FROM_DEFAULT_V4_UCHAR(space_file.execution_buts);
|
||||
}
|
||||
|
||||
#undef FROM_DEFAULT_V4_UCHAR
|
||||
|
@@ -34,17 +34,32 @@ struct wmWindowManager;
|
||||
#define FILE_LAYOUT_HOR 1
|
||||
#define FILE_LAYOUT_VER 2
|
||||
|
||||
#define MAX_FILE_COLUMN 4
|
||||
|
||||
typedef enum FileListColumns {
|
||||
typedef enum FileAttributeColumnType {
|
||||
COLUMN_NONE = -1,
|
||||
COLUMN_NAME = 0,
|
||||
COLUMN_DATE,
|
||||
COLUMN_TIME,
|
||||
COLUMN_DATETIME,
|
||||
COLUMN_SIZE,
|
||||
} FileListColumns;
|
||||
|
||||
ATTRIBUTE_COLUMN_MAX
|
||||
} FileAttributeColumnType;
|
||||
|
||||
typedef struct FileAttributeColumn {
|
||||
/** UI name for this column */
|
||||
const char *name;
|
||||
|
||||
float width;
|
||||
/* The sort type to use when sorting by this column. */
|
||||
int sort_type; /* eFileSortType */
|
||||
|
||||
/* Alignment of column texts, header text is always left aligned */
|
||||
int text_align; /* eFontStyle_Align */
|
||||
} FileAttributeColumn;
|
||||
|
||||
typedef struct FileLayout {
|
||||
/* view settings - XXX - move into own struct */
|
||||
int offset_top;
|
||||
/* Height of the header for the different FileAttributeColumn's. */
|
||||
int attribute_column_header_h;
|
||||
int prv_w;
|
||||
int prv_h;
|
||||
int tile_w;
|
||||
@@ -54,13 +69,17 @@ typedef struct FileLayout {
|
||||
int prv_border_x;
|
||||
int prv_border_y;
|
||||
int rows;
|
||||
int columns;
|
||||
/* Those are the major layout columns the files are distributed across, not to be confused with
|
||||
* 'attribute_columns' array below. */
|
||||
int flow_columns;
|
||||
int width;
|
||||
int height;
|
||||
int flag;
|
||||
int dirty;
|
||||
int textheight;
|
||||
float column_widths[MAX_FILE_COLUMN];
|
||||
/* The columns for each item (name, modification date/time, size). Not to be confused with the
|
||||
* 'flow_columns' above. */
|
||||
FileAttributeColumn attribute_columns[ATTRIBUTE_COLUMN_MAX];
|
||||
|
||||
/* When we change display size, we may have to update static strings like size of files... */
|
||||
short curr_size;
|
||||
@@ -72,6 +91,7 @@ typedef struct FileSelection {
|
||||
} FileSelection;
|
||||
|
||||
struct rcti;
|
||||
struct View2D;
|
||||
|
||||
struct FileSelectParams *ED_fileselect_get_params(struct SpaceFile *sfile);
|
||||
|
||||
@@ -87,6 +107,17 @@ int ED_fileselect_layout_numfiles(FileLayout *layout, struct ARegion *ar);
|
||||
int ED_fileselect_layout_offset(FileLayout *layout, int x, int y);
|
||||
FileSelection ED_fileselect_layout_offset_rect(FileLayout *layout, const struct rcti *rect);
|
||||
|
||||
void ED_fileselect_layout_maskrect(const FileLayout *layout,
|
||||
const struct View2D *v2d,
|
||||
struct rcti *r_rect);
|
||||
bool ED_fileselect_layout_is_inside_pt(const FileLayout *layout,
|
||||
const struct View2D *v2d,
|
||||
int x,
|
||||
int y);
|
||||
bool ED_fileselect_layout_isect_rect(const FileLayout *layout,
|
||||
const struct View2D *v2d,
|
||||
const struct rcti *rect,
|
||||
struct rcti *r_dst);
|
||||
void ED_fileselect_layout_tilepos(FileLayout *layout, int tile, int *x, int *y);
|
||||
|
||||
void ED_operatormacros_file(void);
|
||||
|
@@ -2244,6 +2244,8 @@ int UI_idcode_icon_get(const int idcode)
|
||||
return ICON_FONT_DATA;
|
||||
case ID_WO:
|
||||
return ICON_WORLD_DATA;
|
||||
case ID_WS:
|
||||
return ICON_WORKSPACE;
|
||||
default:
|
||||
return ICON_NONE;
|
||||
}
|
||||
|
@@ -1265,9 +1265,6 @@ static void region_rect_recursive(
|
||||
else if (ED_area_is_global(sa)) {
|
||||
prefsizey = ED_region_global_size_y();
|
||||
}
|
||||
else if (ar->regiontype == RGN_TYPE_UI && sa->spacetype == SPACE_FILE) {
|
||||
prefsizey = UI_UNIT_Y * 2 + (UI_UNIT_Y / 2);
|
||||
}
|
||||
else {
|
||||
prefsizey = UI_DPI_FAC * (ar->sizey > 1 ? ar->sizey + 0.5f : ar->type->prefsizey);
|
||||
}
|
||||
|
@@ -3935,6 +3935,65 @@ static void SCREEN_OT_region_quadview(wmOperatorType *ot)
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Region Toggle Operator
|
||||
* \{ */
|
||||
|
||||
static int region_toggle_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "region_type");
|
||||
ARegion *region;
|
||||
|
||||
if (RNA_property_is_set(op->ptr, prop)) {
|
||||
region = BKE_area_find_region_type(CTX_wm_area(C), RNA_property_enum_get(op->ptr, prop));
|
||||
}
|
||||
else {
|
||||
region = CTX_wm_region(C);
|
||||
}
|
||||
|
||||
if (region) {
|
||||
ED_region_toggle_hidden(C, region);
|
||||
}
|
||||
ED_region_tag_redraw(region);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static bool region_toggle_poll(bContext *C)
|
||||
{
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
|
||||
/* don't flip anything around in topbar */
|
||||
if (area && area->spacetype == SPACE_TOPBAR) {
|
||||
CTX_wm_operator_poll_msg_set(C, "Toggling regions in the Top-bar is not allowed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ED_operator_areaactive(C);
|
||||
}
|
||||
|
||||
static void SCREEN_OT_region_toggle(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Toggle Region";
|
||||
ot->idname = "SCREEN_OT_region_toggle";
|
||||
ot->description = "Hide or unhide the region";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = region_toggle_exec;
|
||||
ot->poll = region_toggle_poll;
|
||||
ot->flag = 0;
|
||||
|
||||
RNA_def_enum(ot->srna,
|
||||
"region_type",
|
||||
rna_enum_region_type_items,
|
||||
0,
|
||||
"Region Type",
|
||||
"Type of the region to toggle");
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Region Flip Operator
|
||||
* \{ */
|
||||
@@ -5361,6 +5420,7 @@ void ED_operatortypes_screen(void)
|
||||
WM_operatortype_append(SCREEN_OT_area_swap);
|
||||
WM_operatortype_append(SCREEN_OT_region_quadview);
|
||||
WM_operatortype_append(SCREEN_OT_region_scale);
|
||||
WM_operatortype_append(SCREEN_OT_region_toggle);
|
||||
WM_operatortype_append(SCREEN_OT_region_flip);
|
||||
WM_operatortype_append(SCREEN_OT_header_toggle_menus);
|
||||
WM_operatortype_append(SCREEN_OT_region_context_menu);
|
||||
|
@@ -710,7 +710,7 @@ static void SOUND_OT_mixdown(wmOperatorType *ot)
|
||||
FILE_TYPE_FOLDER | FILE_TYPE_SOUND,
|
||||
FILE_SPECIAL,
|
||||
FILE_SAVE,
|
||||
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH,
|
||||
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_SHOW_PROPS,
|
||||
FILE_DEFAULTDISPLAY,
|
||||
FILE_SORT_ALPHA);
|
||||
#ifdef WITH_AUDASPACE
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_fileops_types.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_math.h"
|
||||
|
||||
@@ -77,234 +78,6 @@ static char *file_draw_tooltip_func(bContext *UNUSED(C), void *argN, const char
|
||||
return BLI_strdup(dyn_tooltip);
|
||||
}
|
||||
|
||||
/* Note: This function uses pixelspace (0, 0, winx, winy), not view2d.
|
||||
* The controls are laid out as follows:
|
||||
*
|
||||
* -------------------------------------------
|
||||
* | Directory input | execute |
|
||||
* -------------------------------------------
|
||||
* | Filename input | + | - | cancel |
|
||||
* -------------------------------------------
|
||||
*
|
||||
* The input widgets will stretch to fill any excess space.
|
||||
* When there isn't enough space for all controls to be shown, they are
|
||||
* hidden in this order: x/-, execute/cancel, input widgets.
|
||||
*/
|
||||
void file_draw_buttons(const bContext *C, ARegion *ar)
|
||||
{
|
||||
/* Button layout. */
|
||||
const int max_x = ar->winx - 10;
|
||||
const int line1_y = ar->winy - (IMASEL_BUTTONS_HEIGHT / 2 + IMASEL_BUTTONS_MARGIN);
|
||||
const int line2_y = line1_y - (IMASEL_BUTTONS_HEIGHT / 2 + IMASEL_BUTTONS_MARGIN);
|
||||
const int input_minw = 20;
|
||||
const int btn_h = UI_UNIT_Y;
|
||||
const int btn_fn_w = UI_UNIT_X;
|
||||
const int btn_minw = 80;
|
||||
const int btn_margin = 20;
|
||||
const int separator = 4;
|
||||
|
||||
/* Additional locals. */
|
||||
char uiblockstr[32];
|
||||
int loadbutton;
|
||||
int fnumbuttons;
|
||||
int min_x = 10;
|
||||
int chan_offs = 0;
|
||||
int available_w = max_x - min_x;
|
||||
int line1_w = available_w;
|
||||
int line2_w = available_w;
|
||||
|
||||
uiBut *but;
|
||||
uiBlock *block;
|
||||
SpaceFile *sfile = CTX_wm_space_file(C);
|
||||
FileSelectParams *params = ED_fileselect_get_params(sfile);
|
||||
ARegion *artmp;
|
||||
const bool is_browse_only = (sfile->op == NULL);
|
||||
|
||||
/* Initialize UI block. */
|
||||
BLI_snprintf(uiblockstr, sizeof(uiblockstr), "win %p", (void *)ar);
|
||||
block = UI_block_begin(C, ar, uiblockstr, UI_EMBOSS);
|
||||
|
||||
/* 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_TOOLS && artmp->flag & RGN_FLAG_HIDDEN) {
|
||||
chan_offs = 16;
|
||||
min_x += chan_offs;
|
||||
available_w -= chan_offs;
|
||||
}
|
||||
}
|
||||
|
||||
/* Is there enough space for the execute / cancel buttons? */
|
||||
|
||||
if (is_browse_only) {
|
||||
loadbutton = 0;
|
||||
}
|
||||
else {
|
||||
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
|
||||
loadbutton = UI_fontstyle_string_width(fstyle, params->title) + btn_margin;
|
||||
CLAMP_MIN(loadbutton, btn_minw);
|
||||
if (available_w <= loadbutton + separator + input_minw) {
|
||||
loadbutton = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (loadbutton) {
|
||||
line1_w -= (loadbutton + separator);
|
||||
line2_w = line1_w;
|
||||
}
|
||||
|
||||
/* Is there enough space for file number increment/decrement buttons? */
|
||||
fnumbuttons = 2 * btn_fn_w;
|
||||
if (!loadbutton || line2_w <= fnumbuttons + separator + input_minw) {
|
||||
fnumbuttons = 0;
|
||||
}
|
||||
else {
|
||||
line2_w -= (fnumbuttons + separator);
|
||||
}
|
||||
|
||||
/* Text input fields for directory and file. */
|
||||
if (available_w > 0) {
|
||||
const struct FileDirEntry *file = sfile->files ?
|
||||
filelist_file(sfile->files, params->active_file) :
|
||||
NULL;
|
||||
int overwrite_alert = file_draw_check_exists(sfile);
|
||||
const bool is_active_dir = file && (file->typeflag & FILE_TYPE_FOLDER);
|
||||
|
||||
/* callbacks for operator check functions */
|
||||
UI_block_func_set(block, file_draw_check_cb, NULL, NULL);
|
||||
|
||||
but = uiDefBut(block,
|
||||
UI_BTYPE_TEXT,
|
||||
-1,
|
||||
"",
|
||||
min_x,
|
||||
line1_y,
|
||||
line1_w - chan_offs,
|
||||
btn_h,
|
||||
params->dir,
|
||||
0.0,
|
||||
(float)FILE_MAX,
|
||||
0,
|
||||
0,
|
||||
TIP_("File path"));
|
||||
UI_but_func_complete_set(but, autocomplete_directory, NULL);
|
||||
UI_but_flag_enable(but, UI_BUT_NO_UTF8);
|
||||
UI_but_flag_disable(but, UI_BUT_UNDO);
|
||||
UI_but_funcN_set(but, file_directory_enter_handle, NULL, but);
|
||||
|
||||
/* TODO, directory editing is non-functional while a library is loaded
|
||||
* until this is properly supported just disable it. */
|
||||
if (sfile->files && filelist_lib(sfile->files)) {
|
||||
UI_but_flag_enable(but, UI_BUT_DISABLED);
|
||||
}
|
||||
|
||||
if ((params->flag & FILE_DIRSEL_ONLY) == 0) {
|
||||
but = uiDefBut(
|
||||
block,
|
||||
UI_BTYPE_TEXT,
|
||||
-1,
|
||||
"",
|
||||
min_x,
|
||||
line2_y,
|
||||
line2_w - chan_offs,
|
||||
btn_h,
|
||||
is_active_dir ? (char *)"" : params->file,
|
||||
0.0,
|
||||
(float)FILE_MAXFILE,
|
||||
0,
|
||||
0,
|
||||
TIP_(overwrite_alert ? N_("File name, overwrite existing") : N_("File name")));
|
||||
UI_but_func_complete_set(but, autocomplete_file, NULL);
|
||||
UI_but_flag_enable(but, UI_BUT_NO_UTF8);
|
||||
UI_but_flag_disable(but, UI_BUT_UNDO);
|
||||
/* silly workaround calling NFunc to ensure this does not get called
|
||||
* immediate ui_apply_but_func but only after button deactivates */
|
||||
UI_but_funcN_set(but, file_filename_enter_handle, NULL, but);
|
||||
|
||||
/* check if this overrides a file and if the operator option is used */
|
||||
if (overwrite_alert) {
|
||||
UI_but_flag_enable(but, UI_BUT_REDALERT);
|
||||
}
|
||||
}
|
||||
|
||||
/* clear func */
|
||||
UI_block_func_set(block, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/* Filename number increment / decrement buttons. */
|
||||
if (fnumbuttons && (params->flag & FILE_DIRSEL_ONLY) == 0) {
|
||||
UI_block_align_begin(block);
|
||||
but = uiDefIconButO(block,
|
||||
UI_BTYPE_BUT,
|
||||
"FILE_OT_filenum",
|
||||
0,
|
||||
ICON_REMOVE,
|
||||
min_x + line2_w + separator - chan_offs,
|
||||
line2_y,
|
||||
btn_fn_w,
|
||||
btn_h,
|
||||
TIP_("Decrement the filename number"));
|
||||
RNA_int_set(UI_but_operator_ptr_get(but), "increment", -1);
|
||||
|
||||
but = uiDefIconButO(block,
|
||||
UI_BTYPE_BUT,
|
||||
"FILE_OT_filenum",
|
||||
0,
|
||||
ICON_ADD,
|
||||
min_x + line2_w + separator + btn_fn_w - chan_offs,
|
||||
line2_y,
|
||||
btn_fn_w,
|
||||
btn_h,
|
||||
TIP_("Increment the filename number"));
|
||||
RNA_int_set(UI_but_operator_ptr_get(but), "increment", 1);
|
||||
UI_block_align_end(block);
|
||||
}
|
||||
|
||||
/* Execute / cancel buttons. */
|
||||
if (loadbutton) {
|
||||
const struct FileDirEntry *file = sfile->files ?
|
||||
filelist_file(sfile->files, params->active_file) :
|
||||
NULL;
|
||||
char const *str_exec;
|
||||
|
||||
if (file && FILENAME_IS_PARENT(file->relpath)) {
|
||||
str_exec = IFACE_("Parent Directory");
|
||||
}
|
||||
else if (file && file->typeflag & FILE_TYPE_DIR) {
|
||||
str_exec = IFACE_("Open Directory");
|
||||
}
|
||||
else {
|
||||
str_exec = params->title; /* params->title is already translated! */
|
||||
}
|
||||
|
||||
but = uiDefButO(block,
|
||||
UI_BTYPE_BUT,
|
||||
"FILE_OT_execute",
|
||||
WM_OP_EXEC_REGION_WIN,
|
||||
str_exec,
|
||||
max_x - loadbutton,
|
||||
line1_y,
|
||||
loadbutton,
|
||||
btn_h,
|
||||
"");
|
||||
/* Just a display hint. */
|
||||
UI_but_flag_enable(but, UI_BUT_ACTIVE_DEFAULT);
|
||||
|
||||
uiDefButO(block,
|
||||
UI_BTYPE_BUT,
|
||||
"FILE_OT_cancel",
|
||||
WM_OP_EXEC_REGION_WIN,
|
||||
IFACE_("Cancel"),
|
||||
max_x - loadbutton,
|
||||
line2_y,
|
||||
loadbutton,
|
||||
btn_h,
|
||||
"");
|
||||
}
|
||||
|
||||
UI_block_end(C, block);
|
||||
UI_block_draw(C, block);
|
||||
}
|
||||
|
||||
static void draw_tile(int sx, int sy, int width, int height, int colorid, int shade)
|
||||
{
|
||||
float color[4];
|
||||
@@ -349,7 +122,7 @@ static void file_draw_string(int sx,
|
||||
rcti rect;
|
||||
char fname[FILE_MAXFILE];
|
||||
|
||||
if (string[0] == '\0') {
|
||||
if (string[0] == '\0' || width < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -362,7 +135,7 @@ static void file_draw_string(int sx,
|
||||
/* no text clipping needed, UI_fontstyle_draw does it but is a bit too strict
|
||||
* (for buttons it works) */
|
||||
rect.xmin = sx;
|
||||
rect.xmax = (int)(sx + ceil(width + 5.0f / UI_DPI_FAC));
|
||||
rect.xmax = sx + round_fl_to_int(width);
|
||||
rect.ymin = sy - height;
|
||||
rect.ymax = sy;
|
||||
|
||||
@@ -404,8 +177,8 @@ static void file_draw_preview(uiBlock *block,
|
||||
float scaledx, scaledy;
|
||||
float scale;
|
||||
int ex, ey;
|
||||
bool use_dropshadow = !is_icon && (typeflags & FILE_TYPE_IMAGE);
|
||||
float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
bool use_dropshadow = !is_icon &&
|
||||
(typeflags & (FILE_TYPE_IMAGE | FILE_TYPE_MOVIE | FILE_TYPE_BLENDER));
|
||||
|
||||
BLI_assert(imb != NULL);
|
||||
|
||||
@@ -442,13 +215,27 @@ static void file_draw_preview(uiBlock *block,
|
||||
|
||||
/* shadow */
|
||||
if (use_dropshadow) {
|
||||
UI_draw_box_shadow(220, (float)xco, (float)yco, (float)(xco + ex), (float)(yco + ey));
|
||||
UI_draw_box_shadow(128, (float)xco, (float)yco, (float)(xco + ex), (float)(yco + ey));
|
||||
}
|
||||
|
||||
GPU_blend(true);
|
||||
|
||||
/* the image */
|
||||
if (!is_icon && typeflags & FILE_TYPE_FTFONT) {
|
||||
/* the large image */
|
||||
|
||||
float col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
if (is_icon) {
|
||||
/* File and Folder icons draw with lowered opacity until we add themes */
|
||||
col[3] = 0.6f;
|
||||
/* Use dark images if background is light */
|
||||
float bg[3];
|
||||
UI_GetThemeColor3fv(TH_BACK, bg);
|
||||
if (rgb_to_grayscale(bg) > 0.5f) {
|
||||
col[0] = 0;
|
||||
col[1] = 0;
|
||||
col[2] = 0;
|
||||
}
|
||||
}
|
||||
else if (typeflags & FILE_TYPE_FTFONT) {
|
||||
UI_GetThemeColor4fv(TH_TEXT, col);
|
||||
}
|
||||
|
||||
@@ -477,30 +264,61 @@ static void file_draw_preview(uiBlock *block,
|
||||
GPU_blend_set_func_separate(
|
||||
GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
if (icon) {
|
||||
UI_icon_draw_ex((float)xco + (7 * UI_DPI_FAC),
|
||||
(float)yco + (7 * UI_DPI_FAC),
|
||||
icon,
|
||||
icon_aspect,
|
||||
1.0f,
|
||||
0.0f,
|
||||
NULL,
|
||||
false);
|
||||
if (icon && (icon != ICON_FILE_FONT)) {
|
||||
/* size of center icon is scaled to fit container and UI scale */
|
||||
float icon_x, icon_y;
|
||||
|
||||
if (is_icon) {
|
||||
const float icon_size = 16.0f / icon_aspect * U.dpi_fac;
|
||||
float icon_opacity = MIN2(icon_aspect, 0.7);
|
||||
uchar icon_color[4] = {255, 255, 255, 255};
|
||||
float bg[3];
|
||||
/* base this off theme color of file or folder later */
|
||||
UI_GetThemeColor3fv(TH_BACK, bg);
|
||||
if (rgb_to_grayscale(bg) > 0.5f) {
|
||||
icon_color[0] = 0;
|
||||
icon_color[1] = 0;
|
||||
icon_color[2] = 0;
|
||||
}
|
||||
icon_x = xco + (ex / 2.0f) - (icon_size / 2.0f);
|
||||
icon_y = yco + (ey / 2.0f) - (icon_size * ((typeflags & FILE_TYPE_DIR) ? 0.78f : 0.65f));
|
||||
UI_icon_draw_ex(
|
||||
icon_x, icon_y, icon, icon_aspect / U.dpi_fac, icon_opacity, 0.0f, icon_color, false);
|
||||
}
|
||||
else {
|
||||
const uchar dark[4] = {0, 0, 0, 255};
|
||||
const uchar light[4] = {255, 255, 255, 255};
|
||||
|
||||
/* Smaller, fainter icon for preview image thumbnail. */
|
||||
icon_x = xco + (2.0f * UI_DPI_FAC);
|
||||
icon_y = yco + (2.0f * UI_DPI_FAC);
|
||||
|
||||
UI_icon_draw_ex(icon_x + 1, icon_y - 1, icon, 1.0f / U.dpi_fac, 0.2f, 0.0f, dark, false);
|
||||
UI_icon_draw_ex(icon_x, icon_y, icon, 1.0f / U.dpi_fac, 0.6f, 0.0f, light, false);
|
||||
}
|
||||
}
|
||||
|
||||
/* border */
|
||||
if (use_dropshadow) {
|
||||
GPUVertFormat *format = immVertexFormat();
|
||||
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
uint pos_attr = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
uint col_attr = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
immUniformColor4f(0.0f, 0.0f, 0.0f, 0.4f);
|
||||
imm_draw_box_wire_2d(pos, (float)xco, (float)yco, (float)(xco + ex), (float)(yco + ey));
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
|
||||
immBegin(GPU_PRIM_LINE_LOOP, 4);
|
||||
immAttr4f(col_attr, 1.0f, 1.0f, 1.0f, 0.15f);
|
||||
immVertex2f(pos_attr, (float)xco + 1, (float)(yco + ey));
|
||||
immAttr4f(col_attr, 1.0f, 1.0f, 1.0f, 0.2f);
|
||||
immVertex2f(pos_attr, (float)(xco + ex), (float)(yco + ey));
|
||||
immAttr4f(col_attr, 0.0f, 0.0f, 0.0f, 0.2f);
|
||||
immVertex2f(pos_attr, (float)(xco + ex), (float)yco + 1);
|
||||
immAttr4f(col_attr, 0.0f, 0.0f, 0.0f, 0.3f);
|
||||
immVertex2f(pos_attr, (float)xco + 1, (float)yco + 1);
|
||||
immEnd();
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
but = uiDefBut(block, UI_BTYPE_LABEL, 0, "", xco, yco, ex, ey, NULL, 0.0, 0.0, 0, 0, NULL);
|
||||
UI_but_func_tooltip_set(but, file_draw_tooltip_func, BLI_strdup(path));
|
||||
|
||||
/* dragregion */
|
||||
if (drag) {
|
||||
@@ -557,6 +375,7 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
|
||||
|
||||
static void draw_background(FileLayout *layout, View2D *v2d)
|
||||
{
|
||||
const int item_height = layout->tile_h + (2 * layout->tile_border_y);
|
||||
int i;
|
||||
int sy;
|
||||
|
||||
@@ -565,9 +384,11 @@ static void draw_background(FileLayout *layout, View2D *v2d)
|
||||
immUniformThemeColorShade(TH_BACK, -7);
|
||||
|
||||
/* alternating flat shade background */
|
||||
for (i = 0; (i <= layout->rows); i += 2) {
|
||||
sy = (int)v2d->cur.ymax - i * (layout->tile_h + 2 * layout->tile_border_y) -
|
||||
layout->tile_border_y;
|
||||
for (i = 2; (i <= layout->rows + 1); i += 2) {
|
||||
sy = (int)v2d->cur.ymax - layout->offset_top - i * item_height - layout->tile_border_y;
|
||||
|
||||
/* Offsett pattern slightly to add scroll effect. */
|
||||
sy += round_fl_to_int(item_height * (v2d->tot.ymax - v2d->cur.ymax) / item_height);
|
||||
|
||||
immRectf(pos,
|
||||
v2d->cur.xmin,
|
||||
@@ -632,6 +453,176 @@ static void draw_dividers(FileLayout *layout, View2D *v2d)
|
||||
}
|
||||
}
|
||||
|
||||
static void draw_columnheader_background(const FileLayout *layout, const View2D *v2d)
|
||||
{
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
immUniformThemeColorShade(TH_BACK, 11);
|
||||
|
||||
immRectf(pos,
|
||||
v2d->cur.xmin,
|
||||
v2d->cur.ymax - layout->attribute_column_header_h,
|
||||
v2d->cur.xmax,
|
||||
v2d->cur.ymax);
|
||||
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
static void draw_columnheader_columns(const FileSelectParams *params,
|
||||
FileLayout *layout,
|
||||
const View2D *v2d,
|
||||
const uchar text_col[4])
|
||||
{
|
||||
const float divider_pad = 0.2 * layout->attribute_column_header_h;
|
||||
int sx = v2d->cur.xmin, sy = v2d->cur.ymax;
|
||||
|
||||
for (FileAttributeColumnType column_type = 0; column_type < ATTRIBUTE_COLUMN_MAX;
|
||||
column_type++) {
|
||||
if (!file_attribute_column_type_enabled(params, column_type)) {
|
||||
continue;
|
||||
}
|
||||
const FileAttributeColumn *column = &layout->attribute_columns[column_type];
|
||||
|
||||
/* Active sort type triangle */
|
||||
if (params->sort == column->sort_type) {
|
||||
float tri_color[4];
|
||||
|
||||
rgba_uchar_to_float(tri_color, text_col);
|
||||
UI_draw_icon_tri(sx + column->width - (0.3f * U.widget_unit) -
|
||||
ATTRIBUTE_COLUMN_PADDING / 2.0f,
|
||||
sy + (0.1f * U.widget_unit) - (layout->attribute_column_header_h / 2),
|
||||
(params->flag & FILE_SORT_INVERT) ? 't' : 'v',
|
||||
tri_color);
|
||||
}
|
||||
|
||||
file_draw_string(sx + ATTRIBUTE_COLUMN_PADDING,
|
||||
sy - layout->tile_border_y,
|
||||
IFACE_(column->name),
|
||||
column->width - 2 * ATTRIBUTE_COLUMN_PADDING,
|
||||
layout->attribute_column_header_h - layout->tile_border_y,
|
||||
UI_STYLE_TEXT_LEFT,
|
||||
text_col);
|
||||
|
||||
/* Separator line */
|
||||
if (column_type != COLUMN_NAME) {
|
||||
uint pos = GPU_vertformat_attr_add(
|
||||
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
immUniformThemeColorShade(TH_BACK, -10);
|
||||
immBegin(GPU_PRIM_LINES, 2);
|
||||
immVertex2f(pos, sx - 1, sy - divider_pad);
|
||||
immVertex2f(pos, sx - 1, sy - layout->attribute_column_header_h + divider_pad);
|
||||
immEnd();
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
sx += column->width;
|
||||
}
|
||||
|
||||
/* Vertical separator lines line */
|
||||
{
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
immUniformThemeColorShade(TH_BACK, -10);
|
||||
immBegin(GPU_PRIM_LINES, 4);
|
||||
immVertex2f(pos, v2d->cur.xmin, sy);
|
||||
immVertex2f(pos, v2d->cur.xmax, sy);
|
||||
immVertex2f(pos, v2d->cur.xmin, sy - layout->attribute_column_header_h);
|
||||
immVertex2f(pos, v2d->cur.xmax, sy - layout->attribute_column_header_h);
|
||||
immEnd();
|
||||
immUnbindProgram();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the stat string stored in file->entry if necessary.
|
||||
*/
|
||||
static const char *filelist_get_details_column_string(FileAttributeColumnType column,
|
||||
const FileDirEntry *file,
|
||||
const bool small_size,
|
||||
const bool update_stat_strings)
|
||||
{
|
||||
switch (column) {
|
||||
case COLUMN_DATETIME:
|
||||
if (!(file->typeflag & FILE_TYPE_BLENDERLIB) && !FILENAME_IS_CURRPAR(file->relpath)) {
|
||||
if ((file->entry->datetime_str[0] == '\0') || update_stat_strings) {
|
||||
char date[FILELIST_DIRENTRY_DATE_LEN], time[FILELIST_DIRENTRY_TIME_LEN];
|
||||
bool is_today, is_yesterday;
|
||||
|
||||
BLI_filelist_entry_datetime_to_string(
|
||||
NULL, file->entry->time, small_size, time, date, &is_today, &is_yesterday);
|
||||
|
||||
if (is_today || is_yesterday) {
|
||||
BLI_strncpy(date, is_today ? N_("Today") : N_("Yesterday"), sizeof(date));
|
||||
}
|
||||
BLI_snprintf(
|
||||
file->entry->datetime_str, sizeof(file->entry->datetime_str), "%s %s", date, time);
|
||||
}
|
||||
|
||||
return file->entry->datetime_str;
|
||||
}
|
||||
break;
|
||||
case COLUMN_SIZE:
|
||||
if ((file->typeflag & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) ||
|
||||
!(file->typeflag & (FILE_TYPE_DIR | FILE_TYPE_BLENDERLIB))) {
|
||||
if ((file->entry->size_str[0] == '\0') || update_stat_strings) {
|
||||
BLI_filelist_entry_size_to_string(
|
||||
NULL, file->entry->size, small_size, file->entry->size_str);
|
||||
}
|
||||
|
||||
return file->entry->size_str;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void draw_details_columns(const FileSelectParams *params,
|
||||
const FileLayout *layout,
|
||||
const FileDirEntry *file,
|
||||
const int pos_x,
|
||||
const int pos_y,
|
||||
const uchar text_col[4])
|
||||
{
|
||||
const bool small_size = SMALL_SIZE_CHECK(params->thumbnail_size);
|
||||
const bool update_stat_strings = small_size != SMALL_SIZE_CHECK(layout->curr_size);
|
||||
int sx = pos_x - layout->tile_border_x - (UI_UNIT_X * 0.1f), sy = pos_y;
|
||||
|
||||
for (FileAttributeColumnType column_type = 0; column_type < ATTRIBUTE_COLUMN_MAX;
|
||||
column_type++) {
|
||||
const FileAttributeColumn *column = &layout->attribute_columns[column_type];
|
||||
|
||||
/* Name column is not a detail column (should already be drawn), always skip here. */
|
||||
if (column_type == COLUMN_NAME) {
|
||||
sx += column->width;
|
||||
continue;
|
||||
}
|
||||
if (!file_attribute_column_type_enabled(params, column_type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const char *str = filelist_get_details_column_string(
|
||||
column_type, file, small_size, update_stat_strings);
|
||||
|
||||
if (str) {
|
||||
file_draw_string(sx + ATTRIBUTE_COLUMN_PADDING,
|
||||
sy - layout->tile_border_y,
|
||||
IFACE_(str),
|
||||
column->width - 2 * ATTRIBUTE_COLUMN_PADDING,
|
||||
layout->tile_h,
|
||||
column->text_align,
|
||||
text_col);
|
||||
}
|
||||
|
||||
sx += column->width;
|
||||
}
|
||||
}
|
||||
|
||||
void file_draw_list(const bContext *C, ARegion *ar)
|
||||
{
|
||||
SpaceFile *sfile = CTX_wm_space_file(C);
|
||||
@@ -652,18 +643,14 @@ void file_draw_list(const bContext *C, ARegion *ar)
|
||||
bool is_icon;
|
||||
eFontStyle_Align align;
|
||||
bool do_drag;
|
||||
int column_space = 0.6f * UI_UNIT_X;
|
||||
unsigned char text_col[4];
|
||||
const bool small_size = SMALL_SIZE_CHECK(params->thumbnail_size);
|
||||
const bool update_stat_strings = small_size != SMALL_SIZE_CHECK(layout->curr_size);
|
||||
const float thumb_icon_aspect = sqrtf(64.0f / (float)(params->thumbnail_size));
|
||||
const bool draw_columnheader = (params->display == FILE_VERTICALDISPLAY);
|
||||
const float thumb_icon_aspect = MIN2(64.0f / (float)(params->thumbnail_size), 1.0f);
|
||||
|
||||
numfiles = filelist_files_ensure(files);
|
||||
|
||||
if (params->display != FILE_IMGDISPLAY) {
|
||||
|
||||
draw_background(layout, v2d);
|
||||
|
||||
draw_dividers(layout, v2d);
|
||||
}
|
||||
|
||||
@@ -679,13 +666,14 @@ void file_draw_list(const bContext *C, ARegion *ar)
|
||||
numfiles_layout += layout->rows;
|
||||
}
|
||||
else {
|
||||
numfiles_layout += layout->columns;
|
||||
numfiles_layout += layout->flow_columns;
|
||||
}
|
||||
|
||||
filelist_file_cache_slidingwindow_set(files, numfiles_layout);
|
||||
|
||||
textwidth = (FILE_IMGDISPLAY == params->display) ? layout->tile_w :
|
||||
(int)layout->column_widths[COLUMN_NAME];
|
||||
textwidth = (FILE_IMGDISPLAY == params->display) ?
|
||||
layout->tile_w :
|
||||
round_fl_to_int(layout->attribute_columns[COLUMN_NAME].width);
|
||||
textheight = (int)(layout->textheight * 3.0 / 2.0 + 0.5);
|
||||
|
||||
align = (FILE_IMGDISPLAY == params->display) ? UI_STYLE_TEXT_CENTER : UI_STYLE_TEXT_LEFT;
|
||||
@@ -719,11 +707,16 @@ void file_draw_list(const bContext *C, ARegion *ar)
|
||||
|
||||
BLF_batch_draw_begin();
|
||||
|
||||
UI_GetThemeColor4ubv(TH_TEXT, text_col);
|
||||
|
||||
for (i = offset; (i < numfiles) && (i < offset + numfiles_layout); i++) {
|
||||
unsigned int file_selflag;
|
||||
char path[FILE_MAX_LIBEXTRA];
|
||||
int padx = 0.1f * UI_UNIT_X;
|
||||
int icon_ofs = 0;
|
||||
|
||||
ED_fileselect_layout_tilepos(layout, i, &sx, &sy);
|
||||
sx += (int)(v2d->tot.xmin + 0.1f * UI_UNIT_X);
|
||||
sx += (int)(v2d->tot.xmin + padx);
|
||||
sy = (int)(v2d->tot.ymax - sy);
|
||||
|
||||
file = filelist_file(files, i);
|
||||
@@ -737,15 +730,14 @@ void file_draw_list(const bContext *C, ARegion *ar)
|
||||
int colorid = (file_selflag & FILE_SEL_SELECTED) ? TH_HILITE : TH_BACK;
|
||||
int shade = (params->highlight_file == i) || (file_selflag & FILE_SEL_HIGHLIGHTED) ? 35 :
|
||||
0;
|
||||
const short width = ELEM(params->display, FILE_VERTICALDISPLAY, FILE_HORIZONTALDISPLAY) ?
|
||||
layout->tile_w - (2 * padx) :
|
||||
layout->tile_w;
|
||||
|
||||
BLI_assert(i == 0 || !FILENAME_IS_CURRPAR(file->relpath));
|
||||
|
||||
draw_tile(sx,
|
||||
sy - 1,
|
||||
layout->tile_w + 4,
|
||||
sfile->layout->tile_h + layout->tile_border_y,
|
||||
colorid,
|
||||
shade);
|
||||
draw_tile(
|
||||
sx, sy - 1, width, sfile->layout->tile_h + layout->tile_border_y, colorid, shade);
|
||||
}
|
||||
}
|
||||
UI_draw_roundbox_corner_set(UI_CNR_NONE);
|
||||
@@ -778,38 +770,28 @@ void file_draw_list(const bContext *C, ARegion *ar)
|
||||
file_draw_icon(block,
|
||||
path,
|
||||
sx,
|
||||
sy - (UI_UNIT_Y / 6),
|
||||
sy - layout->tile_border_y,
|
||||
filelist_geticon(files, i, true),
|
||||
ICON_DEFAULT_WIDTH_SCALE,
|
||||
ICON_DEFAULT_HEIGHT_SCALE,
|
||||
do_drag);
|
||||
sx += ICON_DEFAULT_WIDTH_SCALE + 0.2f * UI_UNIT_X;
|
||||
icon_ofs += ICON_DEFAULT_WIDTH_SCALE + 0.2f * UI_UNIT_X;
|
||||
}
|
||||
|
||||
UI_GetThemeColor4ubv(TH_TEXT, text_col);
|
||||
|
||||
if (file_selflag & FILE_SEL_EDITING) {
|
||||
uiBut *but;
|
||||
short width;
|
||||
|
||||
if (params->display == FILE_SHORTDISPLAY) {
|
||||
width = layout->tile_w - (ICON_DEFAULT_WIDTH_SCALE + 0.2f * UI_UNIT_X);
|
||||
}
|
||||
else if (params->display == FILE_LONGDISPLAY) {
|
||||
width = layout->column_widths[COLUMN_NAME] + (column_space * 3.5f);
|
||||
}
|
||||
else {
|
||||
BLI_assert(params->display == FILE_IMGDISPLAY);
|
||||
width = textwidth;
|
||||
}
|
||||
const short width = (params->display == FILE_IMGDISPLAY) ?
|
||||
textwidth :
|
||||
layout->attribute_columns[COLUMN_NAME].width -
|
||||
ATTRIBUTE_COLUMN_PADDING;
|
||||
|
||||
but = uiDefBut(block,
|
||||
UI_BTYPE_TEXT,
|
||||
1,
|
||||
"",
|
||||
sx,
|
||||
sx + icon_ofs,
|
||||
sy - layout->tile_h - 0.15f * UI_UNIT_X,
|
||||
width,
|
||||
width - icon_ofs,
|
||||
textheight,
|
||||
sfile->params->renamefile,
|
||||
1.0f,
|
||||
@@ -825,74 +807,19 @@ void file_draw_list(const bContext *C, ARegion *ar)
|
||||
sfile->files, file, FILE_SEL_REMOVE, FILE_SEL_EDITING, CHECK_ALL);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(file_selflag & FILE_SEL_EDITING)) {
|
||||
int tpos = (FILE_IMGDISPLAY == params->display) ? sy - layout->tile_h + layout->textheight :
|
||||
sy;
|
||||
file_draw_string(sx + 1, tpos, file->name, (float)textwidth, textheight, align, text_col);
|
||||
else {
|
||||
const int txpos = (params->display == FILE_IMGDISPLAY) ? sx : sx + 1 + icon_ofs;
|
||||
const int typos = (params->display == FILE_IMGDISPLAY) ?
|
||||
sy - layout->tile_h + layout->textheight :
|
||||
sy - layout->tile_border_y;
|
||||
const int twidth = (params->display == FILE_IMGDISPLAY) ?
|
||||
textwidth :
|
||||
textwidth - 1 - icon_ofs - padx - layout->tile_border_x;
|
||||
file_draw_string(txpos, typos, file->name, (float)twidth, textheight, align, text_col);
|
||||
}
|
||||
|
||||
sx += (int)layout->column_widths[COLUMN_NAME] + column_space;
|
||||
if (params->display == FILE_SHORTDISPLAY) {
|
||||
if ((file->typeflag & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) ||
|
||||
!(file->typeflag & (FILE_TYPE_DIR | FILE_TYPE_BLENDERLIB))) {
|
||||
if ((file->entry->size_str[0] == '\0') || update_stat_strings) {
|
||||
BLI_filelist_entry_size_to_string(
|
||||
NULL, file->entry->size, small_size, file->entry->size_str);
|
||||
}
|
||||
file_draw_string(sx,
|
||||
sy,
|
||||
file->entry->size_str,
|
||||
layout->column_widths[COLUMN_SIZE],
|
||||
layout->tile_h,
|
||||
align,
|
||||
text_col);
|
||||
}
|
||||
sx += (int)layout->column_widths[COLUMN_SIZE] + column_space;
|
||||
}
|
||||
else if (params->display == FILE_LONGDISPLAY) {
|
||||
if (!(file->typeflag & FILE_TYPE_BLENDERLIB) && !FILENAME_IS_CURRPAR(file->relpath)) {
|
||||
if ((file->entry->date_str[0] == '\0') || update_stat_strings) {
|
||||
BLI_filelist_entry_datetime_to_string(
|
||||
NULL, file->entry->time, small_size, file->entry->time_str, file->entry->date_str);
|
||||
}
|
||||
file_draw_string(sx,
|
||||
sy,
|
||||
file->entry->date_str,
|
||||
layout->column_widths[COLUMN_DATE],
|
||||
layout->tile_h,
|
||||
align,
|
||||
text_col);
|
||||
sx += (int)layout->column_widths[COLUMN_DATE] + column_space;
|
||||
file_draw_string(sx,
|
||||
sy,
|
||||
file->entry->time_str,
|
||||
layout->column_widths[COLUMN_TIME],
|
||||
layout->tile_h,
|
||||
align,
|
||||
text_col);
|
||||
sx += (int)layout->column_widths[COLUMN_TIME] + column_space;
|
||||
}
|
||||
else {
|
||||
sx += (int)layout->column_widths[COLUMN_DATE] + column_space;
|
||||
sx += (int)layout->column_widths[COLUMN_TIME] + column_space;
|
||||
}
|
||||
|
||||
if ((file->typeflag & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) ||
|
||||
!(file->typeflag & (FILE_TYPE_DIR | FILE_TYPE_BLENDERLIB))) {
|
||||
if ((file->entry->size_str[0] == '\0') || update_stat_strings) {
|
||||
BLI_filelist_entry_size_to_string(
|
||||
NULL, file->entry->size, small_size, file->entry->size_str);
|
||||
}
|
||||
file_draw_string(sx,
|
||||
sy,
|
||||
file->entry->size_str,
|
||||
layout->column_widths[COLUMN_SIZE],
|
||||
layout->tile_h,
|
||||
align,
|
||||
text_col);
|
||||
}
|
||||
sx += (int)layout->column_widths[COLUMN_SIZE] + column_space;
|
||||
if (params->display != FILE_IMGDISPLAY) {
|
||||
draw_details_columns(params, layout, file, sx, sy, text_col);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -901,5 +828,11 @@ void file_draw_list(const bContext *C, ARegion *ar)
|
||||
UI_block_end(C, block);
|
||||
UI_block_draw(C, block);
|
||||
|
||||
/* Draw last, on top of file list. */
|
||||
if (draw_columnheader) {
|
||||
draw_columnheader_background(layout, v2d);
|
||||
draw_columnheader_columns(params, layout, v2d, text_col);
|
||||
}
|
||||
|
||||
layout->curr_size = params->thumbnail_size;
|
||||
}
|
||||
|
@@ -30,9 +30,11 @@ struct ARegion;
|
||||
struct ARegionType;
|
||||
struct FileSelectParams;
|
||||
struct SpaceFile;
|
||||
struct View2D;
|
||||
|
||||
/* file_ops.c */
|
||||
struct ARegion *file_tools_region(struct ScrArea *sa);
|
||||
struct ARegion *file_tool_props_region(struct ScrArea *sa);
|
||||
|
||||
/* file_draw.c */
|
||||
#define TILE_BORDER_X (UI_UNIT_X / 4)
|
||||
@@ -42,9 +44,10 @@ struct ARegion *file_tools_region(struct ScrArea *sa);
|
||||
#define IMASEL_BUTTONS_HEIGHT (UI_UNIT_Y * 2)
|
||||
#define IMASEL_BUTTONS_MARGIN (UI_UNIT_Y / 6)
|
||||
|
||||
#define ATTRIBUTE_COLUMN_PADDING (0.5f * UI_UNIT_X)
|
||||
|
||||
#define SMALL_SIZE_CHECK(_size) ((_size) < 64) /* Related to FileSelectParams.thumbnail_size. */
|
||||
|
||||
void file_draw_buttons(const bContext *C, ARegion *ar);
|
||||
void file_calc_previews(const bContext *C, ARegion *ar);
|
||||
void file_draw_list(const bContext *C, ARegion *ar);
|
||||
|
||||
@@ -64,6 +67,7 @@ typedef enum WalkSelectDirection {
|
||||
} WalkSelectDirections;
|
||||
|
||||
void FILE_OT_highlight(struct wmOperatorType *ot);
|
||||
void FILE_OT_sort_column_ui_context(struct wmOperatorType *ot);
|
||||
void FILE_OT_select(struct wmOperatorType *ot);
|
||||
void FILE_OT_select_walk(struct wmOperatorType *ot);
|
||||
void FILE_OT_select_all(struct wmOperatorType *ot);
|
||||
@@ -112,6 +116,16 @@ void file_operator_to_sfile(bContext *C, struct SpaceFile *sfile, struct wmOpera
|
||||
|
||||
/* filesel.c */
|
||||
void fileselect_file_set(SpaceFile *sfile, const int index);
|
||||
bool file_attribute_column_type_enabled(const FileSelectParams *params,
|
||||
FileAttributeColumnType column);
|
||||
bool file_attribute_column_header_is_inside(const struct View2D *v2d,
|
||||
const FileLayout *layout,
|
||||
int x,
|
||||
int y);
|
||||
FileAttributeColumnType file_attribute_column_type_find_isect(const View2D *v2d,
|
||||
const FileSelectParams *params,
|
||||
FileLayout *layout,
|
||||
int x);
|
||||
float file_string_width(const char *str);
|
||||
|
||||
float file_font_pointsize(void);
|
||||
|
@@ -78,7 +78,12 @@ static FileSelection find_file_mouse_rect(SpaceFile *sfile, ARegion *ar, const r
|
||||
|
||||
BLI_rctf_rcti_copy(&rect_region_fl, rect_region);
|
||||
|
||||
/* Okay, manipulating v2d rects here is hacky... */
|
||||
v2d->mask.ymax -= sfile->layout->offset_top;
|
||||
v2d->cur.ymax -= sfile->layout->offset_top;
|
||||
UI_view2d_region_to_view_rctf(v2d, &rect_region_fl, &rect_view_fl);
|
||||
v2d->mask.ymax += sfile->layout->offset_top;
|
||||
v2d->cur.ymax += sfile->layout->offset_top;
|
||||
|
||||
BLI_rcti_init(&rect_view,
|
||||
(int)(v2d->tot.xmin + rect_view_fl.xmin),
|
||||
@@ -190,7 +195,6 @@ static FileSelect file_select_do(bContext *C, int selected_idx, bool do_diropen)
|
||||
const bool is_parent_dir = FILENAME_IS_PARENT(file->relpath);
|
||||
|
||||
if (do_diropen == false) {
|
||||
params->file[0] = '\0';
|
||||
retval = FILE_SELECT_DIR;
|
||||
}
|
||||
/* the path is too long and we are not going up! */
|
||||
@@ -262,8 +266,8 @@ static void file_ensure_inside_viewbounds(ARegion *ar, SpaceFile *sfile, const i
|
||||
cur->ymax = cur->ymin + ar->winy;
|
||||
}
|
||||
/* up */
|
||||
else if (cur->ymax < rect.ymax) {
|
||||
cur->ymax = rect.ymax + layout->tile_border_y;
|
||||
else if ((cur->ymax - layout->offset_top) < rect.ymax) {
|
||||
cur->ymax = rect.ymax + layout->tile_border_y + layout->offset_top;
|
||||
cur->ymin = cur->ymax - ar->winy;
|
||||
}
|
||||
/* left - also use if tile is wider than viewbounds so view is aligned to file name */
|
||||
@@ -278,7 +282,7 @@ static void file_ensure_inside_viewbounds(ARegion *ar, SpaceFile *sfile, const i
|
||||
}
|
||||
else {
|
||||
BLI_assert(cur->xmin <= rect.xmin && cur->xmax >= rect.xmax && cur->ymin <= rect.ymin &&
|
||||
cur->ymax >= rect.ymax);
|
||||
(cur->ymax - layout->offset_top) >= rect.ymax);
|
||||
changed = false;
|
||||
}
|
||||
|
||||
@@ -384,7 +388,7 @@ static int file_box_select_modal(bContext *C, wmOperator *op, const wmEvent *eve
|
||||
if (result == OPERATOR_RUNNING_MODAL) {
|
||||
WM_operator_properties_border_to_rcti(op, &rect);
|
||||
|
||||
BLI_rcti_isect(&(ar->v2d.mask), &rect, &rect);
|
||||
ED_fileselect_layout_isect_rect(sfile->layout, &ar->v2d, &rect, &rect);
|
||||
|
||||
sel = file_selection_get(C, &rect, 0);
|
||||
if ((sel.first != params->sel_first) || (sel.last != params->sel_last)) {
|
||||
@@ -440,7 +444,7 @@ static int file_box_select_exec(bContext *C, wmOperator *op)
|
||||
file_deselect_all(sfile, FILE_SEL_SELECTED);
|
||||
}
|
||||
|
||||
BLI_rcti_isect(&(ar->v2d.mask), &rect, &rect);
|
||||
ED_fileselect_layout_isect_rect(sfile->layout, &ar->v2d, &rect, &rect);
|
||||
|
||||
ret = file_select(C, &rect, select ? FILE_SEL_ADD : FILE_SEL_REMOVE, false, false);
|
||||
|
||||
@@ -493,7 +497,7 @@ static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
rect.xmin = rect.xmax = event->mval[0];
|
||||
rect.ymin = rect.ymax = event->mval[1];
|
||||
|
||||
if (!BLI_rcti_isect_pt(&ar->v2d.mask, rect.xmin, rect.ymin)) {
|
||||
if (!ED_fileselect_layout_is_inside_pt(sfile->layout, &ar->v2d, rect.xmin, rect.ymin)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
@@ -691,7 +695,7 @@ static bool file_walk_select_do(bContext *C,
|
||||
if (has_selection) {
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
FileLayout *layout = ED_fileselect_get_layout(sfile, ar);
|
||||
const int idx_shift = (layout->flag & FILE_LAYOUT_HOR) ? layout->rows : layout->columns;
|
||||
const int idx_shift = (layout->flag & FILE_LAYOUT_HOR) ? layout->rows : layout->flow_columns;
|
||||
|
||||
if ((layout->flag & FILE_LAYOUT_HOR && direction == FILE_SELECT_WALK_UP) ||
|
||||
(layout->flag & FILE_LAYOUT_VER && direction == FILE_SELECT_WALK_LEFT)) {
|
||||
@@ -1185,7 +1189,7 @@ int file_highlight_set(SpaceFile *sfile, ARegion *ar, int mx, int my)
|
||||
mx -= ar->winrct.xmin;
|
||||
my -= ar->winrct.ymin;
|
||||
|
||||
if (BLI_rcti_isect_pt(&ar->v2d.mask, mx, my)) {
|
||||
if (ED_fileselect_layout_is_inside_pt(sfile->layout, v2d, mx, my)) {
|
||||
float fx, fy;
|
||||
int highlight_file;
|
||||
|
||||
@@ -1234,6 +1238,53 @@ void FILE_OT_highlight(struct wmOperatorType *ot)
|
||||
ot->poll = ED_operator_file_active;
|
||||
}
|
||||
|
||||
static int file_column_sort_ui_context_invoke(bContext *C,
|
||||
wmOperator *UNUSED(op),
|
||||
const wmEvent *event)
|
||||
{
|
||||
const ARegion *ar = CTX_wm_region(C);
|
||||
SpaceFile *sfile = CTX_wm_space_file(C);
|
||||
|
||||
if (file_attribute_column_header_is_inside(
|
||||
&ar->v2d, sfile->layout, event->mval[0], event->mval[1])) {
|
||||
const FileAttributeColumnType column_type = file_attribute_column_type_find_isect(
|
||||
&ar->v2d, sfile->params, sfile->layout, event->mval[0]);
|
||||
|
||||
if (column_type != COLUMN_NONE) {
|
||||
const FileAttributeColumn *column = &sfile->layout->attribute_columns[column_type];
|
||||
|
||||
if (column->sort_type != FILE_SORT_NONE) {
|
||||
if (sfile->params->sort == column->sort_type) {
|
||||
/* Already sorting by selected column -> toggle sort invert (three state logic). */
|
||||
sfile->params->flag ^= FILE_SORT_INVERT;
|
||||
}
|
||||
else {
|
||||
sfile->params->sort = column->sort_type;
|
||||
sfile->params->flag &= ~FILE_SORT_INVERT;
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
void FILE_OT_sort_column_ui_context(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Sort from Column";
|
||||
ot->description = "Change sorting to use column under cursor";
|
||||
ot->idname = "FILE_OT_sort_column_ui_context";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = file_column_sort_ui_context_invoke;
|
||||
ot->poll = ED_operator_file_active;
|
||||
|
||||
ot->flag = OPTYPE_INTERNAL;
|
||||
}
|
||||
|
||||
int file_cancel_exec(bContext *C, wmOperator *UNUSED(unused))
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
@@ -1713,7 +1764,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
|
||||
/* Number of items in a block (i.e. lines in a column in horizontal layout, or columns in a line
|
||||
* in vertical layout).
|
||||
*/
|
||||
const int items_block_size = is_horizontal ? sfile->layout->rows : sfile->layout->columns;
|
||||
const int items_block_size = is_horizontal ? sfile->layout->rows : sfile->layout->flow_columns;
|
||||
|
||||
/* Scroll offset is the first file in the row/column we are editing in. */
|
||||
if (sfile->scroll_offset == 0) {
|
||||
@@ -1998,7 +2049,6 @@ void FILE_OT_directory_new(struct wmOperatorType *ot)
|
||||
ot->idname = "FILE_OT_directory_new";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = WM_operator_confirm;
|
||||
ot->exec = file_directory_new_exec;
|
||||
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
|
||||
|
||||
@@ -2260,10 +2310,29 @@ ARegion *file_tools_region(ScrArea *sa)
|
||||
arnew->regiontype = RGN_TYPE_TOOLS;
|
||||
arnew->alignment = RGN_ALIGN_LEFT;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ARegion *file_tool_props_region(ScrArea *sa)
|
||||
{
|
||||
ARegion *ar, *arnew;
|
||||
|
||||
if ((ar = BKE_area_find_region_type(sa, RGN_TYPE_TOOL_PROPS)) != NULL) {
|
||||
return ar;
|
||||
}
|
||||
|
||||
/* add subdiv level; after execute region */
|
||||
ar = BKE_area_find_region_type(sa, RGN_TYPE_EXECUTE);
|
||||
|
||||
/* is error! */
|
||||
if (ar == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
arnew = MEM_callocN(sizeof(ARegion), "tool props for file");
|
||||
BLI_insertlinkafter(&sa->regionbase, ar, arnew);
|
||||
arnew->regiontype = RGN_TYPE_TOOL_PROPS;
|
||||
arnew->alignment = RGN_ALIGN_RIGHT;
|
||||
|
||||
return arnew;
|
||||
}
|
||||
@@ -2292,6 +2361,17 @@ void FILE_OT_bookmark_toggle(struct wmOperatorType *ot)
|
||||
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
|
||||
}
|
||||
|
||||
static bool file_filenum_poll(bContext *C)
|
||||
{
|
||||
SpaceFile *sfile = CTX_wm_space_file(C);
|
||||
|
||||
if (!ED_operator_file_active(C)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return sfile->params && (sfile->params->action_type == FILE_SAVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for a string of digits within name (using BLI_stringdec) and adjusts it by add.
|
||||
*/
|
||||
@@ -2349,7 +2429,7 @@ void FILE_OT_filenum(struct wmOperatorType *ot)
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = file_filenum_exec;
|
||||
ot->poll = ED_operator_file_active; /* <- important, handler is on window level */
|
||||
ot->poll = file_filenum_poll;
|
||||
|
||||
/* props */
|
||||
RNA_def_int(ot->srna, "increment", 1, -100, 100, "Increment", "", -100, 100);
|
||||
|
@@ -103,6 +103,7 @@ void file_panels_register(ARegionType *art)
|
||||
strcpy(pt->idname, "FILE_PT_operator");
|
||||
strcpy(pt->label, N_("Operator"));
|
||||
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
|
||||
pt->flag = PNL_NO_HEADER;
|
||||
pt->poll = file_panel_operator_poll;
|
||||
pt->draw_header = file_panel_operator_header;
|
||||
pt->draw = file_panel_operator;
|
||||
|
@@ -329,25 +329,20 @@ enum {
|
||||
FL_IS_PENDING = 1 << 2,
|
||||
FL_NEED_SORTING = 1 << 3,
|
||||
FL_NEED_FILTERING = 1 << 4,
|
||||
FL_SORT_INVERT = 1 << 5,
|
||||
};
|
||||
|
||||
#define SPECIAL_IMG_SIZE 48
|
||||
#define SPECIAL_IMG_ROWS 4
|
||||
#define SPECIAL_IMG_COLS 4
|
||||
#define SPECIAL_IMG_SIZE 256
|
||||
#define SPECIAL_IMG_ROWS 1
|
||||
#define SPECIAL_IMG_COLS 6
|
||||
|
||||
enum {
|
||||
SPECIAL_IMG_FOLDER = 0,
|
||||
SPECIAL_IMG_PARENT = 1,
|
||||
SPECIAL_IMG_REFRESH = 2,
|
||||
SPECIAL_IMG_BLENDFILE = 3,
|
||||
SPECIAL_IMG_SOUNDFILE = 4,
|
||||
SPECIAL_IMG_MOVIEFILE = 5,
|
||||
SPECIAL_IMG_PYTHONFILE = 6,
|
||||
SPECIAL_IMG_TEXTFILE = 7,
|
||||
SPECIAL_IMG_FONTFILE = 8,
|
||||
SPECIAL_IMG_UNKNOWNFILE = 9,
|
||||
SPECIAL_IMG_LOADING = 10,
|
||||
SPECIAL_IMG_BACKUP = 11,
|
||||
SPECIAL_IMG_DOCUMENT = 0,
|
||||
SPECIAL_IMG_FOLDER = 1,
|
||||
SPECIAL_IMG_PARENT = 2,
|
||||
SPECIAL_IMG_DRIVE_FIXED = 3,
|
||||
SPECIAL_IMG_DRIVE_ATTACHED = 4,
|
||||
SPECIAL_IMG_DRIVE_REMOTE = 5,
|
||||
SPECIAL_IMG_MAX,
|
||||
};
|
||||
|
||||
@@ -369,6 +364,19 @@ static void filelist_cache_clear(FileListEntryCache *cache, size_t new_size);
|
||||
|
||||
/* ********** Sort helpers ********** */
|
||||
|
||||
struct FileSortData {
|
||||
bool inverted;
|
||||
};
|
||||
|
||||
static int compare_apply_inverted(int val, const struct FileSortData *sort_data)
|
||||
{
|
||||
return sort_data->inverted ? -val : val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles inverted sorting itself (currently there's nothing to invert), so if this returns non-0,
|
||||
* it should be used as-is and not inverted.
|
||||
*/
|
||||
static int compare_direntry_generic(const FileListInternEntry *entry1,
|
||||
const FileListInternEntry *entry2)
|
||||
{
|
||||
@@ -420,10 +428,11 @@ static int compare_direntry_generic(const FileListInternEntry *entry1,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int compare_name(void *UNUSED(user_data), const void *a1, const void *a2)
|
||||
static int compare_name(void *user_data, const void *a1, const void *a2)
|
||||
{
|
||||
const FileListInternEntry *entry1 = a1;
|
||||
const FileListInternEntry *entry2 = a2;
|
||||
const struct FileSortData *sort_data = user_data;
|
||||
char *name1, *name2;
|
||||
int ret;
|
||||
|
||||
@@ -434,13 +443,14 @@ static int compare_name(void *UNUSED(user_data), const void *a1, const void *a2)
|
||||
name1 = entry1->name;
|
||||
name2 = entry2->name;
|
||||
|
||||
return BLI_strcasecmp_natural(name1, name2);
|
||||
return compare_apply_inverted(BLI_strcasecmp_natural(name1, name2), sort_data);
|
||||
}
|
||||
|
||||
static int compare_date(void *UNUSED(user_data), const void *a1, const void *a2)
|
||||
static int compare_date(void *user_data, const void *a1, const void *a2)
|
||||
{
|
||||
const FileListInternEntry *entry1 = a1;
|
||||
const FileListInternEntry *entry2 = a2;
|
||||
const struct FileSortData *sort_data = user_data;
|
||||
char *name1, *name2;
|
||||
int64_t time1, time2;
|
||||
int ret;
|
||||
@@ -452,22 +462,23 @@ static int compare_date(void *UNUSED(user_data), const void *a1, const void *a2)
|
||||
time1 = (int64_t)entry1->st.st_mtime;
|
||||
time2 = (int64_t)entry2->st.st_mtime;
|
||||
if (time1 < time2) {
|
||||
return 1;
|
||||
return compare_apply_inverted(1, sort_data);
|
||||
}
|
||||
if (time1 > time2) {
|
||||
return -1;
|
||||
return compare_apply_inverted(-1, sort_data);
|
||||
}
|
||||
|
||||
name1 = entry1->name;
|
||||
name2 = entry2->name;
|
||||
|
||||
return BLI_strcasecmp_natural(name1, name2);
|
||||
return compare_apply_inverted(BLI_strcasecmp_natural(name1, name2), sort_data);
|
||||
}
|
||||
|
||||
static int compare_size(void *UNUSED(user_data), const void *a1, const void *a2)
|
||||
static int compare_size(void *user_data, const void *a1, const void *a2)
|
||||
{
|
||||
const FileListInternEntry *entry1 = a1;
|
||||
const FileListInternEntry *entry2 = a2;
|
||||
const struct FileSortData *sort_data = user_data;
|
||||
char *name1, *name2;
|
||||
uint64_t size1, size2;
|
||||
int ret;
|
||||
@@ -479,22 +490,23 @@ static int compare_size(void *UNUSED(user_data), const void *a1, const void *a2)
|
||||
size1 = entry1->st.st_size;
|
||||
size2 = entry2->st.st_size;
|
||||
if (size1 < size2) {
|
||||
return 1;
|
||||
return compare_apply_inverted(1, sort_data);
|
||||
}
|
||||
if (size1 > size2) {
|
||||
return -1;
|
||||
return compare_apply_inverted(-1, sort_data);
|
||||
}
|
||||
|
||||
name1 = entry1->name;
|
||||
name2 = entry2->name;
|
||||
|
||||
return BLI_strcasecmp_natural(name1, name2);
|
||||
return compare_apply_inverted(BLI_strcasecmp_natural(name1, name2), sort_data);
|
||||
}
|
||||
|
||||
static int compare_extension(void *UNUSED(user_data), const void *a1, const void *a2)
|
||||
static int compare_extension(void *user_data, const void *a1, const void *a2)
|
||||
{
|
||||
const FileListInternEntry *entry1 = a1;
|
||||
const FileListInternEntry *entry2 = a2;
|
||||
const struct FileSortData *sort_data = user_data;
|
||||
char *name1, *name2;
|
||||
int ret;
|
||||
|
||||
@@ -516,10 +528,10 @@ static int compare_extension(void *UNUSED(user_data), const void *a1, const void
|
||||
return -1;
|
||||
}
|
||||
if (entry1->blentype < entry2->blentype) {
|
||||
return -1;
|
||||
return compare_apply_inverted(-1, sort_data);
|
||||
}
|
||||
if (entry1->blentype > entry2->blentype) {
|
||||
return 1;
|
||||
return compare_apply_inverted(1, sort_data);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -539,48 +551,58 @@ static int compare_extension(void *UNUSED(user_data), const void *a1, const void
|
||||
}
|
||||
|
||||
if ((ret = BLI_strcasecmp(sufix1, sufix2))) {
|
||||
return ret;
|
||||
return compare_apply_inverted(ret, sort_data);
|
||||
}
|
||||
}
|
||||
|
||||
name1 = entry1->name;
|
||||
name2 = entry2->name;
|
||||
|
||||
return BLI_strcasecmp_natural(name1, name2);
|
||||
return compare_apply_inverted(BLI_strcasecmp_natural(name1, name2), sort_data);
|
||||
}
|
||||
|
||||
void filelist_sort(struct FileList *filelist)
|
||||
{
|
||||
if ((filelist->flags & FL_NEED_SORTING) && (filelist->sort != FILE_SORT_NONE)) {
|
||||
void *sort_cb = NULL;
|
||||
|
||||
switch (filelist->sort) {
|
||||
case FILE_SORT_ALPHA:
|
||||
BLI_listbase_sort_r(&filelist->filelist_intern.entries, compare_name, NULL);
|
||||
sort_cb = compare_name;
|
||||
break;
|
||||
case FILE_SORT_TIME:
|
||||
BLI_listbase_sort_r(&filelist->filelist_intern.entries, compare_date, NULL);
|
||||
sort_cb = compare_date;
|
||||
break;
|
||||
case FILE_SORT_SIZE:
|
||||
BLI_listbase_sort_r(&filelist->filelist_intern.entries, compare_size, NULL);
|
||||
sort_cb = compare_size;
|
||||
break;
|
||||
case FILE_SORT_EXTENSION:
|
||||
BLI_listbase_sort_r(&filelist->filelist_intern.entries, compare_extension, NULL);
|
||||
sort_cb = compare_extension;
|
||||
break;
|
||||
case FILE_SORT_NONE: /* Should never reach this point! */
|
||||
default:
|
||||
BLI_assert(0);
|
||||
break;
|
||||
}
|
||||
BLI_listbase_sort_r(
|
||||
&filelist->filelist_intern.entries,
|
||||
sort_cb,
|
||||
&(struct FileSortData){.inverted = (filelist->flags & FL_SORT_INVERT) != 0});
|
||||
|
||||
filelist_filter_clear(filelist);
|
||||
filelist->flags &= ~FL_NEED_SORTING;
|
||||
}
|
||||
}
|
||||
|
||||
void filelist_setsorting(struct FileList *filelist, const short sort)
|
||||
void filelist_setsorting(struct FileList *filelist, const short sort, bool invert_sort)
|
||||
{
|
||||
if (filelist->sort != sort) {
|
||||
const bool was_invert_sort = filelist->flags & FL_SORT_INVERT;
|
||||
|
||||
if ((filelist->sort != sort) || (was_invert_sort != invert_sort)) {
|
||||
filelist->sort = sort;
|
||||
filelist->flags |= FL_NEED_SORTING;
|
||||
filelist->flags = invert_sort ? (filelist->flags | FL_SORT_INVERT) :
|
||||
(filelist->flags & ~FL_SORT_INVERT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,9 +657,9 @@ static bool is_filtered_file(FileListInternEntry *file,
|
||||
{
|
||||
bool is_filtered = !is_hidden_file(file->relpath, filter);
|
||||
|
||||
if (is_filtered && (filter->flags & FLF_DO_FILTER) && !FILENAME_IS_CURRPAR(file->relpath)) {
|
||||
if (is_filtered && !FILENAME_IS_CURRPAR(file->relpath)) {
|
||||
/* We only check for types if some type are enabled in filtering. */
|
||||
if (filter->filter) {
|
||||
if (filter->filter && (filter->flags & FLF_DO_FILTER)) {
|
||||
if (file->typeflag & FILE_TYPE_DIR) {
|
||||
if (file->typeflag &
|
||||
(FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) {
|
||||
@@ -657,6 +679,7 @@ static bool is_filtered_file(FileListInternEntry *file,
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If there's a filter string, apply it as filter even if FLF_DO_FILTER is not set. */
|
||||
if (is_filtered && (filter->filter_search[0] != '\0')) {
|
||||
if (fnmatch(filter->filter_search, file->relpath, FNM_CASEFOLD) != 0) {
|
||||
is_filtered = false;
|
||||
@@ -676,9 +699,9 @@ static bool is_filtered_lib(FileListInternEntry *file, const char *root, FileLis
|
||||
|
||||
if (BLO_library_path_explode(path, dir, &group, &name)) {
|
||||
is_filtered = !is_hidden_file(file->relpath, filter);
|
||||
if (is_filtered && (filter->flags & FLF_DO_FILTER) && !FILENAME_IS_CURRPAR(file->relpath)) {
|
||||
if (is_filtered && !FILENAME_IS_CURRPAR(file->relpath)) {
|
||||
/* We only check for types if some type are enabled in filtering. */
|
||||
if (filter->filter || filter->filter_id) {
|
||||
if ((filter->filter || filter->filter_id) && (filter->flags & FLF_DO_FILTER)) {
|
||||
if (file->typeflag & FILE_TYPE_DIR) {
|
||||
if (file->typeflag &
|
||||
(FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) {
|
||||
@@ -704,6 +727,7 @@ static bool is_filtered_lib(FileListInternEntry *file, const char *root, FileLis
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If there's a filter string, apply it as filter even if FLF_DO_FILTER is not set. */
|
||||
if (is_filtered && (filter->filter_search[0] != '\0')) {
|
||||
if (fnmatch(filter->filter_search, file->relpath, FNM_CASEFOLD) != 0) {
|
||||
is_filtered = false;
|
||||
@@ -904,42 +928,12 @@ static ImBuf *filelist_geticon_image_ex(const unsigned int typeflag, const char
|
||||
if (FILENAME_IS_PARENT(relpath)) {
|
||||
ibuf = gSpecialFileImages[SPECIAL_IMG_PARENT];
|
||||
}
|
||||
else if (FILENAME_IS_CURRENT(relpath)) {
|
||||
ibuf = gSpecialFileImages[SPECIAL_IMG_REFRESH];
|
||||
}
|
||||
else {
|
||||
ibuf = gSpecialFileImages[SPECIAL_IMG_FOLDER];
|
||||
}
|
||||
}
|
||||
else if (typeflag & FILE_TYPE_BLENDER) {
|
||||
ibuf = gSpecialFileImages[SPECIAL_IMG_BLENDFILE];
|
||||
}
|
||||
else if (typeflag & FILE_TYPE_BLENDERLIB) {
|
||||
ibuf = gSpecialFileImages[SPECIAL_IMG_UNKNOWNFILE];
|
||||
}
|
||||
else if (typeflag & (FILE_TYPE_MOVIE)) {
|
||||
ibuf = gSpecialFileImages[SPECIAL_IMG_MOVIEFILE];
|
||||
}
|
||||
else if (typeflag & FILE_TYPE_SOUND) {
|
||||
ibuf = gSpecialFileImages[SPECIAL_IMG_SOUNDFILE];
|
||||
}
|
||||
else if (typeflag & FILE_TYPE_PYSCRIPT) {
|
||||
ibuf = gSpecialFileImages[SPECIAL_IMG_PYTHONFILE];
|
||||
}
|
||||
else if (typeflag & FILE_TYPE_FTFONT) {
|
||||
ibuf = gSpecialFileImages[SPECIAL_IMG_FONTFILE];
|
||||
}
|
||||
else if (typeflag & FILE_TYPE_TEXT) {
|
||||
ibuf = gSpecialFileImages[SPECIAL_IMG_TEXTFILE];
|
||||
}
|
||||
else if (typeflag & FILE_TYPE_IMAGE) {
|
||||
ibuf = gSpecialFileImages[SPECIAL_IMG_LOADING];
|
||||
}
|
||||
else if (typeflag & FILE_TYPE_BLENDER_BACKUP) {
|
||||
ibuf = gSpecialFileImages[SPECIAL_IMG_BACKUP];
|
||||
}
|
||||
else {
|
||||
ibuf = gSpecialFileImages[SPECIAL_IMG_UNKNOWNFILE];
|
||||
ibuf = gSpecialFileImages[SPECIAL_IMG_DOCUMENT];
|
||||
}
|
||||
|
||||
return ibuf;
|
||||
@@ -1001,10 +995,13 @@ static int filelist_geticon_ex(const int typeflag,
|
||||
return ICON_FILE_BLANK;
|
||||
}
|
||||
else if (typeflag & FILE_TYPE_COLLADA) {
|
||||
return ICON_FILE_BLANK;
|
||||
return ICON_FILE_3D;
|
||||
}
|
||||
else if (typeflag & FILE_TYPE_ALEMBIC) {
|
||||
return ICON_FILE_BLANK;
|
||||
return ICON_FILE_3D;
|
||||
}
|
||||
else if (typeflag & FILE_TYPE_OBJECT_IO) {
|
||||
return ICON_FILE_3D;
|
||||
}
|
||||
else if (typeflag & FILE_TYPE_TEXT) {
|
||||
return ICON_FILE_TEXT;
|
||||
@@ -1243,7 +1240,8 @@ static void filelist_cache_previews_clear(FileListEntryCache *cache)
|
||||
BLI_task_pool_cancel(cache->previews_pool);
|
||||
|
||||
while ((preview = BLI_thread_queue_pop_timeout(cache->previews_done, 0))) {
|
||||
// printf("%s: DONE %d - %s - %p\n", __func__, preview->index, preview->path, preview->img);
|
||||
// printf("%s: DONE %d - %s - %p\n", __func__, preview->index, preview->path,
|
||||
// preview->img);
|
||||
if (preview->img) {
|
||||
IMB_freeImBuf(preview->img);
|
||||
}
|
||||
@@ -2128,6 +2126,9 @@ int ED_path_extension_type(const char *path)
|
||||
else if (BLI_path_extension_check(path, ".abc")) {
|
||||
return FILE_TYPE_ALEMBIC;
|
||||
}
|
||||
else if (BLI_path_extension_check_n(path, ".obj", ".3ds", ".fbx", ".glb", ".gltf", NULL)) {
|
||||
return FILE_TYPE_OBJECT_IO;
|
||||
}
|
||||
else if (BLI_path_extension_check_array(path, imb_ext_image)) {
|
||||
return FILE_TYPE_IMAGE;
|
||||
}
|
||||
@@ -2177,9 +2178,9 @@ int ED_file_extension_icon(const char *path)
|
||||
case FILE_TYPE_BTX:
|
||||
return ICON_FILE_BLANK;
|
||||
case FILE_TYPE_COLLADA:
|
||||
return ICON_FILE_BLANK;
|
||||
case FILE_TYPE_ALEMBIC:
|
||||
return ICON_FILE_BLANK;
|
||||
case FILE_TYPE_OBJECT_IO:
|
||||
return ICON_FILE_3D;
|
||||
case FILE_TYPE_TEXT:
|
||||
return ICON_FILE_TEXT;
|
||||
default:
|
||||
|
@@ -55,7 +55,7 @@ void folderlist_pushdir(struct ListBase *folderlist, const char *dir);
|
||||
const char *folderlist_peeklastdir(struct ListBase *folderdist);
|
||||
int folderlist_clear_next(struct SpaceFile *sfile);
|
||||
|
||||
void filelist_setsorting(struct FileList *filelist, const short sort);
|
||||
void filelist_setsorting(struct FileList *filelist, const short sort, bool invert_sort);
|
||||
void filelist_sort(struct FileList *filelist);
|
||||
|
||||
void filelist_setfilter_options(struct FileList *filelist,
|
||||
|
@@ -49,6 +49,8 @@
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_fnmatch.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
||||
#include "BKE_appdir.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_main.h"
|
||||
@@ -69,6 +71,8 @@
|
||||
#include "file_intern.h"
|
||||
#include "filelist.h"
|
||||
|
||||
#define VERTLIST_MAJORCOLUMN_WIDTH (25 * UI_UNIT_X)
|
||||
|
||||
FileSelectParams *ED_fileselect_get_params(struct SpaceFile *sfile)
|
||||
{
|
||||
if (!sfile->params) {
|
||||
@@ -99,6 +103,8 @@ short ED_fileselect_set_params(SpaceFile *sfile)
|
||||
sfile->params->filter_glob[0] = '\0';
|
||||
/* set the default thumbnails size */
|
||||
sfile->params->thumbnail_size = 128;
|
||||
/* Show size column by default. */
|
||||
sfile->params->details_flags = FILE_DETAILS_SIZE | FILE_DETAILS_DATETIME;
|
||||
}
|
||||
|
||||
params = sfile->params;
|
||||
@@ -161,6 +167,10 @@ short ED_fileselect_set_params(SpaceFile *sfile)
|
||||
params->flag &= ~FILE_DIRSEL_ONLY;
|
||||
}
|
||||
|
||||
if ((prop = RNA_struct_find_property(op->ptr, "hide_props_region"))) {
|
||||
params->flag |= RNA_property_boolean_get(op->ptr, prop) ? FILE_HIDE_TOOL_PROPS : 0;
|
||||
}
|
||||
|
||||
params->filter = 0;
|
||||
if ((prop = RNA_struct_find_property(op->ptr, "filter_blender"))) {
|
||||
params->filter |= RNA_property_boolean_get(op->ptr, prop) ? FILE_TYPE_BLENDER : 0;
|
||||
@@ -261,6 +271,10 @@ short ED_fileselect_set_params(SpaceFile *sfile)
|
||||
params->sort = FILE_SORT_ALPHA;
|
||||
}
|
||||
|
||||
if ((prop = RNA_struct_find_property(op->ptr, "action_type"))) {
|
||||
params->action_type = RNA_property_enum_get(op->ptr, prop);
|
||||
}
|
||||
|
||||
if (params->display == FILE_DEFAULTDISPLAY) {
|
||||
if (params->display_previous == FILE_DEFAULTDISPLAY) {
|
||||
if (U.uiflag & USER_SHOW_THUMBNAILS) {
|
||||
@@ -268,11 +282,11 @@ short ED_fileselect_set_params(SpaceFile *sfile)
|
||||
params->display = FILE_IMGDISPLAY;
|
||||
}
|
||||
else {
|
||||
params->display = FILE_SHORTDISPLAY;
|
||||
params->display = FILE_VERTICALDISPLAY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
params->display = FILE_SHORTDISPLAY;
|
||||
params->display = FILE_VERTICALDISPLAY;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -293,7 +307,7 @@ short ED_fileselect_set_params(SpaceFile *sfile)
|
||||
params->type = FILE_UNIX;
|
||||
params->flag |= FILE_HIDE_DOT;
|
||||
params->flag &= ~FILE_DIRSEL_ONLY;
|
||||
params->display = FILE_SHORTDISPLAY;
|
||||
params->display = FILE_VERTICALDISPLAY;
|
||||
params->display_previous = FILE_DEFAULTDISPLAY;
|
||||
params->sort = FILE_SORT_ALPHA;
|
||||
params->filter = 0;
|
||||
@@ -344,7 +358,7 @@ void ED_fileselect_reset_params(SpaceFile *sfile)
|
||||
void fileselect_file_set(SpaceFile *sfile, const int index)
|
||||
{
|
||||
const struct FileDirEntry *file = filelist_file(sfile->files, index);
|
||||
if (file && file->relpath && file->relpath[0] && !(file->typeflag & FILE_TYPE_FOLDER)) {
|
||||
if (file && file->relpath && file->relpath[0] && !(file->typeflag & FILE_TYPE_DIR)) {
|
||||
BLI_strncpy(sfile->params->file, file->relpath, FILE_MAXFILE);
|
||||
}
|
||||
}
|
||||
@@ -372,10 +386,10 @@ int ED_fileselect_layout_numfiles(FileLayout *layout, ARegion *ar)
|
||||
}
|
||||
else {
|
||||
const int y_item = layout->tile_h + (2 * layout->tile_border_y);
|
||||
const int y_view = (int)(BLI_rctf_size_y(&ar->v2d.cur));
|
||||
const int y_view = (int)(BLI_rctf_size_y(&ar->v2d.cur)) - layout->offset_top;
|
||||
const int y_over = y_item - (y_view % y_item);
|
||||
numfiles = (int)((float)(y_view + y_over) / (float)(y_item));
|
||||
return numfiles * layout->columns;
|
||||
return numfiles * layout->flow_columns;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,19 +409,19 @@ FileSelection ED_fileselect_layout_offset_rect(FileLayout *layout, const rcti *r
|
||||
}
|
||||
|
||||
colmin = (rect->xmin) / (layout->tile_w + 2 * layout->tile_border_x);
|
||||
rowmin = (rect->ymin) / (layout->tile_h + 2 * layout->tile_border_y);
|
||||
rowmin = (rect->ymin - layout->offset_top) / (layout->tile_h + 2 * layout->tile_border_y);
|
||||
colmax = (rect->xmax) / (layout->tile_w + 2 * layout->tile_border_x);
|
||||
rowmax = (rect->ymax) / (layout->tile_h + 2 * layout->tile_border_y);
|
||||
rowmax = (rect->ymax - layout->offset_top) / (layout->tile_h + 2 * layout->tile_border_y);
|
||||
|
||||
if (is_inside(colmin, rowmin, layout->columns, layout->rows) ||
|
||||
is_inside(colmax, rowmax, layout->columns, layout->rows)) {
|
||||
CLAMP(colmin, 0, layout->columns - 1);
|
||||
if (is_inside(colmin, rowmin, layout->flow_columns, layout->rows) ||
|
||||
is_inside(colmax, rowmax, layout->flow_columns, layout->rows)) {
|
||||
CLAMP(colmin, 0, layout->flow_columns - 1);
|
||||
CLAMP(rowmin, 0, layout->rows - 1);
|
||||
CLAMP(colmax, 0, layout->columns - 1);
|
||||
CLAMP(colmax, 0, layout->flow_columns - 1);
|
||||
CLAMP(rowmax, 0, layout->rows - 1);
|
||||
}
|
||||
|
||||
if ((colmin > layout->columns - 1) || (rowmin > layout->rows - 1)) {
|
||||
if ((colmin > layout->flow_columns - 1) || (rowmin > layout->rows - 1)) {
|
||||
sel.first = -1;
|
||||
}
|
||||
else {
|
||||
@@ -415,10 +429,10 @@ FileSelection ED_fileselect_layout_offset_rect(FileLayout *layout, const rcti *r
|
||||
sel.first = layout->rows * colmin + rowmin;
|
||||
}
|
||||
else {
|
||||
sel.first = colmin + layout->columns * rowmin;
|
||||
sel.first = colmin + layout->flow_columns * rowmin;
|
||||
}
|
||||
}
|
||||
if ((colmax > layout->columns - 1) || (rowmax > layout->rows - 1)) {
|
||||
if ((colmax > layout->flow_columns - 1) || (rowmax > layout->rows - 1)) {
|
||||
sel.last = -1;
|
||||
}
|
||||
else {
|
||||
@@ -426,7 +440,7 @@ FileSelection ED_fileselect_layout_offset_rect(FileLayout *layout, const rcti *r
|
||||
sel.last = layout->rows * colmax + rowmax;
|
||||
}
|
||||
else {
|
||||
sel.last = colmax + layout->columns * rowmax;
|
||||
sel.last = colmax + layout->flow_columns * rowmax;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -443,9 +457,9 @@ int ED_fileselect_layout_offset(FileLayout *layout, int x, int y)
|
||||
}
|
||||
|
||||
offsetx = (x) / (layout->tile_w + 2 * layout->tile_border_x);
|
||||
offsety = (y) / (layout->tile_h + 2 * layout->tile_border_y);
|
||||
offsety = (y - layout->offset_top) / (layout->tile_h + 2 * layout->tile_border_y);
|
||||
|
||||
if (offsetx > layout->columns - 1) {
|
||||
if (offsetx > layout->flow_columns - 1) {
|
||||
return -1;
|
||||
}
|
||||
if (offsety > layout->rows - 1) {
|
||||
@@ -456,27 +470,123 @@ int ED_fileselect_layout_offset(FileLayout *layout, int x, int y)
|
||||
active_file = layout->rows * offsetx + offsety;
|
||||
}
|
||||
else {
|
||||
active_file = offsetx + layout->columns * offsety;
|
||||
active_file = offsetx + layout->flow_columns * offsety;
|
||||
}
|
||||
return active_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the currently visible bounds of the layout in screen space. Matches View2D.mask minus the
|
||||
* top column-header row.
|
||||
*/
|
||||
void ED_fileselect_layout_maskrect(const FileLayout *layout, const View2D *v2d, rcti *r_rect)
|
||||
{
|
||||
*r_rect = v2d->mask;
|
||||
r_rect->ymax -= layout->offset_top;
|
||||
}
|
||||
|
||||
bool ED_fileselect_layout_is_inside_pt(const FileLayout *layout, const View2D *v2d, int x, int y)
|
||||
{
|
||||
rcti maskrect;
|
||||
ED_fileselect_layout_maskrect(layout, v2d, &maskrect);
|
||||
return BLI_rcti_isect_pt(&maskrect, x, y);
|
||||
}
|
||||
|
||||
bool ED_fileselect_layout_isect_rect(const FileLayout *layout,
|
||||
const View2D *v2d,
|
||||
const rcti *rect,
|
||||
rcti *r_dst)
|
||||
{
|
||||
rcti maskrect;
|
||||
ED_fileselect_layout_maskrect(layout, v2d, &maskrect);
|
||||
return BLI_rcti_isect(&maskrect, rect, r_dst);
|
||||
}
|
||||
|
||||
void ED_fileselect_layout_tilepos(FileLayout *layout, int tile, int *x, int *y)
|
||||
{
|
||||
if (layout->flag == FILE_LAYOUT_HOR) {
|
||||
*x = layout->tile_border_x +
|
||||
(tile / layout->rows) * (layout->tile_w + 2 * layout->tile_border_x);
|
||||
*y = layout->tile_border_y +
|
||||
*y = layout->offset_top + layout->tile_border_y +
|
||||
(tile % layout->rows) * (layout->tile_h + 2 * layout->tile_border_y);
|
||||
}
|
||||
else {
|
||||
*x = layout->tile_border_x +
|
||||
((tile) % layout->columns) * (layout->tile_w + 2 * layout->tile_border_x);
|
||||
*y = layout->tile_border_y +
|
||||
((tile) / layout->columns) * (layout->tile_h + 2 * layout->tile_border_y);
|
||||
((tile) % layout->flow_columns) * (layout->tile_w + 2 * layout->tile_border_x);
|
||||
*y = layout->offset_top + layout->tile_border_y +
|
||||
((tile) / layout->flow_columns) * (layout->tile_h + 2 * layout->tile_border_y);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the region coordinate defined by \a x and \a y are inside the column header.
|
||||
*/
|
||||
bool file_attribute_column_header_is_inside(const View2D *v2d,
|
||||
const FileLayout *layout,
|
||||
int x,
|
||||
int y)
|
||||
{
|
||||
rcti header_rect = v2d->mask;
|
||||
header_rect.ymin = header_rect.ymax - layout->attribute_column_header_h;
|
||||
return BLI_rcti_isect_pt(&header_rect, x, y);
|
||||
}
|
||||
|
||||
bool file_attribute_column_type_enabled(const FileSelectParams *params,
|
||||
FileAttributeColumnType column)
|
||||
{
|
||||
switch (column) {
|
||||
case COLUMN_NAME:
|
||||
/* Always enabled */
|
||||
return true;
|
||||
case COLUMN_DATETIME:
|
||||
return (params->details_flags & FILE_DETAILS_DATETIME) != 0;
|
||||
case COLUMN_SIZE:
|
||||
return (params->details_flags & FILE_DETAILS_SIZE) != 0;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the column type at region coordinate given by \a x (y doesn't matter for this).
|
||||
*/
|
||||
FileAttributeColumnType file_attribute_column_type_find_isect(const View2D *v2d,
|
||||
const FileSelectParams *params,
|
||||
FileLayout *layout,
|
||||
int x)
|
||||
{
|
||||
float mx, my;
|
||||
int offset_tile;
|
||||
|
||||
UI_view2d_region_to_view(v2d, x, v2d->mask.ymax - layout->offset_top - 1, &mx, &my);
|
||||
offset_tile = ED_fileselect_layout_offset(
|
||||
layout, (int)(v2d->tot.xmin + mx), (int)(v2d->tot.ymax - my));
|
||||
if (offset_tile > -1) {
|
||||
int tile_x, tile_y;
|
||||
int pos_x = 0;
|
||||
int rel_x; /* x relative to the hovered tile */
|
||||
|
||||
ED_fileselect_layout_tilepos(layout, offset_tile, &tile_x, &tile_y);
|
||||
/* Column header drawing doesn't use left tile border, so subtract it. */
|
||||
rel_x = mx - (tile_x - layout->tile_border_x);
|
||||
|
||||
for (FileAttributeColumnType column = 0; column < ATTRIBUTE_COLUMN_MAX; column++) {
|
||||
if (!file_attribute_column_type_enabled(params, column)) {
|
||||
continue;
|
||||
}
|
||||
const int width = layout->attribute_columns[column].width;
|
||||
|
||||
if (IN_RANGE(rel_x, pos_x, pos_x + width)) {
|
||||
return column;
|
||||
}
|
||||
|
||||
pos_x += width;
|
||||
}
|
||||
}
|
||||
|
||||
return COLUMN_NONE;
|
||||
}
|
||||
|
||||
float file_string_width(const char *str)
|
||||
{
|
||||
uiStyle *style = UI_style_get();
|
||||
@@ -512,20 +622,52 @@ float file_font_pointsize(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void column_widths(FileSelectParams *params, struct FileLayout *layout)
|
||||
static void file_attribute_columns_widths(const FileSelectParams *params, FileLayout *layout)
|
||||
{
|
||||
int i;
|
||||
FileAttributeColumn *columns = layout->attribute_columns;
|
||||
const bool small_size = SMALL_SIZE_CHECK(params->thumbnail_size);
|
||||
const int pad = small_size ? 0 : ATTRIBUTE_COLUMN_PADDING * 2;
|
||||
|
||||
for (i = 0; i < MAX_FILE_COLUMN; ++i) {
|
||||
layout->column_widths[i] = 0;
|
||||
for (int i = 0; i < ATTRIBUTE_COLUMN_MAX; ++i) {
|
||||
layout->attribute_columns[i].width = 0;
|
||||
}
|
||||
|
||||
layout->column_widths[COLUMN_NAME] = ((float)params->thumbnail_size / 8.0f) * UI_UNIT_X;
|
||||
/* Biggest possible reasonable values... */
|
||||
layout->column_widths[COLUMN_DATE] = file_string_width(small_size ? "23/08/89" : "23-Dec-89");
|
||||
layout->column_widths[COLUMN_TIME] = file_string_width("23:59");
|
||||
layout->column_widths[COLUMN_SIZE] = file_string_width(small_size ? "98.7 M" : "98.7 MiB");
|
||||
columns[COLUMN_DATETIME].width = file_string_width(small_size ? "23/08/89" :
|
||||
"23 Dec 6789, 23:59") +
|
||||
pad;
|
||||
columns[COLUMN_SIZE].width = file_string_width(small_size ? "98.7 M" : "098.7 MB") + pad;
|
||||
if (params->display == FILE_IMGDISPLAY) {
|
||||
columns[COLUMN_NAME].width = ((float)params->thumbnail_size / 8.0f) * UI_UNIT_X;
|
||||
}
|
||||
/* Name column uses remaining width */
|
||||
else {
|
||||
int remwidth = layout->tile_w;
|
||||
for (FileAttributeColumnType column_type = ATTRIBUTE_COLUMN_MAX - 1; column_type >= 0;
|
||||
column_type--) {
|
||||
if ((column_type == COLUMN_NAME) ||
|
||||
!file_attribute_column_type_enabled(params, column_type)) {
|
||||
continue;
|
||||
}
|
||||
remwidth -= columns[column_type].width;
|
||||
}
|
||||
columns[COLUMN_NAME].width = remwidth;
|
||||
}
|
||||
}
|
||||
|
||||
static void file_attribute_columns_init(const FileSelectParams *params, FileLayout *layout)
|
||||
{
|
||||
file_attribute_columns_widths(params, layout);
|
||||
|
||||
layout->attribute_columns[COLUMN_NAME].name = N_("Name");
|
||||
layout->attribute_columns[COLUMN_NAME].sort_type = FILE_SORT_ALPHA;
|
||||
layout->attribute_columns[COLUMN_NAME].text_align = UI_STYLE_TEXT_LEFT;
|
||||
layout->attribute_columns[COLUMN_DATETIME].name = N_("Date Modified");
|
||||
layout->attribute_columns[COLUMN_DATETIME].sort_type = FILE_SORT_TIME;
|
||||
layout->attribute_columns[COLUMN_DATETIME].text_align = UI_STYLE_TEXT_LEFT;
|
||||
layout->attribute_columns[COLUMN_SIZE].name = N_("Size");
|
||||
layout->attribute_columns[COLUMN_SIZE].sort_type = FILE_SORT_SIZE;
|
||||
layout->attribute_columns[COLUMN_SIZE].text_align = UI_STYLE_TEXT_RIGHT;
|
||||
}
|
||||
|
||||
void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *ar)
|
||||
@@ -533,7 +675,6 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *ar)
|
||||
FileSelectParams *params = ED_fileselect_get_params(sfile);
|
||||
FileLayout *layout = NULL;
|
||||
View2D *v2d = &ar->v2d;
|
||||
int maxlen = 0;
|
||||
int numfiles;
|
||||
int textheight;
|
||||
|
||||
@@ -560,57 +701,66 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, ARegion *ar)
|
||||
layout->tile_w = layout->prv_w + 2 * layout->prv_border_x;
|
||||
layout->tile_h = layout->prv_h + 2 * layout->prv_border_y + textheight;
|
||||
layout->width = (int)(BLI_rctf_size_x(&v2d->cur) - 2 * layout->tile_border_x);
|
||||
layout->columns = layout->width / (layout->tile_w + 2 * layout->tile_border_x);
|
||||
if (layout->columns > 0) {
|
||||
layout->rows = numfiles / layout->columns + 1; // XXX dirty, modulo is zero
|
||||
layout->flow_columns = layout->width / (layout->tile_w + 2 * layout->tile_border_x);
|
||||
layout->attribute_column_header_h = 0;
|
||||
layout->offset_top = 0;
|
||||
if (layout->flow_columns > 0) {
|
||||
layout->rows = numfiles / layout->flow_columns + 1; // XXX dirty, modulo is zero
|
||||
}
|
||||
else {
|
||||
layout->columns = 1;
|
||||
layout->flow_columns = 1;
|
||||
layout->rows = numfiles + 1; // XXX dirty, modulo is zero
|
||||
}
|
||||
layout->height = sfile->layout->rows * (layout->tile_h + 2 * layout->tile_border_y) +
|
||||
layout->tile_border_y * 2;
|
||||
layout->tile_border_y * 2 - layout->offset_top;
|
||||
layout->flag = FILE_LAYOUT_VER;
|
||||
}
|
||||
else {
|
||||
int column_space = 0.6f * UI_UNIT_X;
|
||||
int column_icon_space = 0.2f * UI_UNIT_X;
|
||||
else if (params->display == FILE_VERTICALDISPLAY) {
|
||||
int rowcount;
|
||||
|
||||
layout->prv_w = 0;
|
||||
layout->prv_h = 0;
|
||||
layout->prv_w = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_X;
|
||||
layout->prv_h = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_Y;
|
||||
layout->tile_border_x = 0.4f * UI_UNIT_X;
|
||||
layout->tile_border_y = 0.1f * UI_UNIT_Y;
|
||||
layout->prv_border_x = 0;
|
||||
layout->prv_border_y = 0;
|
||||
layout->tile_h = textheight * 3 / 2;
|
||||
layout->width = (int)(BLI_rctf_size_x(&v2d->cur) - 2 * layout->tile_border_x);
|
||||
layout->tile_w = layout->width;
|
||||
layout->flow_columns = 1;
|
||||
layout->attribute_column_header_h = layout->tile_h * 1.2f + 2 * layout->tile_border_y;
|
||||
layout->offset_top = layout->attribute_column_header_h;
|
||||
rowcount = (int)(BLI_rctf_size_y(&v2d->cur) - layout->offset_top - 2 * layout->tile_border_y) /
|
||||
(layout->tile_h + 2 * layout->tile_border_y);
|
||||
file_attribute_columns_init(params, layout);
|
||||
|
||||
layout->rows = MAX2(rowcount, numfiles);
|
||||
BLI_assert(layout->rows != 0);
|
||||
layout->height = sfile->layout->rows * (layout->tile_h + 2 * layout->tile_border_y) +
|
||||
layout->tile_border_y * 2 + layout->offset_top;
|
||||
layout->flag = FILE_LAYOUT_VER;
|
||||
}
|
||||
else if (params->display == FILE_HORIZONTALDISPLAY) {
|
||||
layout->prv_w = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_X;
|
||||
layout->prv_h = ((float)params->thumbnail_size / 20.0f) * UI_UNIT_Y;
|
||||
layout->tile_border_x = 0.4f * UI_UNIT_X;
|
||||
layout->tile_border_y = 0.1f * UI_UNIT_Y;
|
||||
layout->tile_h = textheight * 3 / 2;
|
||||
layout->attribute_column_header_h = 0;
|
||||
layout->offset_top = layout->attribute_column_header_h;
|
||||
layout->height = (int)(BLI_rctf_size_y(&v2d->cur) - 2 * layout->tile_border_y);
|
||||
/* Padding by full scrollbar H is too much, can overlap tile border Y. */
|
||||
layout->rows = (layout->height - V2D_SCROLL_HEIGHT + layout->tile_border_y) /
|
||||
(layout->tile_h + 2 * layout->tile_border_y);
|
||||
layout->tile_w = VERTLIST_MAJORCOLUMN_WIDTH;
|
||||
file_attribute_columns_init(params, layout);
|
||||
|
||||
column_widths(params, layout);
|
||||
|
||||
if (params->display == FILE_SHORTDISPLAY) {
|
||||
maxlen = ICON_DEFAULT_WIDTH_SCALE + column_icon_space +
|
||||
(int)layout->column_widths[COLUMN_NAME] + column_space +
|
||||
(int)layout->column_widths[COLUMN_SIZE] + column_space;
|
||||
}
|
||||
else {
|
||||
maxlen = ICON_DEFAULT_WIDTH_SCALE + column_icon_space +
|
||||
(int)layout->column_widths[COLUMN_NAME] + column_space +
|
||||
(int)layout->column_widths[COLUMN_DATE] + column_space +
|
||||
(int)layout->column_widths[COLUMN_TIME] + column_space +
|
||||
(int)layout->column_widths[COLUMN_SIZE] + column_space;
|
||||
}
|
||||
layout->tile_w = maxlen;
|
||||
if (layout->rows > 0) {
|
||||
layout->columns = numfiles / layout->rows + 1; // XXX dirty, modulo is zero
|
||||
layout->flow_columns = numfiles / layout->rows + 1; // XXX dirty, modulo is zero
|
||||
}
|
||||
else {
|
||||
layout->rows = 1;
|
||||
layout->columns = numfiles + 1; // XXX dirty, modulo is zero
|
||||
layout->flow_columns = numfiles + 1; // XXX dirty, modulo is zero
|
||||
}
|
||||
layout->width = sfile->layout->columns * (layout->tile_w + 2 * layout->tile_border_x) +
|
||||
layout->width = sfile->layout->flow_columns * (layout->tile_w + 2 * layout->tile_border_x) +
|
||||
layout->tile_border_x * 2;
|
||||
layout->flag = FILE_LAYOUT_HOR;
|
||||
}
|
||||
|
@@ -72,23 +72,40 @@ static SpaceLink *file_new(const ScrArea *UNUSED(area), const Scene *UNUSED(scen
|
||||
/* Ignore user preference "USER_HEADER_BOTTOM" here (always show top for new types). */
|
||||
ar->alignment = RGN_ALIGN_TOP;
|
||||
|
||||
/* Tools region */
|
||||
ar = MEM_callocN(sizeof(ARegion), "tools region for file");
|
||||
BLI_addtail(&sfile->regionbase, ar);
|
||||
ar->regiontype = RGN_TYPE_TOOLS;
|
||||
ar->alignment = RGN_ALIGN_LEFT;
|
||||
|
||||
/* Tool props (aka operator) region */
|
||||
ar = MEM_callocN(sizeof(ARegion), "tool props region 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 region for file");
|
||||
BLI_addtail(&sfile->regionbase, ar);
|
||||
ar->regiontype = RGN_TYPE_UI;
|
||||
ar->alignment = RGN_ALIGN_TOP;
|
||||
ar->flag |= RGN_FLAG_DYNAMIC_SIZE;
|
||||
|
||||
/* Tools region */
|
||||
ar = MEM_callocN(sizeof(ARegion), "tools region for file");
|
||||
BLI_addtail(&sfile->regionbase, ar);
|
||||
ar->regiontype = RGN_TYPE_TOOLS;
|
||||
ar->alignment = RGN_ALIGN_LEFT;
|
||||
/* Tools region (lower split region) */
|
||||
ar = MEM_callocN(sizeof(ARegion), "lower tools region for file");
|
||||
BLI_addtail(&sfile->regionbase, ar);
|
||||
ar->regiontype = RGN_TYPE_TOOLS;
|
||||
ar->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV;
|
||||
ar->flag |= RGN_FLAG_DYNAMIC_SIZE;
|
||||
|
||||
/* Execute region */
|
||||
ar = MEM_callocN(sizeof(ARegion), "execute region for file");
|
||||
BLI_addtail(&sfile->regionbase, ar);
|
||||
ar->regiontype = RGN_TYPE_EXECUTE;
|
||||
ar->alignment = RGN_ALIGN_BOTTOM;
|
||||
ar->flag |= RGN_FLAG_DYNAMIC_SIZE;
|
||||
|
||||
/* Tool props region is added as needed. */
|
||||
#if 0
|
||||
/* Tool props (aka operator) region */
|
||||
ar = MEM_callocN(sizeof(ARegion), "tool props region for file");
|
||||
BLI_addtail(&sfile->regionbase, ar);
|
||||
ar->regiontype = RGN_TYPE_TOOL_PROPS;
|
||||
ar->alignment = RGN_ALIGN_RIGHT;
|
||||
#endif
|
||||
|
||||
/* main region */
|
||||
ar = MEM_callocN(sizeof(ARegion), "main region for file");
|
||||
@@ -204,6 +221,7 @@ static SpaceLink *file_duplicate(SpaceLink *sl)
|
||||
static void file_refresh(const bContext *C, ScrArea *sa)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
SpaceFile *sfile = CTX_wm_space_file(C);
|
||||
FileSelectParams *params = ED_fileselect_get_params(sfile);
|
||||
struct FSMenu *fsmenu = ED_fsmenu_get();
|
||||
@@ -217,15 +235,16 @@ static void file_refresh(const bContext *C, ScrArea *sa)
|
||||
}
|
||||
filelist_setdir(sfile->files, params->dir);
|
||||
filelist_setrecursion(sfile->files, params->recursion_level);
|
||||
filelist_setsorting(sfile->files, params->sort);
|
||||
filelist_setfilter_options(sfile->files,
|
||||
(params->flag & FILE_FILTER) != 0,
|
||||
(params->flag & FILE_HIDE_DOT) != 0,
|
||||
false, /* TODO hide_parent, should be controllable? */
|
||||
params->filter,
|
||||
params->filter_id,
|
||||
params->filter_glob,
|
||||
params->filter_search);
|
||||
filelist_setsorting(sfile->files, params->sort, params->flag & FILE_SORT_INVERT);
|
||||
filelist_setfilter_options(
|
||||
sfile->files,
|
||||
(params->flag & FILE_FILTER) != 0,
|
||||
(params->flag & FILE_HIDE_DOT) != 0,
|
||||
true, /* Just always hide parent, prefer to not add an extra user option for this. */
|
||||
params->filter,
|
||||
params->filter_id,
|
||||
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);
|
||||
@@ -254,7 +273,7 @@ static void file_refresh(const bContext *C, ScrArea *sa)
|
||||
else {
|
||||
filelist_cache_previews_set(sfile->files, false);
|
||||
if (sfile->previews_timer) {
|
||||
WM_event_remove_timer_notifier(wm, CTX_wm_window(C), sfile->previews_timer);
|
||||
WM_event_remove_timer_notifier(wm, win, sfile->previews_timer);
|
||||
sfile->previews_timer = NULL;
|
||||
}
|
||||
}
|
||||
@@ -269,10 +288,20 @@ static void file_refresh(const bContext *C, ScrArea *sa)
|
||||
|
||||
/* Might be called with NULL sa, see file_main_region_draw() below. */
|
||||
if (sa && BKE_area_find_region_type(sa, RGN_TYPE_TOOLS) == NULL) {
|
||||
/* Create TOOLS/TOOL_PROPS regions. */
|
||||
/* Create TOOLS region. */
|
||||
file_tools_region(sa);
|
||||
|
||||
ED_area_initialize(wm, CTX_wm_window(C), sa);
|
||||
ED_area_initialize(wm, win, sa);
|
||||
}
|
||||
if (sa && sfile->op && BKE_area_find_region_type(sa, RGN_TYPE_TOOL_PROPS) == NULL) {
|
||||
/* Create TOOL_PROPS region. */
|
||||
ARegion *region_props = file_tool_props_region(sa);
|
||||
|
||||
if (params->flag & FILE_HIDE_TOOL_PROPS) {
|
||||
region_props->flag |= RGN_FLAG_HIDDEN;
|
||||
}
|
||||
|
||||
ED_area_initialize(wm, win, sa);
|
||||
}
|
||||
|
||||
ED_area_tag_redraw(sa);
|
||||
@@ -406,6 +435,11 @@ static void file_main_region_draw(const bContext *C, ARegion *ar)
|
||||
v2d->keepofs &= ~V2D_LOCKOFS_Y;
|
||||
v2d->keepofs |= V2D_LOCKOFS_X;
|
||||
}
|
||||
else if (params->display == FILE_VERTICALDISPLAY) {
|
||||
v2d->scroll = V2D_SCROLL_RIGHT;
|
||||
v2d->keepofs &= ~V2D_LOCKOFS_Y;
|
||||
v2d->keepofs |= V2D_LOCKOFS_X;
|
||||
}
|
||||
else {
|
||||
v2d->scroll = V2D_SCROLL_BOTTOM;
|
||||
v2d->keepofs &= ~V2D_LOCKOFS_X;
|
||||
@@ -439,7 +473,9 @@ static void file_main_region_draw(const bContext *C, ARegion *ar)
|
||||
UI_view2d_view_restore(C);
|
||||
|
||||
/* scrollers */
|
||||
scrollers = UI_view2d_scrollers_calc(v2d, NULL);
|
||||
rcti view_rect;
|
||||
ED_fileselect_layout_maskrect(sfile->layout, v2d, &view_rect);
|
||||
scrollers = UI_view2d_scrollers_calc(v2d, &view_rect);
|
||||
UI_view2d_scrollers_draw(v2d, scrollers);
|
||||
UI_view2d_scrollers_free(scrollers);
|
||||
}
|
||||
@@ -452,6 +488,7 @@ static void file_operatortypes(void)
|
||||
WM_operatortype_append(FILE_OT_select_box);
|
||||
WM_operatortype_append(FILE_OT_select_bookmark);
|
||||
WM_operatortype_append(FILE_OT_highlight);
|
||||
WM_operatortype_append(FILE_OT_sort_column_ui_context);
|
||||
WM_operatortype_append(FILE_OT_execute);
|
||||
WM_operatortype_append(FILE_OT_cancel);
|
||||
WM_operatortype_append(FILE_OT_parent);
|
||||
@@ -538,7 +575,8 @@ static void file_ui_region_init(wmWindowManager *wm, ARegion *ar)
|
||||
{
|
||||
wmKeyMap *keymap;
|
||||
|
||||
UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
|
||||
ED_region_panels_init(wm, ar);
|
||||
ar->v2d.keepzoom |= V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y;
|
||||
|
||||
/* own keymap */
|
||||
keymap = WM_keymap_ensure(wm->defaultconf, "File Browser", SPACE_FILE, 0);
|
||||
@@ -550,22 +588,18 @@ static void file_ui_region_init(wmWindowManager *wm, ARegion *ar)
|
||||
|
||||
static void file_ui_region_draw(const bContext *C, ARegion *ar)
|
||||
{
|
||||
float col[3];
|
||||
/* clear */
|
||||
UI_GetThemeColor3fv(TH_BACK, col);
|
||||
GPU_clear_color(col[0], col[1], col[2], 0.0);
|
||||
GPU_clear(GPU_COLOR_BIT);
|
||||
ED_region_panels(C, ar);
|
||||
}
|
||||
|
||||
/* scrolling here is just annoying, disable it */
|
||||
ar->v2d.cur.ymax = BLI_rctf_size_y(&ar->v2d.cur);
|
||||
ar->v2d.cur.ymin = 0;
|
||||
static void file_execution_region_init(wmWindowManager *wm, ARegion *ar)
|
||||
{
|
||||
ED_region_panels_init(wm, ar);
|
||||
ar->v2d.keepzoom |= V2D_LOCKZOOM_X | V2D_LOCKZOOM_Y;
|
||||
}
|
||||
|
||||
/* set view2d view matrix for scrolling (without scrollers) */
|
||||
UI_view2d_view_ortho(&ar->v2d);
|
||||
|
||||
file_draw_buttons(C, ar);
|
||||
|
||||
UI_view2d_view_restore(C);
|
||||
static void file_execution_region_draw(const bContext *C, ARegion *ar)
|
||||
{
|
||||
ED_region_panels(C, ar);
|
||||
}
|
||||
|
||||
static void file_ui_region_listener(wmWindow *UNUSED(win),
|
||||
@@ -656,13 +690,21 @@ void ED_spacetype_file(void)
|
||||
/* regions: ui */
|
||||
art = MEM_callocN(sizeof(ARegionType), "spacetype file region");
|
||||
art->regionid = RGN_TYPE_UI;
|
||||
art->prefsizey = 60;
|
||||
art->keymapflag = ED_KEYMAP_UI;
|
||||
art->listener = file_ui_region_listener;
|
||||
art->init = file_ui_region_init;
|
||||
art->draw = file_ui_region_draw;
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
/* regions: execution */
|
||||
art = MEM_callocN(sizeof(ARegionType), "spacetype file region");
|
||||
art->regionid = RGN_TYPE_EXECUTE;
|
||||
art->keymapflag = ED_KEYMAP_UI;
|
||||
art->listener = file_ui_region_listener;
|
||||
art->init = file_execution_region_init;
|
||||
art->draw = file_execution_region_draw;
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
/* regions: channels (directories) */
|
||||
art = MEM_callocN(sizeof(ARegionType), "spacetype file region");
|
||||
art->regionid = RGN_TYPE_TOOLS;
|
||||
@@ -677,8 +719,8 @@ void ED_spacetype_file(void)
|
||||
/* regions: tool properties */
|
||||
art = MEM_callocN(sizeof(ARegionType), "spacetype file operator region");
|
||||
art->regionid = RGN_TYPE_TOOL_PROPS;
|
||||
art->prefsizex = 0;
|
||||
art->prefsizey = 360;
|
||||
art->prefsizex = 240;
|
||||
art->prefsizey = 60;
|
||||
art->keymapflag = ED_KEYMAP_UI;
|
||||
art->listener = file_tools_region_listener;
|
||||
art->init = file_tools_region_init;
|
||||
|
@@ -1538,7 +1538,7 @@ void GRAPH_OT_sound_bake(wmOperatorType *ot)
|
||||
FILE_TYPE_FOLDER | FILE_TYPE_SOUND | FILE_TYPE_MOVIE,
|
||||
FILE_SPECIAL,
|
||||
FILE_OPENFILE,
|
||||
WM_FILESEL_FILEPATH,
|
||||
WM_FILESEL_FILEPATH | WM_FILESEL_SHOW_PROPS,
|
||||
FILE_DEFAULTDISPLAY,
|
||||
FILE_SORT_ALPHA);
|
||||
RNA_def_float(ot->srna,
|
||||
|
@@ -677,8 +677,11 @@ typedef struct FileSelectParams {
|
||||
/** Display mode flag. */
|
||||
short display;
|
||||
short display_previous;
|
||||
/** Details toggles (file size, creation date, etc.) */
|
||||
char details_flags;
|
||||
/* The type of file action (opening or saving) */
|
||||
char action_type; /* eFileSel_Action */
|
||||
/** Filter when (flags & FILE_FILTER) is true. */
|
||||
char _pad2[2];
|
||||
int filter;
|
||||
|
||||
/** Max number of levels in dirtree to show at once, 0 to disable recursion. */
|
||||
@@ -736,8 +739,8 @@ typedef struct SpaceFile {
|
||||
/* FileSelectParams.display */
|
||||
enum eFileDisplayType {
|
||||
FILE_DEFAULTDISPLAY = 0,
|
||||
FILE_SHORTDISPLAY = 1,
|
||||
FILE_LONGDISPLAY = 2,
|
||||
FILE_VERTICALDISPLAY = 1,
|
||||
FILE_HORIZONTALDISPLAY = 2,
|
||||
FILE_IMGDISPLAY = 3,
|
||||
};
|
||||
|
||||
@@ -750,6 +753,12 @@ enum eFileSortType {
|
||||
FILE_SORT_SIZE = 4,
|
||||
};
|
||||
|
||||
/* FileSelectParams.details_flags */
|
||||
enum eFileDetails {
|
||||
FILE_DETAILS_SIZE = (1 << 0),
|
||||
FILE_DETAILS_DATETIME = (1 << 1),
|
||||
};
|
||||
|
||||
/* these values need to be hardcoded in structs, dna does not recognize defines */
|
||||
/* also defined in BKE */
|
||||
#define FILE_MAXDIR 768
|
||||
@@ -787,6 +796,8 @@ typedef enum eFileSel_Params_Flag {
|
||||
FILE_FILTER = (1 << 8),
|
||||
FILE_PARAMS_FLAG_UNUSED_9 = (1 << 9), /* cleared */
|
||||
FILE_GROUP_INSTANCE = (1 << 10),
|
||||
FILE_SORT_INVERT = (1 << 11),
|
||||
FILE_HIDE_TOOL_PROPS = (1 << 12)
|
||||
} eFileSel_Params_Flag;
|
||||
|
||||
/* sfile->params->rename_flag */
|
||||
@@ -824,6 +835,8 @@ typedef enum eFileSel_File_Types {
|
||||
FILE_TYPE_OPERATOR = (1 << 14),
|
||||
FILE_TYPE_APPLICATIONBUNDLE = (1 << 15),
|
||||
FILE_TYPE_ALEMBIC = (1 << 16),
|
||||
/** For all kinds of recognized import/export formats. No need for specialized types. */
|
||||
FILE_TYPE_OBJECT_IO = (1 << 17),
|
||||
|
||||
/** An FS directory (i.e. S_ISDIR on its path is true). */
|
||||
FILE_TYPE_DIR = (1 << 30),
|
||||
@@ -882,8 +895,7 @@ typedef struct FileDirEntryRevision {
|
||||
int64_t time;
|
||||
/* Temp caching of UI-generated strings... */
|
||||
char size_str[16];
|
||||
char time_str[8];
|
||||
char date_str[16];
|
||||
char datetime_str[16 + 8];
|
||||
} FileDirEntryRevision;
|
||||
|
||||
/* Container for a variant, only relevant in asset context.
|
||||
|
@@ -420,19 +420,19 @@ const EnumPropertyItem rna_enum_file_sort_items[] = {
|
||||
{FILE_SORT_ALPHA,
|
||||
"FILE_SORT_ALPHA",
|
||||
ICON_SORTALPHA,
|
||||
"Sort alphabetically",
|
||||
"Name",
|
||||
"Sort the file list alphabetically"},
|
||||
{FILE_SORT_EXTENSION,
|
||||
"FILE_SORT_EXTENSION",
|
||||
ICON_SORTBYEXT,
|
||||
"Sort by extension",
|
||||
"Extension",
|
||||
"Sort the file list by extension/type"},
|
||||
{FILE_SORT_TIME,
|
||||
"FILE_SORT_TIME",
|
||||
ICON_SORTTIME,
|
||||
"Sort by time",
|
||||
"Modified Date",
|
||||
"Sort files by modification time"},
|
||||
{FILE_SORT_SIZE, "FILE_SORT_SIZE", ICON_SORTSIZE, "Sort by size", "Sort files by size"},
|
||||
{FILE_SORT_SIZE, "FILE_SORT_SIZE", ICON_SORTSIZE, "Size", "Sort files by size"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
@@ -2142,6 +2142,18 @@ static void rna_SpaceClipEditor_view_type_update(Main *UNUSED(bmain),
|
||||
|
||||
/* File browser. */
|
||||
|
||||
int rna_FileSelectParams_filename_editable(struct PointerRNA *ptr, const char **r_info)
|
||||
{
|
||||
FileSelectParams *params = ptr->data;
|
||||
|
||||
if (params && (params->flag & FILE_DIRSEL_ONLY)) {
|
||||
*r_info = "Only directories can be chosen for the current operation.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
return params ? PROP_EDITABLE : 0;
|
||||
}
|
||||
|
||||
static bool rna_FileSelectParams_use_lib_get(PointerRNA *ptr)
|
||||
{
|
||||
FileSelectParams *params = ptr->data;
|
||||
@@ -5133,25 +5145,25 @@ static void rna_def_fileselect_params(BlenderRNA *brna)
|
||||
PropertyRNA *prop;
|
||||
|
||||
static const EnumPropertyItem file_display_items[] = {
|
||||
{FILE_SHORTDISPLAY,
|
||||
"LIST_SHORT",
|
||||
ICON_SHORTDISPLAY,
|
||||
"Short List",
|
||||
"Display files as short list"},
|
||||
{FILE_LONGDISPLAY,
|
||||
"LIST_LONG",
|
||||
{FILE_VERTICALDISPLAY,
|
||||
"LIST_VERTICAL",
|
||||
ICON_LONGDISPLAY,
|
||||
"Long List",
|
||||
"Display files as a detailed list"},
|
||||
"Vertical List",
|
||||
"Display files as a vertical list"},
|
||||
{FILE_HORIZONTALDISPLAY,
|
||||
"LIST_HORIZONTAL",
|
||||
ICON_SHORTDISPLAY,
|
||||
"Horizontal List",
|
||||
"Display files as a horizontal list"},
|
||||
{FILE_IMGDISPLAY, "THUMBNAIL", ICON_IMGDISPLAY, "Thumbnails", "Display files as thumbnails"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem display_size_items[] = {
|
||||
{32, "TINY", 0, "Tiny", ""},
|
||||
{64, "SMALL", 0, "Small", ""},
|
||||
{64, "TINY", 0, "Tiny", ""},
|
||||
{96, "SMALL", 0, "Small", ""},
|
||||
{128, "NORMAL", 0, "Regular", ""},
|
||||
{256, "LARGE", 0, "Large", ""},
|
||||
{192, "LARGE", 0, "Large", ""},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
@@ -5267,7 +5279,10 @@ static void rna_def_fileselect_params(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Title", "Title for the file browser");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
|
||||
prop = RNA_def_property(srna, "directory", PROP_STRING, PROP_DIRPATH);
|
||||
/* Use BYTESTRING rather than DIRPATH as subtype so UI code doesn't add OT_directory_browse
|
||||
* button when displaying this prop in the file browser (it would just open a file browser). That
|
||||
* should be the only effective difference between the two. */
|
||||
prop = RNA_def_property(srna, "directory", PROP_STRING, PROP_BYTESTRING);
|
||||
RNA_def_property_string_sdna(prop, NULL, "dir");
|
||||
RNA_def_property_ui_text(prop, "Directory", "Directory displayed in the file browser");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
|
||||
@@ -5275,6 +5290,7 @@ static void rna_def_fileselect_params(BlenderRNA *brna)
|
||||
prop = RNA_def_property(srna, "filename", PROP_STRING, PROP_FILENAME);
|
||||
RNA_def_property_string_sdna(prop, NULL, "file");
|
||||
RNA_def_property_ui_text(prop, "File Name", "Active file in the file browser");
|
||||
RNA_def_property_editable_func(prop, "rna_FileSelectParams_filename_editable");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_library_browsing", PROP_BOOLEAN, PROP_NONE);
|
||||
@@ -5295,6 +5311,19 @@ static void rna_def_fileselect_params(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Recursion", "Numbers of dirtree levels to show simultaneously");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "show_details_size", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "details_flags", FILE_DETAILS_SIZE);
|
||||
RNA_def_property_ui_text(prop, "File Size", "Draw a column listing the size of each file");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "show_details_datetime", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "details_flags", FILE_DETAILS_DATETIME);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"File Modification Date",
|
||||
"Draw a column listing the date and time of modification for each file");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_filter", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", FILE_FILTER);
|
||||
RNA_def_property_ui_text(prop, "Filter Files", "Enable filtering of files");
|
||||
@@ -5311,6 +5340,12 @@ static void rna_def_fileselect_params(BlenderRNA *brna)
|
||||
RNA_def_property_ui_text(prop, "Sort", "");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_sort_invert", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", FILE_SORT_INVERT);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Reverse Sorting", "Sort items descending, from highest value to lowest");
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_filter_image", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "filter", FILE_TYPE_IMAGE);
|
||||
RNA_def_property_ui_text(prop, "Filter Images", "Show image files");
|
||||
|
@@ -159,7 +159,7 @@ enum {
|
||||
WM_WINDOW_USERPREFS,
|
||||
WM_WINDOW_DRIVERS,
|
||||
WM_WINDOW_INFO,
|
||||
// WM_WINDOW_FILESEL // UNUSED
|
||||
WM_WINDOW_FILESEL,
|
||||
};
|
||||
|
||||
struct wmWindow *WM_window_open(struct bContext *C, const struct rcti *rect);
|
||||
@@ -493,6 +493,8 @@ bool WM_operator_properties_checker_interval_test(const struct CheckerIntervalPa
|
||||
#define WM_FILESEL_FILENAME (1 << 2)
|
||||
#define WM_FILESEL_FILEPATH (1 << 3)
|
||||
#define WM_FILESEL_FILES (1 << 4)
|
||||
/* Show the properties sidebar by default. */
|
||||
#define WM_FILESEL_SHOW_PROPS (1 << 5)
|
||||
|
||||
/* operator as a python command (resultuing string must be freed) */
|
||||
char *WM_operator_pystring_ex(struct bContext *C,
|
||||
|
@@ -2339,46 +2339,32 @@ static int wm_handler_fileselect_do(bContext *C,
|
||||
|
||||
switch (val) {
|
||||
case EVT_FILESELECT_FULL_OPEN: {
|
||||
ScrArea *sa;
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
const int sizex = 1020 * UI_DPI_FAC;
|
||||
const int sizey = 600 * UI_DPI_FAC;
|
||||
|
||||
/* sa can be null when window A is active, but mouse is over window B
|
||||
* in this case, open file select in original window A. Also don't
|
||||
* use global areas. */
|
||||
if (handler->context.area == NULL || ED_area_is_global(handler->context.area)) {
|
||||
bScreen *screen = CTX_wm_screen(C);
|
||||
sa = (ScrArea *)screen->areabase.first;
|
||||
if (WM_window_open_temp(
|
||||
C, win->sizex / 2, win->sizey / 2, sizex, sizey, WM_WINDOW_FILESEL) != NULL) {
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
ARegion *region_header = BKE_area_find_region_type(area, RGN_TYPE_HEADER);
|
||||
|
||||
BLI_assert(area->spacetype == SPACE_FILE);
|
||||
|
||||
region_header->flag |= RGN_FLAG_HIDDEN;
|
||||
/* Header on bottom, AZone triangle to toggle header looks misplaced at the top */
|
||||
region_header->alignment = RGN_ALIGN_BOTTOM;
|
||||
|
||||
/* settings for filebrowser, sfile is not operator owner but sends events */
|
||||
sfile = (SpaceFile *)area->spacedata.first;
|
||||
sfile->op = handler->op;
|
||||
|
||||
ED_fileselect_set_params(sfile);
|
||||
}
|
||||
else {
|
||||
sa = handler->context.area;
|
||||
BKE_report(&wm->reports, RPT_ERROR, "Failed to open window!");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (sa->full) {
|
||||
/* ensure the first area becomes the file browser, because the second one is the small
|
||||
* top (info-)area which might be too small (in fullscreens we have max two areas) */
|
||||
if (sa->prev) {
|
||||
sa = sa->prev;
|
||||
}
|
||||
ED_area_newspace(C, sa, SPACE_FILE, true); /* 'sa' is modified in-place */
|
||||
/* we already had a fullscreen here -> mark new space as a stacked fullscreen */
|
||||
sa->flag |= (AREA_FLAG_STACKED_FULLSCREEN | AREA_FLAG_TEMP_TYPE);
|
||||
}
|
||||
else if (sa->spacetype == SPACE_FILE) {
|
||||
sa = ED_screen_state_toggle(C, CTX_wm_window(C), sa, SCREENMAXIMIZED);
|
||||
}
|
||||
else {
|
||||
sa = ED_screen_full_newspace(C, sa, SPACE_FILE); /* sets context */
|
||||
}
|
||||
|
||||
/* note, getting the 'sa' back from the context causes a nasty bug where the newly created
|
||||
* 'sa' != CTX_wm_area(C). removed the line below and set 'sa' in the 'if' above */
|
||||
/* sa = CTX_wm_area(C); */
|
||||
|
||||
/* settings for filebrowser, sfile is not operator owner but sends events */
|
||||
sfile = (SpaceFile *)sa->spacedata.first;
|
||||
sfile->op = handler->op;
|
||||
|
||||
ED_fileselect_set_params(sfile);
|
||||
|
||||
action = WM_HANDLER_BREAK;
|
||||
break;
|
||||
}
|
||||
@@ -2390,14 +2376,27 @@ static int wm_handler_fileselect_do(bContext *C,
|
||||
BLI_remlink(handlers, handler);
|
||||
|
||||
if (val != EVT_FILESELECT_EXTERNAL_CANCEL) {
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
for (wmWindow *win = wm->windows.first; win; win = win->next) {
|
||||
if (WM_window_is_temp_screen(win)) {
|
||||
bScreen *screen = WM_window_get_active_screen(win);
|
||||
ScrArea *file_sa = screen->areabase.first;
|
||||
|
||||
if (sa->full) {
|
||||
ED_screen_full_prevspace(C, sa);
|
||||
}
|
||||
/* user may have left fullscreen */
|
||||
else {
|
||||
ED_area_prevspace(C, sa);
|
||||
BLI_assert(file_sa->spacetype == SPACE_FILE);
|
||||
|
||||
if (BLI_listbase_is_single(&file_sa->spacedata)) {
|
||||
wmWindow *ctx_win = CTX_wm_window(C);
|
||||
wm_window_close(C, wm, win);
|
||||
CTX_wm_window_set(C, ctx_win); // wm_window_close() NULLs.
|
||||
}
|
||||
else if (file_sa->full) {
|
||||
ED_screen_full_prevspace(C, file_sa);
|
||||
}
|
||||
else {
|
||||
ED_area_prevspace(C, file_sa);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1205,6 +1205,8 @@ static ImBuf *blend_file_thumb(const bContext *C,
|
||||
/* will be scaled down, but gives some nice oversampling */
|
||||
ImBuf *ibuf;
|
||||
BlendThumbnail *thumb;
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
wmWindow *windrawable_old = wm->windrawable;
|
||||
char err_out[256] = "unknown";
|
||||
|
||||
/* screen if no camera found */
|
||||
@@ -1238,6 +1240,9 @@ static ImBuf *blend_file_thumb(const bContext *C,
|
||||
/* gets scaled to BLEN_THUMB_SIZE */
|
||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||
|
||||
/* Offscreen drawing requires a drawable window context. */
|
||||
wm_window_make_drawable(wm, CTX_wm_window(C));
|
||||
|
||||
if (scene->camera) {
|
||||
ibuf = ED_view3d_draw_offscreen_imbuf_simple(depsgraph,
|
||||
scene,
|
||||
@@ -1270,6 +1275,14 @@ static ImBuf *blend_file_thumb(const bContext *C,
|
||||
err_out);
|
||||
}
|
||||
|
||||
/* Reset to old drawable. */
|
||||
if (windrawable_old) {
|
||||
wm_window_make_drawable(wm, windrawable_old);
|
||||
}
|
||||
else {
|
||||
wm_window_clear_drawable(wm);
|
||||
}
|
||||
|
||||
if (ibuf) {
|
||||
float aspect = (scene->r.xsch * scene->r.xasp) / (scene->r.ysch * scene->r.yasp);
|
||||
|
||||
@@ -2322,7 +2335,7 @@ static void wm_open_mainfile_ui(bContext *UNUSED(C), wmOperator *op)
|
||||
|
||||
void WM_OT_open_mainfile(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Open Blender File";
|
||||
ot->name = "Open";
|
||||
ot->idname = "WM_OT_open_mainfile";
|
||||
ot->description = "Open a Blender file";
|
||||
|
||||
@@ -2504,7 +2517,7 @@ void WM_OT_recover_auto_save(wmOperatorType *ot)
|
||||
FILE_BLENDER,
|
||||
FILE_OPENFILE,
|
||||
WM_FILESEL_FILEPATH,
|
||||
FILE_LONGDISPLAY,
|
||||
FILE_HORIZONTALDISPLAY,
|
||||
FILE_SORT_TIME);
|
||||
}
|
||||
|
||||
@@ -2638,7 +2651,7 @@ void WM_OT_save_as_mainfile(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
ot->name = "Save As Blender File";
|
||||
ot->name = "Save As";
|
||||
ot->idname = "WM_OT_save_as_mainfile";
|
||||
ot->description = "Save the current file in the desired location";
|
||||
|
||||
|
@@ -561,7 +561,7 @@ static void wm_link_append_properties_common(wmOperatorType *ot, bool is_link)
|
||||
|
||||
void WM_OT_link(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Link from Library";
|
||||
ot->name = "Link";
|
||||
ot->idname = "WM_OT_link";
|
||||
ot->description = "Link from a Library .blend file";
|
||||
|
||||
@@ -585,7 +585,7 @@ void WM_OT_link(wmOperatorType *ot)
|
||||
|
||||
void WM_OT_append(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Append from Library";
|
||||
ot->name = "Append";
|
||||
ot->idname = "WM_OT_append";
|
||||
ot->description = "Append from a Library .blend file";
|
||||
|
||||
|
@@ -65,19 +65,27 @@ void WM_operator_properties_filesel(wmOperatorType *ot,
|
||||
0,
|
||||
"Default",
|
||||
"Automatically determine display type for files"},
|
||||
{FILE_SHORTDISPLAY,
|
||||
"LIST_SHORT",
|
||||
ICON_SHORTDISPLAY,
|
||||
{FILE_VERTICALDISPLAY,
|
||||
"LIST_VERTICAL",
|
||||
ICON_SHORTDISPLAY, /* Name of deprecated short list */
|
||||
"Short List",
|
||||
"Display files as short list"},
|
||||
{FILE_LONGDISPLAY,
|
||||
"LIST_LONG",
|
||||
ICON_LONGDISPLAY,
|
||||
{FILE_HORIZONTALDISPLAY,
|
||||
"LIST_HORIZONTAL",
|
||||
ICON_LONGDISPLAY, /* Name of deprecated long list */
|
||||
"Long List",
|
||||
"Display files as a detailed list"},
|
||||
{FILE_IMGDISPLAY, "THUMBNAIL", ICON_IMGDISPLAY, "Thumbnails", "Display files as thumbnails"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
static const EnumPropertyItem file_action_types[] = {
|
||||
{FILE_OPENFILE,
|
||||
"OPENFILE",
|
||||
0,
|
||||
"Open",
|
||||
"Use the file browser for opening files or a directory"},
|
||||
{FILE_SAVE, "SAVE", 0, "Save", "Use the file browser for saving a file"},
|
||||
};
|
||||
|
||||
if (flag & WM_FILESEL_FILEPATH) {
|
||||
RNA_def_string_file_path(ot->srna, "filepath", NULL, FILE_MAX, "File Path", "Path to file");
|
||||
@@ -99,6 +107,15 @@ void WM_operator_properties_filesel(wmOperatorType *ot,
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
if ((flag & WM_FILESEL_SHOW_PROPS) == 0) {
|
||||
prop = RNA_def_boolean(ot->srna,
|
||||
"hide_props_region",
|
||||
true,
|
||||
"Hide Operator Properties",
|
||||
"Collapse the region displaying the operator settings");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
if (action == FILE_SAVE) {
|
||||
/* note, this is only used to check if we should highlight the filename area red when the
|
||||
* filepath is an existing file. */
|
||||
@@ -186,6 +203,9 @@ void WM_operator_properties_filesel(wmOperatorType *ot,
|
||||
prop = RNA_def_enum(
|
||||
ot->srna, "sort_method", rna_enum_file_sort_items, sort, "File sorting mode", "");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
|
||||
prop = RNA_def_enum(ot->srna, "action_type", file_action_types, action, "Action Type", "");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
static void wm_operator_properties_select_action_ex(wmOperatorType *ot,
|
||||
|
@@ -807,6 +807,7 @@ wmWindow *WM_window_open_temp(bContext *C, int x, int y, int sizex, int sizey, i
|
||||
ScrArea *sa;
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
eSpace_Type space_type = SPACE_EMPTY;
|
||||
const char *title;
|
||||
|
||||
/* convert to native OS window coordinates */
|
||||
@@ -888,17 +889,24 @@ wmWindow *WM_window_open_temp(bContext *C, int x, int y, int sizex, int sizey, i
|
||||
CTX_wm_area_set(C, sa);
|
||||
|
||||
if (type == WM_WINDOW_RENDER) {
|
||||
ED_area_newspace(C, sa, SPACE_IMAGE, false);
|
||||
space_type = SPACE_IMAGE;
|
||||
}
|
||||
else if (type == WM_WINDOW_DRIVERS) {
|
||||
ED_area_newspace(C, sa, SPACE_GRAPH, false);
|
||||
space_type = SPACE_GRAPH;
|
||||
}
|
||||
else if (type == WM_WINDOW_USERPREFS) {
|
||||
space_type = SPACE_USERPREF;
|
||||
}
|
||||
else if (type == WM_WINDOW_FILESEL) {
|
||||
space_type = SPACE_FILE;
|
||||
}
|
||||
else if (type == WM_WINDOW_INFO) {
|
||||
ED_area_newspace(C, sa, SPACE_INFO, false);
|
||||
}
|
||||
else {
|
||||
ED_area_newspace(C, sa, SPACE_USERPREF, false);
|
||||
BLI_assert(false);
|
||||
}
|
||||
ED_area_newspace(C, sa, space_type, false);
|
||||
|
||||
ED_screen_change(C, screen);
|
||||
ED_screen_refresh(CTX_wm_manager(C), win); /* test scale */
|
||||
|
Reference in New Issue
Block a user