import bpy, time, sys, traceback
from . graphics.shader import Shader
from . graphics.load import load_image_file
from . database import DB
from . api.create import Create
from . events.event import Event_System
from . presets.preset_a import Preset_A
from . presets.preset_b import Preset_B
from . presets.preset_kit_ops import Preset_Kit_Ops
from . presets.preset_infinity_mods import Preset_Infinity_Mods
from . presets.pizza_ops import Preset_Pizza_Ops
from . presets.preset_brush_ops import Preset_Brush_Ops
from . presets.video_page import Preset_Videos
from . presets.every_scroll_win import Preset_Every_Scroll
class Modal_Communications():
# Key = Unique Time Signature
# Value = All the com data per instance of modal
coms = {}
unique_id = None
unique_offset = 0
class Com_Instance():
def __init__(self):
# Coms from operations modal
self.start_fade = False
# Destroy
self.destroy_now = False
# Coms for ui modal to operations modal
self.shader_ref = None
self.db_ref = None
self.preset_ref = None
self.event_system_ref = None
self.create_api_ref = None
self.scale_ref = None
# Coms for UI creation
self.custom_preset = "" # Create a non standard window
self.only_use_fast_ui = False # Prevents expanded mode
self.show_fast_ui = False # Only show the expanded
# Functions from ui modal
self.get_preset = None
# Overrides
self.start_mod_hidden = False
# Fail safes
self.time_since_fade_start = None
# If the windows should use warp mode
self.use_warp_mode = False
class Master():
def __init__(self, context, custom_preset="", show_fast_ui=True, use_warp_mode=False, start_mod_hidden=False):
self.context = context
# Override
self.only_use_fast_ui = False
# Create unique id
Modal_Communications.unique_id = time.time() + Modal_Communications.unique_offset
Modal_Communications.unique_offset += 1
if Modal_Communications.unique_offset > 10:
Modal_Communications.unique_offset = 0
self.unique_id = Modal_Communications.unique_id
Modal_Communications.coms[self.unique_id] = Com_Instance()
# Overrides
Modal_Communications.coms[self.unique_id].only_use_fast_ui = self.only_use_fast_ui
Modal_Communications.coms[self.unique_id].show_fast_ui = show_fast_ui
Modal_Communications.coms[self.unique_id].custom_preset = custom_preset
Modal_Communications.coms[self.unique_id].start_mod_hidden = start_mod_hidden
# Warp mode
Modal_Communications.coms[self.unique_id].use_warp_mode = use_warp_mode
# Start the UI modal
self.__launch_modal()
def __launch_modal(self):
'''The modal will create: Shader, Database, Preset, Event System, Create Api'''
bpy.ops.hops.modal_ui_draw('INVOKE_DEFAULT')
def setup(self):
'''Clears the layouts on all the windows.'''
if not self.__key_checker():
return
Modal_Communications.coms[self.unique_id].only_use_fast_ui = self.only_use_fast_ui
if Modal_Communications.coms[self.unique_id].scale_ref != Modal_Communications.coms[self.unique_id].db_ref.prefs.ui.Hops_modal_size:
Modal_Communications.coms[self.unique_id].scale_ref = Modal_Communications.coms[self.unique_id].db_ref.prefs.ui.Hops_modal_size
Modal_Communications.coms[self.unique_id].get_preset()
if Modal_Communications.coms[self.unique_id].only_use_fast_ui == False:
if Modal_Communications.coms[self.unique_id].db_ref.event.tab_pressed:
if not Modal_Communications.coms[self.unique_id].db_ref.event.shift_pressed:
Modal_Communications.coms[self.unique_id].db_ref.fast_ui.show = False
Modal_Communications.coms[self.unique_id].db_ref.clear_db()
Modal_Communications.coms[self.unique_id].create_api_ref.cell_index = 0
def receive_event(self, event, skip_m_h=False):
'''Update the event data in the database.'''
if not self.__key_checker():
return
Modal_Communications.coms[self.unique_id].event_system_ref.update_event_data(event=event, context=self.context, skip_m_h=skip_m_h)
# Fast UI
def receive_fast_ui(self, win_list=[], help_list=[], image="", mods_list=[], active_mod_name="", mods_label_text="Press M", number_mods=True):
'''Receive the main window dictionary.\n
Image is any image file name from the icons folder, without the extension.'''
if not self.__key_checker():
return
if Modal_Communications.coms[self.unique_id].db_ref.fast_ui.show == True:
Modal_Communications.coms[self.unique_id].db_ref.fast_ui.build_main(
win_list=win_list,
help_list=help_list,
image=image,
mods_list=mods_list,
active_mod_name=active_mod_name,
mods_label_text=mods_label_text,
number_mods=number_mods)
def collapse_fast_help(self):
'''Collapse fast help menu'''
if not self.__key_checker():
return
Modal_Communications.coms[self.unique_id].db_ref.fast_ui.show_help = False
def should_build_fast_ui(self):
'''Use this to determine if you should build the fast ui or the main ui.'''
if not self.__key_checker():
return
if Modal_Communications.coms[self.unique_id].only_use_fast_ui == True:
return True
if Modal_Communications.coms[self.unique_id].db_ref.fast_ui.show:
return True
return False
def receive_main(self, win_dict={}, window_name="MAIN", win_form=None):
'''Receive the main window dictionary.'''
if not self.__key_checker():
return
if Modal_Communications.coms[self.unique_id].preset_ref != None:
Modal_Communications.coms[self.unique_id].preset_ref.build_main(win_dict=win_dict, window_name=window_name, win_form=win_form)
def receive_help(self, hot_keys_dict={}, quick_ops_dict={}):
'''Receive the help window dictionary.'''
if not self.__key_checker():
return
if Modal_Communications.coms[self.unique_id].preset_ref != None:
Modal_Communications.coms[self.unique_id].preset_ref.build_help(hot_keys_dict=hot_keys_dict, quick_ops_dict=quick_ops_dict)
def receive_mod(self, win_dict={}, active_mod_name="", rename_window="", body_scroll=True):
'''Receive the mod window dictionary.'''
if not self.__key_checker():
return
if Modal_Communications.coms[self.unique_id].preset_ref != None:
Modal_Communications.coms[self.unique_id].preset_ref.build_mods(win_dict=win_dict, active_mod_name=active_mod_name, rename_window=rename_window, body_scroll=body_scroll)
def finished(self):
'''Run the event layer.'''
if not self.__key_checker():
return
if Modal_Communications.coms[self.unique_id].db_ref.fast_ui.show == False:
Modal_Communications.coms[self.unique_id].event_system_ref.run()
Modal_Communications.coms[self.unique_id].time_since_fade_start = time.time()
def is_mouse_over_ui(self):
'''For modal exit.'''
if not self.__key_checker():
return
if Modal_Communications.coms[self.unique_id].db_ref.fast_ui.show:
return False
elif Modal_Communications.coms[self.unique_id].db_ref.ui_event.active_window_key == "":
return False
else:
return True
def destroy(self):
'''Remove the shader and graphics data.'''
if not self.__key_checker():
return
Modal_Communications.coms[self.unique_id].destroy_now = True
def destroy_immediate (self):
'''Remove the shader and graphics data immediately.'''
if not self.__key_checker():
return
Modal_Communications.coms[self.unique_id].destroy_now = True
Modal_Communications.coms[self.unique_id].shader_ref.destroy()
Modal_Communications.coms[self.unique_id].preset_ref.destroy()
def run_fade(self):
'''Called from the operations modal when finished.'''
if not self.__key_checker():
return
Modal_Communications.coms[self.unique_id].start_fade = True
Modal_Communications.coms[self.unique_id].time_since_fade_start = time.time()
def __key_checker(self):
'''Make sure keys are valid.'''
if self.unique_id in Modal_Communications.coms:
return True
if len(Modal_Communications.coms) > 0:
for com in Modal_Communications.coms.items():
com[1].destroy_now = True
return False
class HOPS_MODAL_UI_Draw(bpy.types.Operator):
bl_idname = "hops.modal_ui_draw"
bl_label = "Drawing for modals"
bl_options = {"INTERNAL"}
def start(self):
self.db = DB()
self.preset = None
self.scale = None
self.unique_id = Modal_Communications.unique_id
# Warp mode
self.db.prefs.ui.Hops_warp_mode = Modal_Communications.coms[self.unique_id].use_warp_mode
# Event
self.event_sys = Event_System(db=self.db)
# Graphics
self.shader = None
# API
self.create = Create(db=self.db)
# Get window preset
self.get_preset()
def get_preset(self):
custom_preset = Modal_Communications.coms[self.unique_id].custom_preset
self.db.fast_ui.show = Modal_Communications.coms[self.unique_id].show_fast_ui
# Custom Presets
if custom_preset != "":
if custom_preset == "preset_kit_ops":
self.preset = Preset_Kit_Ops(create=self.create)
return
elif custom_preset == "preset_infinity_mods":
self.preset = Preset_Infinity_Mods(create=self.create)
return
elif custom_preset == "pizza_ops":
self.preset = Preset_Pizza_Ops(create=self.create)
return
elif custom_preset == "brush_ops":
self.preset = Preset_Brush_Ops(create=self.create)
return
elif custom_preset == "Video_Page":
self.preset = Preset_Videos(create=self.create)
return
elif custom_preset == "Every_Scroll":
self.preset = Preset_Every_Scroll(create=self.create)
return
# Prefs Presets
preset = self.db.prefs.ui.Hops_modal_presets
if preset == "preset_A":
self.preset = Preset_A(create=self.create)
elif preset == "preset_B":
self.preset = Preset_B(create=self.create)
def invoke(self, context, event):
self.start()
self.shader = Shader(context=context, db=self.db)
self.scale = self.db.prefs.ui.Hops_modal_size
# self.timer = context.window_manager.event_timer_add(0.025, window=context.window)
self.timer = None
self.setup_modal_com()
context.window_manager.modal_handler_add(self)
return {'RUNNING_MODAL'}
def setup_modal_com(self):
Modal_Communications.coms[self.unique_id].shader_ref = self.shader
Modal_Communications.coms[self.unique_id].db_ref = self.db
Modal_Communications.coms[self.unique_id].preset_ref = self.preset
Modal_Communications.coms[self.unique_id].event_system_ref = self.event_sys
Modal_Communications.coms[self.unique_id].create_api_ref = self.create
Modal_Communications.coms[self.unique_id].scale_ref = self.scale
# Functions
Modal_Communications.coms[self.unique_id].get_preset = self.get_preset
self.db.fast_ui.start_mod_hidden = Modal_Communications.coms[self.unique_id].start_mod_hidden
def modal(self, context, event):
# Redraw
try:
if self.timer != None:
context.area.tag_redraw()
except:
self.shader.destroy()
self.db.fast_ui.destroy()
self.preset.destroy()
Modal_Communications.coms.pop(self.unique_id)
self.remove_timer()
context.area.tag_redraw()
return {'FINISHED'}
# Destroy now
if Modal_Communications.coms[self.unique_id].destroy_now == True:
self.shader.destroy()
self.preset.destroy()
Modal_Communications.coms.pop(self.unique_id)
self.remove_timer()
return {'FINISHED'}
# Remove if key is not there
if self.unique_id not in Modal_Communications.coms:
try:
self.shader.destroy()
self.db.fast_ui.destroy()
self.preset.destroy()
self.remove_timer()
except:
pass
self.remove_timer()
context.area.tag_redraw()
return {'FINISHED'}
# Start fade
if Modal_Communications.coms[self.unique_id].start_fade == True:
if self.timer == None and self.db.prefs.ui.Hops_modal_fade > 0.01:
self.timer = context.window_manager.event_timer_add(0.025, window=context.window)
if self.db.prefs.ui.Hops_modal_fade < 0.01:
self.shader.destroy()
self.db.fast_ui.destroy()
self.preset.destroy()
Modal_Communications.coms.pop(self.unique_id)
self.remove_timer()
context.area.tag_redraw()
return {'FINISHED'}
self.shader.remove_handle()
self.preset.destroy()
# Fade is done
if self.shader.handle == None:
Modal_Communications.coms.pop(self.unique_id)
self.db.fast_ui.destroy()
self.preset.destroy()
self.remove_timer()
context.area.tag_redraw()
return {'FINISHED'}
return {'PASS_THROUGH'}
def remove_timer(self):
if self.timer != None:
bpy.context.window_manager.event_timer_remove(self.timer)
class HOPS_MODAL_UI_Purge(bpy.types.Operator):
"""
Remove straggling UI by refreshing 3d view.
"""
bl_idname = "hops.modal_ui_purge"
bl_label = "Purge dead Hops UI"
def execute(self, context):
for com in Modal_Communications.coms.values():
com.start_fade = True
return {'FINISHED'}