253 lines
6.7 KiB
Python
253 lines
6.7 KiB
Python
import os
|
|
import typing
|
|
|
|
from qtpy import QtCore as QC
|
|
from qtpy import QtWidgets as QW
|
|
|
|
from hydrus.core import HydrusGlobals as HG
|
|
from hydrus.core import HydrusExceptions
|
|
|
|
from hydrus.client import ClientConstants as CC
|
|
from hydrus.client.gui import ClientGUICore as CGC
|
|
from hydrus.client.gui import ClientGUIMenus
|
|
from hydrus.client.gui.widgets import ClientGUICommon
|
|
|
|
class MenuMixin( object ):
|
|
|
|
def __init__( self, menu_items ):
|
|
|
|
self._menu_items = menu_items
|
|
|
|
|
|
def _PopulateMenu( self, menu, menu_items ):
|
|
|
|
for ( item_type, title, description, data ) in menu_items:
|
|
|
|
if item_type == 'normal':
|
|
|
|
func = data
|
|
|
|
ClientGUIMenus.AppendMenuItem( menu, title, description, func )
|
|
|
|
elif item_type == 'check':
|
|
|
|
check_manager = data
|
|
|
|
current_value = check_manager.GetCurrentValue()
|
|
func = check_manager.Invert
|
|
|
|
if current_value is not None:
|
|
|
|
ClientGUIMenus.AppendMenuCheckItem( menu, title, description, current_value, func )
|
|
|
|
|
|
elif item_type == 'separator':
|
|
|
|
ClientGUIMenus.AppendSeparator( menu )
|
|
|
|
elif item_type == 'submenu':
|
|
|
|
submenu = QW.QMenu( menu )
|
|
|
|
self._PopulateMenu( submenu, data )
|
|
|
|
ClientGUIMenus.AppendMenu( menu, submenu, title )
|
|
|
|
elif item_type == 'label':
|
|
|
|
ClientGUIMenus.AppendMenuLabel( menu, title, description = description )
|
|
|
|
|
|
|
|
|
|
def _SetMenuItems( self, menu_items ):
|
|
|
|
self._menu_items = menu_items
|
|
|
|
|
|
class MenuBitmapButton( MenuMixin, ClientGUICommon.BetterBitmapButton ):
|
|
|
|
def __init__( self, parent, bitmap, menu_items ):
|
|
|
|
MenuMixin.__init__( self, menu_items )
|
|
ClientGUICommon.BetterBitmapButton.__init__( self, parent, bitmap, self.DoMenu )
|
|
|
|
|
|
def DoMenu( self ):
|
|
|
|
menu = QW.QMenu()
|
|
|
|
self._PopulateMenu( menu, self._menu_items )
|
|
|
|
CGC.core().PopupMenu( self, menu )
|
|
|
|
|
|
def SetMenuItems( self, menu_items ):
|
|
|
|
MenuMixin._SetMenuItems( self, menu_items )
|
|
|
|
|
|
class MenuButton( MenuMixin, ClientGUICommon.BetterButton ):
|
|
|
|
def __init__( self, parent, label, menu_items ):
|
|
|
|
MenuMixin.__init__( self, menu_items )
|
|
ClientGUICommon.BetterButton.__init__( self, parent, label, self.DoMenu )
|
|
|
|
|
|
def DoMenu( self ):
|
|
|
|
menu = QW.QMenu()
|
|
|
|
self._PopulateMenu( menu, self._menu_items )
|
|
|
|
CGC.core().PopupMenu( self, menu )
|
|
|
|
|
|
def SetMenuItems( self, menu_items ):
|
|
|
|
MenuMixin._SetMenuItems( self, menu_items )
|
|
|
|
|
|
class MenuChoiceButton( MenuMixin, ClientGUICommon.BetterButton ):
|
|
|
|
valueChanged = QC.Signal()
|
|
|
|
def __init__( self, parent, choice_tuples ):
|
|
|
|
self._choice_tuples = list( choice_tuples )
|
|
self._value_index = None if len( self._choice_tuples ) == 0 else 0
|
|
|
|
label = self._GetCurrentDisplayString()
|
|
|
|
menu_items = self._GenerateMenuItems()
|
|
|
|
MenuMixin.__init__( self, menu_items )
|
|
ClientGUICommon.BetterButton.__init__( self, parent, label, self.DoMenu )
|
|
|
|
|
|
def _GenerateMenuItems( self ):
|
|
|
|
menu_items = []
|
|
|
|
for ( value_index, ( display_string, data ) ) in enumerate( self._choice_tuples ):
|
|
|
|
check_manager = self._GetCheckManager( value_index )
|
|
|
|
menu_items.append( ( 'check', display_string, display_string, check_manager ) )
|
|
|
|
|
|
return menu_items
|
|
|
|
|
|
def _GetCheckManager( self, value_index ):
|
|
|
|
# in a sub-call so lambda works
|
|
|
|
check_manager = ClientGUICommon.CheckboxManagerCalls( lambda: self._SetValueIndex( value_index ), lambda: self._value_index == value_index )
|
|
|
|
return check_manager
|
|
|
|
|
|
def _GetCurrentDisplayString( self ):
|
|
|
|
if self._value_index is None:
|
|
|
|
return ''
|
|
|
|
|
|
return self._choice_tuples[ self._value_index ][0]
|
|
|
|
|
|
def _SetValueIndex( self, value_index ):
|
|
|
|
self._value_index = value_index
|
|
|
|
display_string = self._GetCurrentDisplayString()
|
|
|
|
self.setText( display_string )
|
|
|
|
self.valueChanged.emit()
|
|
|
|
self.setEnabled( self._value_index is not None )
|
|
|
|
|
|
def DoMenu( self ):
|
|
|
|
menu = QW.QMenu()
|
|
|
|
self._PopulateMenu( menu, self._menu_items )
|
|
|
|
CGC.core().PopupMenu( self, menu )
|
|
|
|
|
|
def GetChoiceTuples( self ):
|
|
|
|
return list( self._choice_tuples )
|
|
|
|
|
|
def GetValue( self ):
|
|
|
|
if self._value_index is None:
|
|
|
|
return None
|
|
|
|
|
|
return self._choice_tuples[ self._value_index ][1]
|
|
|
|
|
|
def SetChoiceTuples( self, choice_tuples ):
|
|
|
|
self._choice_tuples = choice_tuples
|
|
|
|
menu_items = self._GenerateMenuItems()
|
|
|
|
MenuMixin._SetMenuItems( self, menu_items )
|
|
|
|
if len( menu_items ) == 0:
|
|
|
|
self._SetValueIndex( None )
|
|
|
|
else:
|
|
|
|
self._SetValueIndex( 0 )
|
|
|
|
|
|
|
|
def SetValue( self, data ):
|
|
|
|
for ( value_index, ( display_string, existing_data ) ) in enumerate( self._choice_tuples ):
|
|
|
|
if data == existing_data:
|
|
|
|
self._SetValueIndex( value_index )
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
def wheelEvent( self, event ):
|
|
|
|
can_do_it = HG.client_controller.new_options.GetBoolean( 'menu_choice_buttons_can_mouse_scroll' )
|
|
|
|
if self._value_index is not None and can_do_it:
|
|
|
|
if event.angleDelta().y() > 0:
|
|
|
|
index_delta = -1
|
|
|
|
else:
|
|
|
|
index_delta = 1
|
|
|
|
|
|
new_value_index = ( self._value_index + index_delta ) % len( self._choice_tuples )
|
|
|
|
self._SetValueIndex( new_value_index )
|
|
|
|
|
|
event.accept()
|
|
|
|
|