651 lines
44 KiB
Python
651 lines
44 KiB
Python
# 字节码版本: 3.11a7e (3495)
|
||
# 源代码时间戳: 2025-04-22 11:47:05 UTC (1745322425)
|
||
|
||
"""
|
||
GS曲线工具主窗口
|
||
---
|
||
GS曲线工具许可协议:
|
||
名为GS曲线工具的此代码集合归乔治·斯拉德科夫斯基(叶戈尔·斯拉德科夫斯基)所有,
|
||
未经他的书面许可,不得复制或分发。
|
||
|
||
GS曲线工具 v1.3.10 个人版
|
||
版权所有 2025,乔治·斯拉德科夫斯基(叶戈尔·斯拉德科夫斯基)
|
||
保留所有权利
|
||
|
||
用户界面字体为Roboto,该字体根据Apache 2.0许可协议授权:
|
||
http://www.apache.org/licenses/LICENSE-2.0
|
||
|
||
Autodesk Maya是Autodesk公司的产品:
|
||
https://www.autodesk.com/
|
||
|
||
社交媒体和联系方式:
|
||
|
||
Discord服务器: https://discord.gg/f4DH6HQ
|
||
在线商店: https://sladkovsky3d.artstation.com/store
|
||
在线文档: https://gs-curvetools.readthedocs.io/
|
||
Twitch频道: https://www.twitch.tv/videonomad
|
||
YouTube频道: https://www.youtube.com/c/GeorgeSladkovsky
|
||
ArtStation作品集: https://www.artstation.com/sladkovsky3d
|
||
联系邮箱: george.sladkovsky@gmail.com
|
||
"""
|
||
import os
|
||
from functools import partial
|
||
import maya.cmds as mc
|
||
from gs_curvetools.api.maya_tools import deferred, get_mod, no_undo, undo
|
||
from gs_curvetools.api.qt_compat import *
|
||
from gs_curvetools.api.typing import *
|
||
from gs_curvetools.api.utils import open_link
|
||
from gs_curvetools.config.constants import *
|
||
from gs_curvetools.config.folders import GetFolder
|
||
from gs_curvetools.debug.logger import logger
|
||
from gs_curvetools.managers.options_manager import OptionsManager
|
||
from gs_curvetools.managers.script_jobs import ScriptJobs
|
||
from gs_curvetools.ui import style
|
||
from gs_curvetools.ui.components import AboutWindow, AttributesFilterWindow, CurveControlWindow, CurveThicknessWindow, CustomLayerColorsWindow, GeoToCurveWindow, RandomizeCurveWindow, ScaleFactorWindow, UVEditorWindow
|
||
from gs_curvetools.ui.tooltips import Tooltips
|
||
from gs_curvetools.ui.utils import maya_dockable_window
|
||
from gs_curvetools.ui.widgets import ActionGroup, Button, Frame, Layer, LayerCollectionWidget, Layout, LineEdit, Menu, MenuItem, Row, get_unique_name, maya_slider, separator, wrap_control
|
||
if TYPE_CHECKING:
|
||
from gs_curvetools.core.core import Core
|
||
from gs_curvetools.managers.widget_manager import WidgetManager
|
||
|
||
class MainWindow(QWidget):
|
||
"""Main GS CurveTools window"""
|
||
|
||
def __init__(self, manager, core):
|
||
menu_height = 786 if MAYA_VER <= 2024 else 810
|
||
dockable_window = maya_dockable_window(name=WINDOWS.MainWindow.name, label=WINDOWS.MainWindow.label, i_h=menu_height)
|
||
mc.workspaceControl(WINDOWS.MainWindow.name, e=1, ui=UI_SCRIPT)
|
||
super(MainWindow, self).__init__(dockable_window)
|
||
self.setParent(dockable_window)
|
||
dockable_layout = dockable_window.layout()
|
||
assert dockable_layout is not None
|
||
dockable_layout.addWidget(self)
|
||
self.widget_manager = manager
|
||
self.core = core
|
||
self.script_jobs = ScriptJobs.singleton()
|
||
self.script_jobs.check_script_jobs(WINDOWS.MainWindow.name)
|
||
self.options_manager = OptionsManager()
|
||
self.tooltips = Tooltips()
|
||
QtGui.QFontDatabase.removeAllApplicationFonts()
|
||
fonts = os.listdir(GetFolder.fonts())
|
||
for font in fonts:
|
||
QtGui.QFontDatabase.addApplicationFont(os.path.join(GetFolder.fonts(), font))
|
||
self.about_window = AboutWindow()
|
||
self.attributes_filter_window = AttributesFilterWindow(self)
|
||
self.curve_control_window = CurveControlWindow(self)
|
||
self.curve_thickness_window = CurveThicknessWindow(self)
|
||
self.custom_layer_colors_window = CustomLayerColorsWindow(self)
|
||
self.geo_to_curve_window = GeoToCurveWindow(self)
|
||
self.randomize_curve_window = RandomizeCurveWindow(self)
|
||
self.scale_factor_window = ScaleFactorWindow(self)
|
||
self.uv_editor = UVEditorWindow(self)
|
||
self.widget_manager.add(WINDOWS.MainWindow.name, dockable_window)
|
||
self._connect_signals()
|
||
|
||
def _connect_signals(self):
|
||
"""Sets up the signals"""
|
||
self.curve_control_window.update_curve_control_ui.connect(self.core.curve_control.update_ui)
|
||
self.curve_control_window.update_main_ui.connect(self.core.updates.update_main_ui)
|
||
|
||
def create_ui(self):
|
||
"""Creates the UI"""
|
||
main_layout = QVBoxLayout(self)
|
||
main_layout.setContentsMargins(*style.scale([2, 0, 2, 0]))
|
||
scroll_area = QScrollArea(self)
|
||
scroll_widget = QWidget()
|
||
scroll_widget.setFocus()
|
||
scroll_layout = QVBoxLayout(scroll_widget)
|
||
scroll_area.setWidget(scroll_widget)
|
||
main_layout.addWidget(scroll_area)
|
||
scroll_layout.setContentsMargins(0, 0, 0, 0)
|
||
scroll_layout.setSpacing(style.scale(2))
|
||
scroll_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
|
||
scroll_area.setFrameShape(QtWidgets.QFrame.Shape.NoFrame)
|
||
scroll_area.setWidgetResizable(True)
|
||
menu_bar_widget = QWidget(scroll_area)
|
||
menu_bar_layout = QHBoxLayout(menu_bar_widget)
|
||
menu_bar_layout.setContentsMargins(0, 0, 0, 0)
|
||
menu_bar_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
|
||
menu_bar = QMenuBar(menu_bar_widget)
|
||
menu_bar.setSizePolicy(QtWidgets.QSizePolicy.Policy.Preferred, QtWidgets.QSizePolicy.Policy.Preferred)
|
||
menu_bar_layout.addWidget(menu_bar)
|
||
scroll_layout.addWidget(menu_bar_widget)
|
||
with Menu('选项', menu_bar) as menu:
|
||
menu.triggered.connect(self.options_manager.save)
|
||
menu.addSection('导入 / 导出')
|
||
import_curves = MenuItem('importCurves', '导入曲线', menu)
|
||
import_curves.triggered.connect(no_undo(self.core.import_export.import_curves))
|
||
export_curves = MenuItem('exportCurves', '导出曲线', menu)
|
||
export_curves.triggered.connect(self.core.import_export.export_curves)
|
||
menu.addSection('全局修改器')
|
||
change_scale_factor = MenuItem('changeScaleFactor', '更改比例因子和精度', menu)
|
||
change_scale_factor.triggered.connect(self.scale_factor_window.show_window)
|
||
global_curve_thickness = MenuItem('globalCurveThickness', '全局曲线厚度', menu)
|
||
global_curve_thickness.triggered.connect(self.curve_thickness_window.show_window)
|
||
menu.addSection('视图端口命令')
|
||
ao_settings = MenuItem('setAOSettings', '设置AO设置', menu)
|
||
ao_settings.triggered.connect(self.options_manager.set_ao_settings)
|
||
with Menu('透明度设置', menu) as transparency_settings_menu:
|
||
simple_transparency = MenuItem('setSimpleTransparency', '简单透明度(快速,不准确)', transparency_settings_menu)
|
||
simple_transparency.triggered.connect(partial(no_undo(self.options_manager.set_transparency_settings), 0))
|
||
object_sorting_transparency = MenuItem('setObjectSortingTransparency', '对象排序透明度(中等)', transparency_settings_menu)
|
||
object_sorting_transparency.triggered.connect(partial(no_undo(self.options_manager.set_transparency_settings), 1))
|
||
set_depth_transparency = MenuItem('setDepthTransparency', '深度透明度(准确,缓慢,推荐)', transparency_settings_menu)
|
||
set_depth_transparency.triggered.connect(partial(no_undo(self.options_manager.set_transparency_settings), 2))
|
||
menu.addSection('转换曲线')
|
||
with Menu('转换曲线', menu) as convert_curves_submenu:
|
||
convert_to_warp_card = MenuItem('convertToWarpCard', '转换为变形面片', convert_curves_submenu)
|
||
convert_to_warp_card.triggered.connect(partial(undo(self.core.functions.convert_selection_to), 0))
|
||
convert_to_warp_tube = MenuItem('convertToWarpTube', '转换为变形管', convert_curves_submenu)
|
||
convert_to_warp_tube.triggered.connect(partial(undo(self.core.functions.convert_selection_to), 1))
|
||
convert_to_extrude_card = MenuItem('convertToExtrudeCard', '转换为挤压面片', convert_curves_submenu)
|
||
convert_to_extrude_card.triggered.connect(partial(undo(self.core.functions.convert_selection_to), 2))
|
||
convert_to_extrude_tube = MenuItem('convertToExtrudeTube', '转换为挤压管', convert_curves_submenu)
|
||
convert_to_extrude_tube.triggered.connect(partial(undo(self.core.functions.convert_selection_to), 3))
|
||
menu.addSection('实用功能')
|
||
duplicate_unparent = MenuItem('duplicateUnparentCurves', '复制并取消父级关联曲线', menu)
|
||
duplicate_unparent.triggered.connect(undo(self.core.functions.duplicate_unparent))
|
||
menu.addSection('常规选项')
|
||
MenuItem('keepCurveAttributes', '保留曲线属性', menu, True, self.options_manager.get('keepCurveAttributes'))
|
||
MenuItem('addBetweenBlendAttributes', '添加面片/管混合属性', menu, True, self.options_manager.get('addBetweenBlendAttributes'))
|
||
MenuItem('fillCreateCurvesOnly', '填充仅创建曲线', menu, True, self.options_manager.get('fillCreateCurvesOnly'))
|
||
MenuItem('convertInstances', '自动转换实例', menu, True, self.options_manager.get('convertInstances'))
|
||
MenuItem('useAutoSamplingOnNewCurves', '对新曲线使用自动采样', menu, True, self.options_manager.get('useAutoSamplingOnNewCurves'))
|
||
MenuItem('useAutoRefineOnNewCurves', '对新曲线使用自动细化', menu, True, self.options_manager.get('useAutoRefineOnNewCurves'))
|
||
MenuItem('flipUVsAfterMirror', '镜像后翻转UV', menu, True, self.options_manager.get('flipUVsAfterMirror'))
|
||
enable_tooltips_menu = MenuItem('enableTooltips', '启用工具提示', menu, True, self.options_manager.get('enableTooltips'))
|
||
enable_tooltips_menu.triggered.connect(self.toggle_tooltips)
|
||
menu.addSection('颜色选项')
|
||
sync_color = MenuItem('syncCurveColor', '同步曲线颜色到图层颜色', menu, True, self.options_manager.get('syncCurveColor'))
|
||
sync_color.triggered.connect(self.core.color_mode.sync_curve_colors)
|
||
MenuItem('colorizedRegroup', '对重新分组的图层进行颜色化', menu, True, self.options_manager.get('colorizedRegroup'))
|
||
color_only_diffuse = MenuItem('colorOnlyDiffuse', '颜色仅影响漫反射', menu, True, self.options_manager.get('colorOnlyDiffuse'))
|
||
color_only_diffuse.triggered.connect(self.core.color_mode.update_color_options)
|
||
checker_pattern = MenuItem('checkerPattern', '颜色模式使用棋盘格图案', menu, True, self.options_manager.get('checkerPattern'))
|
||
checker_pattern.triggered.connect(self.core.color_mode.update_color_options)
|
||
menu.addSection('绑定选项')
|
||
MenuItem('boundCurvesFollowParent', '绑定曲线跟随父级', menu, True, self.options_manager.get('boundCurvesFollowParent'))
|
||
MenuItem('massBindOption', '绑定到所有可用的空曲线', menu, True, self.options_manager.get('massBindOption'))
|
||
MenuItem('bindDuplicatesCurves', '绑定前复制曲线', menu, True, self.options_manager.get('bindDuplicatesCurves'))
|
||
MenuItem('bindFlipUVs', '绑定前翻转UV', menu, True, self.options_manager.get('bindFlipUVs'))
|
||
menu.addSection('解绑/解包选项')
|
||
MenuItem('unpackDeleteOriginalObject', '解包时删除原始对象', menu, True, self.options_manager.get('unpackDeleteOriginalObject'))
|
||
MenuItem('unpackCVMatch', '解包匹配原始CV数量', menu, True, self.options_manager.get('unpackCVMatch'))
|
||
menu.addSection('图层选项')
|
||
MenuItem('ignoreLastLayer', '忽略最后一个图层', menu, True, self.options_manager.get('ignoreLastLayer'))
|
||
MenuItem('syncOutlinerLayerVis', '同步大纲/图层可见性', menu, True, self.options_manager.get('syncOutlinerLayerVis'))
|
||
MenuItem('replacingCurveLayerSelection', '替换曲线图层选择', menu, True, self.options_manager.get('replacingCurveLayerSelection'))
|
||
only_numbers_in_layers = MenuItem('layerNumbersOnly', '图层仅使用数字', menu, True, self.options_manager.get('layerNumbersOnly'))
|
||
only_numbers_in_layers.triggered.connect(self.core.layer_manager.change_layers_to_numbers)
|
||
only_numbers_in_layers.triggered.connect(self.update_layer_list)
|
||
with Menu('活动图层数量', menu) as layer_number_menu, ActionGroup('layerRowsActionGroup', layer_number_menu) as action_group:
|
||
MenuItem('2layerRows', '20个图层', layer_number_menu, True, self.options_manager.get('2layerRows'), collection=action_group)
|
||
MenuItem('3layerRows', '30个图层', layer_number_menu, True, self.options_manager.get('3layerRows'), collection=action_group)
|
||
MenuItem('4layerRows', '40个图层', layer_number_menu, True, self.options_manager.get('4layerRows'), collection=action_group)
|
||
MenuItem('6layerRows', '60个图层', layer_number_menu, True, self.options_manager.get('6layerRows'), collection=action_group)
|
||
MenuItem('8layerRows', '80个图层', layer_number_menu, True, self.options_manager.get('8layerRows'), collection=action_group)
|
||
action_group.triggered.connect(self.core.updates.update_main_ui)
|
||
menu.addSection('图层集合选项')
|
||
MenuItem('ignoreTemplateCollections', '忽略“模板”集合名称', menu, True, self.options_manager.get('ignoreTemplateCollections'))
|
||
MenuItem('groupTemplateCollections', '将“模板”集合分组在一起', menu, True, self.options_manager.get('groupTemplateCollections'))
|
||
layer_collections_toggle = MenuItem('showLayerCollectionsMenu', '显示图层集合菜单', menu, True, self.options_manager.get('showLayerCollectionsMenu'))
|
||
layer_collections_toggle.triggered.connect(self.core.layer_manager.layer_collections.toggle_widget)
|
||
MenuItem('importIntoANewCollection', '导入到新集合中', menu, True, self.options_manager.get('importIntoANewCollection'))
|
||
menu.addSection('其他选项')
|
||
with Menu('其他选项', menu) as other_options_menu:
|
||
other_options_menu.addSection('更新功能')
|
||
convert_to_new_layer_system = MenuItem('convertToNewLayerSystem', '转换为新图层系统', other_options_menu)
|
||
convert_to_new_layer_system.triggered.connect(undo(self.core.utils.convert_to_new_layer_system))
|
||
update_layers = MenuItem('updateLayers', '更新图层', other_options_menu)
|
||
update_layers.triggered.connect(undo(self.core.layer_manager.delete_unused_layers))
|
||
from gs_curvetools.main import reset as reset_gs_curvetools
|
||
reset_to_defaults = MenuItem('resetToDefaults', '恢复默认设置', other_options_menu)
|
||
reset_to_defaults.triggered.connect(reset_gs_curvetools)
|
||
other_options_menu.addSection('修复')
|
||
maya_2020_uv_fix = MenuItem('maya2020UVFix', '修复Maya 2020 - 2022 UV错误', other_options_menu)
|
||
maya_2020_uv_fix.triggered.connect(undo(self.core.fixes.fix_maya_2020_uvs))
|
||
fix_broken_graphs = MenuItem('mayaFixBrokenGraphs', '修复损坏的图表', other_options_menu)
|
||
fix_broken_graphs.triggered.connect(undo(self.core.fixes.fix_broken_graphs))
|
||
convert_bezier_to_nurbs = MenuItem('convertBezierToNurbs', '将所选贝塞尔曲线转换为NURBS曲线', other_options_menu)
|
||
convert_bezier_to_nurbs.triggered.connect(undo(self.core.fixes.convert_bezier_to_nurbs))
|
||
maya_2020_twist_fix = MenuItem('maya2020TwistAttribute', '修复Maya 2020.4扭曲属性', other_options_menu)
|
||
maya_2020_twist_fix.triggered.connect(undo(self.core.fixes.fix_maya_2020_twist))
|
||
maya_2020_unbind_fix = MenuItem('maya2020UnbindFix', '修复Maya 2020.4解绑功能', other_options_menu)
|
||
maya_2020_unbind_fix.triggered.connect(undo(self.core.fixes.fix_maya_2020_unbind))
|
||
delete_all_animation_keys = MenuItem('deleteAllAnimationKeys', '删除所有动画关键帧', other_options_menu)
|
||
delete_all_animation_keys.triggered.connect(undo(self.core.fixes.delete_keys_on_all_objects))
|
||
disable_curve_smooth = MenuItem('disableCurveSmooth', '重置旧版曲线平滑属性', other_options_menu)
|
||
disable_curve_smooth.triggered.connect(self.core.fixes.reset_curve_smooth)
|
||
reset_legacy_magnitude = MenuItem('resetLegacyMagnitude', '重置旧版轮廓幅度属性', other_options_menu)
|
||
reset_legacy_magnitude.triggered.connect(self.core.fixes.reset_legacy_profile_magnitude)
|
||
with Menu('帮助', menu_bar) as menu:
|
||
open_log_file = MenuItem('openLogFile', '打开日志文件', menu)
|
||
open_log_file.triggered.connect(logger.open_log_file)
|
||
open_online_documentation = MenuItem('openOnlineDocumentation', '打开在线文档', menu)
|
||
open_online_documentation.triggered.connect(lambda: open_link(USER_DOCS))
|
||
useful_links = MenuItem('usefulLinks', '有用的链接和联系方式', menu)
|
||
useful_links.triggered.connect(self.about_window.social_window)
|
||
with Menu('关于', menu_bar) as menu:
|
||
about_action = MenuItem('gsAbout', '关于', menu)
|
||
about_action.triggered.connect(self.about_window.about_window)
|
||
menu.addSeparator()
|
||
menu.addAction('Made by George Sladkovsky (%s)' % YEAR).setEnabled(False)
|
||
scroll_layout.addWidget(separator())
|
||
with Row(scroll_layout) as row:
|
||
extrude_warp_switch_group = QtWidgets.QButtonGroup(scroll_layout.widget())
|
||
self.widget_manager.add('gsExtrudeWarpSwitchGroup', extrude_warp_switch_group)
|
||
extrude_warp_switch_group.buttonToggled.connect(self.extrude_warp_toggle)
|
||
extrude_warp_switch_group.buttonClicked.connect(self.options_manager.save)
|
||
warp_switch = Button(row.layout(), 'warpSwitch')
|
||
warp_switch.set_label('变形', line_height=100)
|
||
warp_switch.set_button_style('small')
|
||
warp_switch.setCheckable(True)
|
||
extrude_switch = Button(row.layout(), 'extrudeSwitch')
|
||
extrude_switch.set_label('挤压', line_height=100)
|
||
extrude_switch.set_button_style('small')
|
||
extrude_switch.setCheckable(True)
|
||
extrude_warp_switch_group.addButton(warp_switch, 0)
|
||
extrude_warp_switch_group.addButton(extrude_switch, 1)
|
||
with Row(scroll_layout) as row:
|
||
new_card = Button(row.layout(), 'newCard')
|
||
new_card.set_label('新面片')
|
||
new_card.clicked.connect(partial(undo(self.core.create.new), 0))
|
||
new_tube = Button(row.layout(), 'newTube')
|
||
new_tube.set_label('新管')
|
||
new_tube.clicked.connect(partial(undo(self.core.create.new), 1))
|
||
with Row(scroll_layout) as row:
|
||
curve_card = Button(row.layout(), 'curveCard')
|
||
curve_card.set_label('曲线面片')
|
||
curve_card.clicked.connect(partial(undo(self.core.create.from_curves), 0))
|
||
curve_tube = Button(row.layout(), 'curveTube')
|
||
curve_tube.set_label('曲线管')
|
||
curve_tube.clicked.connect(partial(undo(self.core.create.from_curves), 1))
|
||
with Row(scroll_layout) as row:
|
||
bind = Button(row.layout(), 'gsBind')
|
||
bind.set_label('绑定')
|
||
bind.set_icon('mod-top')
|
||
bind.clicked.connect(undo(self.core.create.bind))
|
||
unbind = Button(row.layout(), 'gsUnbind')
|
||
unbind.set_label('解绑')
|
||
unbind.set_icon('mod-top')
|
||
unbind.clicked.connect(undo(lambda: self.core.create.unpack() if get_mod() == 'Shift' else self.core.create.unbind()))
|
||
scroll_layout.addWidget(separator())
|
||
with Row(scroll_layout) as row:
|
||
add_cards = Button(row.layout(), 'addCards')
|
||
add_cards.set_label('添加面片')
|
||
add_cards.set_icon('mod-top')
|
||
add_cards.clicked.connect(partial(undo(self.core.create.add_between), 0))
|
||
add_tubes = Button(row.layout(), 'addTubes')
|
||
add_tubes.set_label('添加管')
|
||
add_tubes.set_icon('mod-top')
|
||
add_tubes.clicked.connect(partial(undo(self.core.create.add_between), 1))
|
||
with Row(scroll_layout) as row:
|
||
fill = Button(row.layout(), 'gsFill')
|
||
fill.set_label('填充')
|
||
fill.set_icon('mod-top')
|
||
fill.clicked.connect(undo(self.core.create.fill))
|
||
subdivide = Button(row.layout(), 'gsSubdivide')
|
||
subdivide.set_label('细分')
|
||
subdivide.set_icon('mod-top')
|
||
subdivide.clicked.connect(undo(self.core.functions.subdivide_curve))
|
||
with Row(scroll_layout) as row:
|
||
m_add_cards_slider = mc.intSliderGrp('gsCurvesSlider', l='添加', f=1, adj=3, cw=[(1, 20), (2, 25), (3, 1)], min=1, max=10, v=3)
|
||
add_cards_slider = maya_slider(m_add_cards_slider, layout=row.layout())
|
||
self.widget_manager.add('gsCurvesSlider', add_cards_slider)
|
||
add_cards_slider.setContentsMargins(0, 0, 0, 0)
|
||
c = add_cards_slider.children()[2]
|
||
if isinstance(c, QWidget):
|
||
c.setFocusPolicy(QtCore.Qt.FocusPolicy.NoFocus)
|
||
scroll_layout.addWidget(separator())
|
||
with Row(scroll_layout) as row:
|
||
edge_to_curve = Button(row.layout(), 'gsEdgeToCurve')
|
||
edge_to_curve.set_label('边转曲线')
|
||
edge_to_curve.set_icon('mod-top')
|
||
edge_to_curve.clicked.connect(undo(self.core.conversion.edge_to_curve))
|
||
geo_to_curve = Button(row.layout(), 'gsGeoToCurve')
|
||
geo_to_curve.set_label('几何体转曲线')
|
||
geo_to_curve.clicked.connect(self.geo_to_curve_window.open_ui)
|
||
scroll_layout.addWidget(separator())
|
||
with Row(scroll_layout, obj_name='LayerCollectionsLayout', spacing=1) as layer_collections_layout:
|
||
layer_combo_box = LayerCollectionWidget('layerCollectionsComboBox')
|
||
layer_combo_box.setStyleSheet(style.SMALL_COMBO_BOX)
|
||
|
||
def collection_changed():
|
||
self.core.updates.update_visibility_based_on_active_collection()
|
||
self.core.updates.update_main_ui()
|
||
layer_combo_box.currentIndexChanged.connect(lambda *_: deferred(collection_changed)())
|
||
layer_combo_box.setSizeAdjustPolicy(QtWidgets.QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon)
|
||
layer_combo_box.setDuplicatesEnabled(False)
|
||
layer_combo_box.setMinimumWidth(0)
|
||
layer_combo_box.setFixedHeight(style.scale(16))
|
||
mc.popupMenu(mm=1, p=layer_combo_box.objectName())
|
||
mc.menuItem(rp='N', l='清除', c=lambda *_: undo(self.core.layer_manager.layer_collections.clear)())
|
||
mc.menuItem(rp='E', l='复制', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.copy)())
|
||
mc.menuItem(rp='NE', l='上移', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.move_up)())
|
||
mc.menuItem(rp='NW', l='合并上移', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.merge_up)())
|
||
mc.menuItem(rp='W', l='粘贴', c=lambda *_: undo(self.core.layer_manager.layer_collections.paste)())
|
||
mc.menuItem(rp='SW', l='合并下移', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.merge_down)())
|
||
mc.menuItem(rp='SE', l='下移', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.move_down)())
|
||
mc.menuItem(rp='S', l='重命名', c=lambda *_: no_undo(self.core.layer_manager.layer_collections.rename)())
|
||
with Row(layer_collections_layout.layout(), margins=style.scale([1, 0, 0, 0])) as plus_minus_buttons_layout:
|
||
layer_combo_plus = Button(obj_name='layerCollectionsPlus', layout=plus_minus_buttons_layout.layout())
|
||
layer_combo_plus.setFixedHeight(style.scale(16))
|
||
layer_combo_plus.set_label('+', line_height=100)
|
||
layer_combo_plus.setMinimumWidth(1)
|
||
layer_combo_plus.set_button_style('small-filled')
|
||
layer_combo_plus.clicked.connect(self.core.layer_manager.layer_collections.create)
|
||
layer_combo_minus = Button(obj_name='layerCollectionsMinus', layout=plus_minus_buttons_layout.layout())
|
||
layer_combo_minus.setEnabled(False)
|
||
layer_combo_minus.setFixedHeight(style.scale(16))
|
||
layer_combo_minus.setMinimumWidth(1)
|
||
layer_combo_minus.set_label('-', line_height=100)
|
||
layer_combo_minus.set_button_style('small-filled')
|
||
layer_combo_minus.clicked.connect(undo(self.core.layer_manager.layer_collections.delete))
|
||
lcl = layer_collections_layout.layout()
|
||
if isinstance(lcl, QHBoxLayout):
|
||
lcl.addWidget(layer_combo_box, 3)
|
||
lcl.addWidget(plus_minus_buttons_layout, 1)
|
||
layer_combo_box.insertItem(0, '主集合')
|
||
with Row(scroll_layout) as row:
|
||
all_filter = Button(row.layout(), 'gsAllFilter')
|
||
all_filter.set_button_style('small-filled')
|
||
all_filter.set_label('全部', line_height=100)
|
||
all_filter.set_icon('mod-top')
|
||
all_filter.clicked.connect(partial(undo(self.core.layer_manager.layers_filter_toggle), True, True))
|
||
curve_filter = Button(row.layout(), 'gsCurveFilter')
|
||
curve_filter.set_button_style('small-filled')
|
||
curve_filter.set_label('曲线', line_height=100)
|
||
curve_filter.clicked.connect(partial(undo(self.core.layer_manager.layers_filter_toggle), True, False, ignore=['Shift+Ctrl']))
|
||
mc.popupMenu(mm=1, p=curve_filter.objectName())
|
||
mc.menuItem(rp='N', l='切换始终置顶', c=lambda *_: undo(self.core.functions.always_on_top_toggle)())
|
||
mc.menuItem(rp='S', l='在非活动集合上自动隐藏曲线', cb=self.options_manager.get('AutoHideCurvesOnInactiveCollections'), c=undo(self.core.layer_manager.collection_visibility_toggle))
|
||
geo_filter = Button(row.layout(), 'gsGeoFilter')
|
||
geo_filter.set_button_style('small-filled')
|
||
geo_filter.set_label('几何体', line_height=100)
|
||
geo_filter.clicked.connect(partial(undo(self.core.layer_manager.layers_filter_toggle), False, True, ignore=['Shift+Ctrl']))
|
||
color_mode = Button(row.layout(), 'colorMode')
|
||
color_mode.set_button_style('small-filled')
|
||
color_mode.setCheckable(True)
|
||
color_mode.setChecked(False)
|
||
color_mode.set_label('颜色', line_height=100)
|
||
color_mode.clicked.connect(undo(self.core.color_mode.toggle_color_vis))
|
||
mc.popupMenu(mm=1, p=color_mode.objectName())
|
||
mc.menuItem(rp='N', l='随机化颜色', c=lambda *_: undo(self.core.color_mode.randomize_colors)())
|
||
mc.menuItem(rp='E', l='重置曲线颜色', c=lambda *_: self.core.color_mode.reset_curve_colors())
|
||
mc.menuItem(rp='W', l='应用曲线颜色', c=lambda *_: self.core.color_mode.sync_curve_colors(True))
|
||
mc.menuItem(rp='S', l='自定义颜色窗口', c=lambda *_: self.custom_layer_colors_window.window())
|
||
with Layout(scroll_layout, obj_name='LayerLayout') as layer_layout:
|
||
layer_button_grp = QtWidgets.QButtonGroup(layer_layout)
|
||
layer_button_grp.setObjectName(get_unique_name('LayerGroup'))
|
||
layer_button_grp.setExclusive(True)
|
||
self.widget_manager.add('LayerGroup', layer_button_grp)
|
||
with Row(layer_layout.layout(), 'layerRow0', spacing=0) as row:
|
||
for i in range(10):
|
||
layer_button_grp.addButton(self.selection_sets(i, row.layout(), str(i)))
|
||
with Row(layer_layout.layout(), 'layerRow1', spacing=0) as row:
|
||
letter = ord('A')
|
||
letters = [chr(i) for i in range(letter, letter + 10)]
|
||
if self.widget_manager.get('layerNumbersOnly').isChecked():
|
||
letters = list(range(10, 20))
|
||
for i in range(10):
|
||
layer_button_grp.addButton(self.selection_sets(i + 10, row.layout(), str(letters[i])))
|
||
with Row(layer_layout.layout(), 'layerRow2', spacing=0) as row:
|
||
for i in range(10):
|
||
layer_button_grp.addButton(self.selection_sets(i + 20, row.layout(), str(i + 20)))
|
||
self.widget_manager.get('layerRow2').setHidden(True)
|
||
with Row(layer_layout.layout(), 'layerRow3', spacing=0) as row:
|
||
for i in range(10):
|
||
layer_button_grp.addButton(self.selection_sets(i + 30, row.layout(), str(i + 30)))
|
||
self.widget_manager.get('layerRow3').setHidden(True)
|
||
with Row(layer_layout.layout(), 'layerRow4', spacing=0) as row:
|
||
for i in range(10):
|
||
layer_button_grp.addButton(self.selection_sets(i + 40, row.layout(), str(i + 40)))
|
||
self.widget_manager.get('layerRow4').setHidden(True)
|
||
with Row(layer_layout.layout(), 'layerRow5', spacing=0) as row:
|
||
for i in range(10):
|
||
layer_button_grp.addButton(self.selection_sets(i + 50, row.layout(), str(i + 50)))
|
||
self.widget_manager.get('layerRow5').setHidden(True)
|
||
with Row(layer_layout.layout(), 'layerRow6', spacing=0) as row:
|
||
for i in range(10):
|
||
layer_button_grp.addButton(self.selection_sets(i + 60, row.layout(), str(i + 60)))
|
||
self.widget_manager.get('layerRow6').setHidden(True)
|
||
with Row(layer_layout.layout(), 'layerRow7', spacing=0) as row:
|
||
for i in range(10):
|
||
layer_button_grp.addButton(self.selection_sets(i + 70, row.layout(), str(i + 70)))
|
||
self.widget_manager.get('layerRow7').setHidden(True)
|
||
self.widget_manager.get('curveGrp0').setChecked(True)
|
||
with Row(scroll_layout) as row:
|
||
extract_selected = Button(row.layout(), 'gsExtractSelected')
|
||
extract_selected.set_label('提取<br>所选')
|
||
extract_selected.set_icon('mod-bottom')
|
||
extract_selected.clicked.connect(undo(self.core.functions.extract_selected_curves))
|
||
extract_all = Button(row.layout(), 'gsExtractAll')
|
||
extract_all.set_label('提取<br>全部')
|
||
extract_all.set_icon('mod-bottom')
|
||
extract_all.clicked.connect(undo(self.core.functions.extract_all_curves))
|
||
scroll_layout.addWidget(separator())
|
||
with Row(scroll_layout) as row:
|
||
select_curve = Button(row.layout(), 'gsSelectCurve')
|
||
select_curve.set_label('选择<br>曲线')
|
||
select_curve.clicked.connect(partial(undo(self.core.utils.select_part), 1))
|
||
select_geo = Button(row.layout(), 'gsSelectGeo')
|
||
select_geo.set_label('选择<br>几何体')
|
||
select_geo.clicked.connect(partial(undo(self.core.utils.select_part), 2))
|
||
select_group = Button(row.layout(), 'gsSelectGroup')
|
||
select_group.set_label('选择<br>组')
|
||
select_group.clicked.connect(partial(undo(self.core.utils.select_part), 0))
|
||
with Row(scroll_layout) as row:
|
||
group_curves = Button(row.layout(), 'gsGroupCurves')
|
||
group_curves.set_label('分组<br>曲线')
|
||
group_curves.clicked.connect(undo(self.core.functions.group_curves))
|
||
regroup_by_layer = Button(row.layout(), 'gsRegroupByLayer')
|
||
regroup_by_layer.set_label('按图层<br>重新分组')
|
||
regroup_by_layer.clicked.connect(undo(self.core.functions.regroup_by_layer))
|
||
group_name = LineEdit('gsGroupNameTextField', scroll_layout)
|
||
group_name.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)
|
||
group_name.set_auto_format(True)
|
||
group_name.setClearButtonEnabled(True)
|
||
group_name.setPlaceholderText('组名称')
|
||
custom_layer_names_colors = Button(scroll_layout, 'gsCustomLayerNamesAndColors')
|
||
custom_layer_names_colors.set_button_style('small-filled')
|
||
custom_layer_names_colors.set_label('图层名称和颜色')
|
||
custom_layer_names_colors.clicked.connect(self.custom_layer_colors_window.window)
|
||
scroll_layout.addWidget(separator())
|
||
scroll_layout.addWidget(wrap_control(mc.text(l='选择控制点')))
|
||
slider_widget = wrap_control(mc.floatSliderGrp('gsSelectCVSlider', w=1, min=0, max=1, step=0.05, dc=self.core.sliders.select_cv_slider, cc=self.core.sliders.release))
|
||
self.widget_manager.add('gsSelectCVSlider', slider_widget)
|
||
scroll_layout.addWidget(slider_widget)
|
||
with Row(scroll_layout) as row:
|
||
transfer_attributes = Button(row.layout(), 'gsTransferAttributes')
|
||
transfer_attributes.set_label('转移<br>属性.')
|
||
|
||
transfer_attributes.set_icon('mod-bottom')
|
||
transfer_attributes.clicked.connect(undo(self.core.attributes.transfer_attributes))
|
||
mc.popupMenu(mm=1, p=transfer_attributes.objectName())
|
||
mc.menuItem('gsCopyAttributes', rp='N', l='复制属性', aob=1, c=lambda _: self.core.attributes.copy_attributes())
|
||
mc.menuItem(ob=1, c=lambda _: self.attributes_filter_window.open_ui())
|
||
mc.menuItem('gsPasteAttributes', rp='S', l='粘贴属性', aob=1, c=lambda _: self.core.attributes.paste_attributes())
|
||
mc.menuItem(ob=1, c=lambda _: self.attributes_filter_window.open_ui())
|
||
transfer_uvs = Button(row.layout(), 'gsTransferUVs')
|
||
transfer_uvs.set_label('转移\nUV')
|
||
transfer_uvs.set_icon('mod-bottom')
|
||
transfer_uvs.clicked.connect(undo(self.core.attributes.transfer_uvs))
|
||
mc.popupMenu(mm=1, p=transfer_uvs.objectName())
|
||
mc.menuItem('gsCopyUVs', aob=1, rp='N', l='复制UV', c=lambda _: self.core.attributes.copy_uvs())
|
||
mc.menuItem(ob=1, c=lambda _: self.attributes_filter_window.open_ui())
|
||
mc.menuItem('gsPasteUVs', aob=1, rp='S', l='粘贴UV', c=lambda _: self.core.attributes.paste_uvs())
|
||
mc.menuItem(ob=1, c=lambda _: self.attributes_filter_window.open_ui())
|
||
reset_pivot = Button(row.layout(), 'gsResetPivot')
|
||
reset_pivot.set_label('重置\n轴心点')
|
||
reset_pivot.clicked.connect(undo(self.core.functions.reset_curve_pivot_point))
|
||
reset_pivot.set_icon('mod-bottom')
|
||
mc.popupMenu(mm=1, p=reset_pivot.objectName())
|
||
mc.menuItem('gsResetPivotToRoot', rp='N', l='重置到根部', c=lambda _: self.core.functions.reset_curve_pivot_point())
|
||
mc.menuItem('gsResetPivotToTip', rp='S', l='重置到尖端', c=lambda _: self.core.functions.reset_curve_pivot_point(2))
|
||
scroll_layout.addWidget(separator())
|
||
|
||
def rebuild_slider_release():
|
||
self.core.sliders.rebuild_slider_release()
|
||
self.core.sliders.release()
|
||
|
||
def rebuild_button_clicked():
|
||
self.core.sliders.rebuild_slider_drag()
|
||
rebuild_slider_release()
|
||
with Row(scroll_layout, margins=style.scale([1.5, 0, 1.5, 0])) as rebuild_reset_row:
|
||
rebuild_button = Button(obj_name='gsRebuildWithCurrentValue')
|
||
rebuild_button.set_button_style('small-filled')
|
||
rebuild_button.set_label('R', line_height=100)
|
||
rebuild_button.setMinimumWidth(1)
|
||
rebuild_button.setMaximumSize(*style.scale([16, 16]))
|
||
rebuild_button.clicked.connect(rebuild_button_clicked)
|
||
reset_button = Button(obj_name='gsResetRebuildSliderRange')
|
||
reset_button.set_button_style('small-filled')
|
||
reset_button.set_icon('reset')
|
||
reset_button.setMinimumWidth(1)
|
||
reset_button.setMaximumSize(*style.scale([16, 16]))
|
||
reset_button.clicked.connect(lambda: mc.intSliderGrp('gsRebuildSlider', e=1, min=1, max=50))
|
||
rrr = rebuild_reset_row.layout()
|
||
if isinstance(rrr, QHBoxLayout):
|
||
rrr.addWidget(rebuild_button, 1)
|
||
rrr.addWidget(wrap_control(mc.text(l='重建曲线')), 3)
|
||
rrr.addWidget(reset_button, 1)
|
||
rebuild_curve_slider = wrap_control(mc.intSliderGrp('gsRebuildSlider', f=1, cw=[(1, 32), (2, 28)], min=1, max=50, fmx=999, v=1, dc=self.core.sliders.rebuild_slider_drag, cc=lambda *_: rebuild_slider_release()))
|
||
self.widget_manager.add('gsRebuildSlider', rebuild_curve_slider)
|
||
scroll_layout.addWidget(rebuild_curve_slider)
|
||
with Row(scroll_layout) as row:
|
||
duplicate_curve = Button(row.layout(), 'gsDuplicateCurve')
|
||
duplicate_curve.set_label('复制')
|
||
duplicate_curve.clicked.connect(undo(self.core.functions.duplicate_curve))
|
||
randomize_curve = Button(row.layout(), 'gsRandomizeCurve')
|
||
randomize_curve.set_label('随机化')
|
||
randomize_curve.clicked.connect(self.randomize_curve_window.open_ui)
|
||
with Row(scroll_layout) as row:
|
||
extend_curve = Button(row.layout(), 'gsExtendCurve')
|
||
extend_curve.set_label('延伸')
|
||
extend_curve.clicked.connect(undo(self.core.functions.extend_curve))
|
||
reduce_curve = Button(row.layout(), 'gsReduceCurve')
|
||
reduce_curve.set_label('缩减')
|
||
reduce_curve.clicked.connect(undo(self.core.functions.reduce_curve))
|
||
with Row(scroll_layout) as row:
|
||
smooth = Button(row.layout(), 'gsSmooth')
|
||
smooth.set_label('平滑')
|
||
smooth.clicked.connect(undo(self.core.functions.smooth_curve))
|
||
smooth.set_icon('marking-top')
|
||
mc.popupMenu(mm=1, p=smooth.objectName())
|
||
mc.radioMenuItemCollection()
|
||
mc.menuItem('gsSmoothMult1', rp='N', rb=1, l='x1')
|
||
mc.menuItem('gsSmoothMult3', rp='E', rb=0, l='x3')
|
||
mc.menuItem('gsSmoothMult5', rp='S', rb=0, l='x5')
|
||
mc.menuItem('gsSmoothMult10', rp='W', rb=0, l='x10')
|
||
factor_slider = wrap_control(mc.floatSliderGrp('gsFactorSlider', l='因子', adj=3, w=1, cw=[(1, 32), (2, 28)], min=1, max=100))
|
||
self.widget_manager.add('gsFactorSlider', factor_slider)
|
||
scroll_layout.addWidget(factor_slider)
|
||
scroll_layout.addWidget(separator())
|
||
with Frame(scroll_layout, obj_name='MirrorFrame', label='镜像', margins=[1, 1, 1, 1]) as frame:
|
||
with Row(frame.get_frame_layout()) as row:
|
||
mirror_x = Button(row.layout(), 'mirrorX')
|
||
mirror_x.set_label('X')
|
||
mirror_x.set_font_size(16)
|
||
mirror_x.clicked.connect(partial(undo(self.core.functions.mirror_hair), 0))
|
||
mirror_y = Button(row.layout(), 'mirrorY')
|
||
mirror_y.set_label('Y')
|
||
mirror_y.set_font_size(16)
|
||
mirror_y.clicked.connect(partial(undo(self.core.functions.mirror_hair), 1))
|
||
mirror_z = Button(row.layout(), 'mirrorZ')
|
||
mirror_z.set_label('Z')
|
||
mirror_z.set_font_size(16)
|
||
mirror_z.clicked.connect(partial(undo(self.core.functions.mirror_hair), 2))
|
||
with Row(frame.get_frame_layout()) as row:
|
||
mirror_flip_grp = QtWidgets.QButtonGroup(row)
|
||
mirror = Button(row.layout(), 'mirrorRadio')
|
||
mirror.set_label('镜像')
|
||
mirror.set_button_style('small')
|
||
mirror.setCheckable(True)
|
||
mirror.setChecked(True)
|
||
flip = Button(row.layout(), 'flipRadio')
|
||
flip.set_label('翻转')
|
||
flip.set_button_style('small')
|
||
flip.setCheckable(True)
|
||
mirror_flip_grp.addButton(mirror)
|
||
mirror_flip_grp.addButton(flip)
|
||
scroll_layout.addWidget(separator())
|
||
with Row(scroll_layout) as row:
|
||
control_curve = Button(row.layout(), 'gsControlCurve')
|
||
control_curve.set_label('控制曲线')
|
||
control_curve.clicked.connect(undo(self.core.functions.control_curve_create))
|
||
apply_control_curve = Button(row.layout(), 'gsApplyControlCurve')
|
||
apply_control_curve.set_label('应用')
|
||
apply_control_curve.setFixedWidth(style.scale(48))
|
||
apply_control_curve.clicked.connect(undo(self.core.functions.control_curve_apply))
|
||
scroll_layout.addWidget(separator())
|
||
with Row(scroll_layout) as row:
|
||
curve_control_window = Button(row.layout(), 'gsCurveControlWindow')
|
||
curve_control_window.set_label('曲线控制窗口')
|
||
curve_control_window.pressed.connect(self.curve_control_window.open_ui)
|
||
scroll_layout.addWidget(separator())
|
||
with Row(scroll_layout) as row:
|
||
uv_editor = Button(row.layout(), 'gsUVEditorMain')
|
||
uv_editor.set_label('UV编辑器窗口')
|
||
uv_editor.pressed.connect(self.uv_editor.open_ui)
|
||
scroll_layout.addWidget(separator())
|
||
scroll_layout.addWidget(wrap_control(mc.text(l=VERSION)))
|
||
warp_switch.setChecked(self.options_manager.get('warpSwitch'))
|
||
extrude_switch.setChecked(not self.options_manager.get('warpSwitch'))
|
||
self.core.layer_manager.layer_collections.toggle_widget()
|
||
self.tooltips.toggle_custom_tooltips_main(self.options_manager.get('enableTooltips'))
|
||
|
||
def selection_sets(self, i, layout, label):
|
||
def toggle_geometry_edit(*_):
|
||
self.core.layer_manager.curve_geometry_edit_toggle(i)
|
||
self.core.updates.update_main_ui()
|
||
|
||
def toggle_curve_visibility(*_):
|
||
self.core.layer_manager.toggle_obj_visibility(i, 0)
|
||
self.core.updates.update_main_ui()
|
||
|
||
def toggle_geo_visibility(*_):
|
||
self.core.layer_manager.toggle_obj_visibility(i, 1)
|
||
self.core.updates.update_main_ui()
|
||
|
||
def toggle_layer_visibility(*_):
|
||
self.core.layer_manager.toggle_layer_visibility(i)
|
||
self.core.updates.update_main_ui()
|
||
sel_set = Layer(layout=layout, obj_name='curveGrp%s' % i)
|
||
sel_set.setStyleSheet(style.layer())
|
||
sel_set.set_label(str(label))
|
||
mc.popupMenu(mm=1, p=sel_set.objectName())
|
||
mc.menuItem(rp='N', l='将所选内容添加到图层', c=lambda _: self.core.layer_manager.curve_add_to_layer(i))
|
||
mc.menuItem(rp='NW', l='提取几何体', c=lambda _: self.core.functions.extract_curve_geo(i))
|
||
mc.menuItem(rp='NE', l='切换几何体编辑', c=toggle_geometry_edit)
|
||
mc.menuItem(rp='W', l='选择曲线', c=lambda _: self.core.layer_manager.curve_layer_select_obj(i, 0))
|
||
mc.menuItem(rp='E', l='选择几何体', c=lambda _: self.core.layer_manager.curve_layer_select_obj(i, 1))
|
||
mc.menuItem(rp='SW', l='切换曲线可见性', c=toggle_curve_visibility)
|
||
mc.menuItem(rp='SE', l='切换几何体可见性', c=toggle_geo_visibility)
|
||
mc.menuItem(rp='S', l='切换图层可见性', c=toggle_layer_visibility)
|
||
sel_set.clicked.connect(partial(undo(self.core.layer_manager.layer_clicked), i))
|
||
return sel_set
|
||
|
||
def extrude_warp_toggle(self):
|
||
"""Toggle the extrude/warp switch"""
|
||
buttons = ['newCard', 'newTube', 'curveCard', 'curveTube', 'addCards', 'addTubes']
|
||
button_style = style.BUTTON_NORMAL
|
||
if self.widget_manager.get('extrudeSwitch').isChecked():
|
||
button_style = style.BUTTON_NORMAL_BLUE_BORDER
|
||
for button in buttons:
|
||
self.widget_manager.get(button).setStyleSheet(button_style)
|
||
|
||
def update_layer_list(self):
|
||
"""Update the layer list"""
|
||
if self.widget_manager.exists('gsLayerSelector'):
|
||
self.widget_manager.get('gsLayerSelector').updateLayerList()
|
||
self.core.curve_control.update_ui()
|
||
|
||
def toggle_tooltips(self):
|
||
"""Toggle the custom tooltips"""
|
||
for widget in self.widget_manager.get_widgets():
|
||
if hasattr(widget, 'enable_tooltip') and callable(getattr(widget, 'enable_tooltip')):
|
||
widget.enable_tooltip(self.options_manager.get('enableTooltips'))
|
||
self.tooltips.toggle_custom_tooltips_main(self.options_manager.get('enableTooltips'))
|
||
self.tooltips.toggle_custom_tooltips_curve_control(self.options_manager.get('enableTooltips'))
|
||
self.tooltips.toggle_custom_tooltips_scale_factor(self.options_manager.get('enableTooltips')) |