-
-
Notifications
You must be signed in to change notification settings - Fork 55
/
reportpanel.py
153 lines (128 loc) · 5.22 KB
/
reportpanel.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# reportpanel.py
#
# (c) 2017,2021 Michel Anders
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
import bpy
from bpy.props import FloatProperty, StringProperty
from bpy.types import Scene
from time import sleep
bl_info = {
"name": "Report Panel",
"author": "Michel Anders (varkenvarken)",
"version": (0, 0, 202105091029),
"blender": (2, 92, 0),
"location": "Info header",
"description": "Puts a progress indicator the view3d header region",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "Sample scripts"}
# a regular operator. will NOT work without a hack
# it is better to use a modal operator when doing
# time consuming things
class TestProgress(bpy.types.Operator):
bl_idname = 'scene.testprogress'
bl_label = 'Test Progress'
bl_options = {'REGISTER'}
def execute(self, context):
context.scene.progress_indicator_text = "Heavy job"
context.scene.progress_indicator = 0
for tick in range(10):
sleep(1) # placeholder for heavy work
context.scene.progress_indicator = tick*10
# see https://docs.blender.org/api/current/info_gotcha.html
bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
context.scene.progress_indicator = 101 # done
return {"FINISHED"}
class TestProgressModal(bpy.types.Operator):
bl_idname = 'scene.testprogressmodal'
bl_label = 'Test Progress Modal'
bl_options = {'REGISTER'}
def modal(self, context, event):
if event.type == 'TIMER':
self.ticks += 1
if self.ticks > 9:
context.scene.progress_indicator = 101 # done
context.window_manager.event_timer_remove(self.timer)
return {'CANCELLED'}
context.scene.progress_indicator = self.ticks*10
return {'RUNNING_MODAL'}
def invoke(self, context, event):
self.ticks = 0
context.scene.progress_indicator_text = "Heavy modal job"
context.scene.progress_indicator = 0
wm = context.window_manager
self.timer = wm.event_timer_add(1.0, window=context.window)
wm.modal_handler_add(self)
return {'RUNNING_MODAL'}
def menu_func(self, context):
self.layout.operator(TestProgress.bl_idname)
self.layout.operator(TestProgressModal.bl_idname)
# update function to tag all info areas for redraw
def update(self, context):
print('update')
areas = context.window.screen.areas
for area in areas:
if area.type == 'VIEW_3D':
area.tag_redraw()
# a variable where we can store the original draw funtion
info_header_draw = lambda s,c: None
classes = [TestProgress, TestProgressModal]
register_classes, unregister_classes = bpy.utils.register_classes_factory(classes)
def register():
# a value between [0,100] will show the slider
Scene.progress_indicator = FloatProperty(
default=-1,
subtype='PERCENTAGE',
precision=1,
min=-1,
soft_min=0,
soft_max=100,
max=101,
update=update)
# the label in front of the slider can be configured
Scene.progress_indicator_text = StringProperty(
default="Progress",
update=update)
# save the original draw method of the Info header
global info_header_draw
info_header_draw = bpy.types.VIEW3D_HT_tool_header.draw
# create a new draw function
def newdraw(self, context):
global info_header_draw
# first call the original stuff
info_header_draw(self, context)
print('newdraw')
# then add the prop that acts as a progress indicator
if (context.scene.progress_indicator >= 0 and
context.scene.progress_indicator <= 100) :
self.layout.separator()
text = context.scene.progress_indicator_text
self.layout.prop(context.scene,
"progress_indicator",
text=text,
slider=True)
# replace it
bpy.types.VIEW3D_HT_tool_header.draw = newdraw
# regular registration stuff
register_classes()
bpy.types.VIEW3D_MT_object.append(menu_func)
def unregister():
bpy.types.VIEW3D_MT_object.remove(menu_func)
global info_header_draw
bpy.types.VIEW3D_HT_tool_header.draw = info_header_draw
unregister_classes()