This video shows the script that I’m working.
[video]https://pbs.twimg.com/tweet_video/CFnnSLlWYAAZeU8.mp4[/video]
It’s still a very poor script, needs many upgrades.
But I will let it here for those who want to support :).
import bpy
import bgl
import blf
def update_locs(self):
top = self.space.top
vlines = self.space.visible_lines
vrange = range(top, top+vlines)
self.loc_co = set()
for i, loc in enumerate(self.locs):
if loc[0] in vrange:
coords = self.space.region_location_from_cursor(*loc)
self.loc_co.add((i, coords))
def update_text(self, ref_text, IDE, hide = {-1}):
self.locs = []
iddef = 0
lsp = 100
hidden_lines = 0
for i, l in enumerate(ref_text.lines):
text = l.body
if text != '' and not text.isspace():
sp = 0
while text[sp] == ' ':
sp += 1
fdef = text.find('def ')
fclass = text.find('class ')
if fdef != -1 and sp == fdef or\
fclass != -1 and sp == fclass:
self.locs.append((i-hidden_lines, sp+2))
if iddef in hide:
lsp = sp
else:
lsp = 100
iddef +=1
if sp <= lsp:
if i == 0:
IDE.write(text)
else:
IDE.write('
'+text)
else:
hidden_lines += 1
def navigation(self, context, event):
rv3d = context.region_data
if not hasattr(self, 'navigation_cache'): # or self.navigation_cache == False:
self.navigation_cache = True
self.scroll = []
self.scroll_bar = []
for key in context.window_manager.keyconfigs.user.keymaps['Text'].keymap_items:
if key.idname == 'text.scroll':
if not key.properties.is_property_set('lines'):
self.scroll.append((key.alt, key.ctrl, key.shift, key.type, key.value, 0))
else:
self.scroll.append((key.alt, key.ctrl, key.shift, key.type, key.value, key.properties.lines))
elif key.idname == 'text.scroll_bar':
self.scroll_bar.append((key.alt, key.ctrl, key.shift, key.type, key.value))
evkey = (event.alt, event.ctrl, event.shift, event.type, event.value)
for key in self.scroll:
if evkey == key[0:5]:
if key[5] != 0:
bpy.ops.text.scroll(lines=key[5])
else:
bpy.ops.text.scroll('INVOKE_DEFAULT')
update_locs(self)
break
for key in self.scroll_bar:
if evkey == key:
bpy.ops.text.scroll_bar('INVOKE_DEFAULT')
update_locs(self)
break
class ModalDrawOperator(bpy.types.Operator):
"""Draw a line with the mouse"""
bl_idname = "text.modal_operator"
bl_label = "Simple Modal View3D Operator"
def modal(self, context, event):
rx, ry = context.region.width, context.region.height
x, y = event.mouse_region_x, event.mouse_region_y
if x < 0 or y < 0 or x - rx > 0 or y - ry > 0:
return {'PASS_THROUGH'}
else:
#context.area.tag_redraw()
self.update = navigation(self, context, event)
if event.type in {'MOUSEMOVE', 'LEFTMOUSE'}:
di = 10
for i, loc in self.loc_co:
if abs(x - loc[0]) < di and abs(y - loc[1]-15) < di:
context.window.cursor_set("DEFAULT")
if event.type == 'LEFTMOUSE' and event.value == 'PRESS':
if i not in self.hide:
self.hide.add(i)
else:
self.hide.remove(i)
IDE = self.space.text
IDE.clear()
update_text(self, self.text, IDE, hide = self.hide)
update_locs(self)
break
else:
context.window.cursor_set("TEXT")
if event.type in {'RIGHTMOUSE', 'ESC'}:
bpy.data.texts.remove(self.space.text)
self.space.text = self.text
return {'CANCELLED'}
return {'RUNNING_MODAL'}
def invoke(self, context, event):
area = context.area
if area.type == 'TEXT_EDITOR':
for space in area.spaces:
if space.type == 'TEXT_EDITOR':
self.text = space.text
IDE = bpy.data.texts.new('IDE_'+'\"'+self.text.name+'\"')
self.hide = set()
update_text(self, self.text, IDE)
self.loc_co = set()
space.text = IDE
self.space = space
update_locs(self)
break
self.update = True
context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'}
else:
self.report({'WARNING'}, "Text Editor not found, cannot run operator")
return {'CANCELLED'}
class EDITOR_Panel(bpy.types.Panel):
bl_space_type = "TEXT_EDITOR"
bl_region_type = "UI"
bl_label = "Editor"
def draw(self, context):
layout = self.layout
layout.operator("text.modal_operator", text = "IDE")
def register():
bpy.utils.register_class(ModalDrawOperator)
bpy.utils.register_class(EDITOR_Panel)
def unregister():
bpy.utils.unregister_class(ModalDrawOperator)
bpy.utils.unregister_class(EDITOR_Panel)
if __name__ == "__main__":
register()
bpy.ops.text.modal_operator('INVOKE_DEFAULT')
It is in this sub-forum because it’s still incomplete.