hydrus/hydrus/client/gui/ClientGUIScrolledPanels.py

249 lines
7.0 KiB
Python

from qtpy import QtCore as QC
from qtpy import QtWidgets as QW
from qtpy import QtGui as QG
from hydrus.client import ClientApplicationCommand as CAC
from hydrus.client import ClientConstants as CC
from hydrus.client.gui import ClientGUIShortcuts
from hydrus.client.gui import ClientGUITopLevelWindows
from hydrus.client.gui import QtPorting as QP
class ResizingEventFilter( QC.QObject ):
def eventFilter( self, watched, event ):
if event.type() == QC.QEvent.Resize:
parent = self.parent()
if isinstance( parent, ResizingScrolledPanel ):
# weird hack fix for a guy who was getting QPaintEvents in here
if not hasattr( event, 'oldSize' ):
return False
old_size = event.oldSize()
size = event.size()
width_larger = size.width() > old_size.width() and size.height() >= old_size.height()
height_larger = size.width() >= old_size.width() and size.height() > old_size.height()
if width_larger or height_larger:
QP.CallAfter( parent.WidgetJustSized, width_larger, height_larger )
return False
class ResizingScrolledPanel( QW.QScrollArea ):
okSignal = QC.Signal()
def __init__( self, parent ):
QW.QScrollArea.__init__( self, parent )
self.setWidget( QW.QWidget( self ) )
self.setWidgetResizable( True )
self.widget().installEventFilter( ResizingEventFilter( self ) )
def _OKParent( self ):
self.okSignal.emit()
def CheckValid( self ):
pass
def CleanBeforeDestroy( self ):
pass
def sizeHint( self ):
if self.widget():
# just as a fun note, QScrollArea does a 12 x 8 character height sizeHint on its own here due to as-yet invalid widget size, wew lad
frame_width = self.frameWidth()
frame_size = QC.QSize( frame_width * 2, frame_width * 2 )
size_hint = self.widget().sizeHint() + frame_size
#visible_size = self.widget().visibleRegion().boundingRect().size()
#size_hint = self.widget().sizeHint() + self.size() - visible_size
available_screen_size = QW.QApplication.desktop().availableGeometry( self ).size()
screen_fill_factor = 0.85 # don't let size hint be bigger than this percentage of the available screen width/height
if size_hint.width() > screen_fill_factor * available_screen_size.width():
size_hint.setWidth( screen_fill_factor * available_screen_size.width() )
if size_hint.height() > screen_fill_factor * available_screen_size.height():
size_hint.setHeight( screen_fill_factor * available_screen_size.height() )
return size_hint
else:
return QW.QScrollArea.sizeHint( self )
def UserIsOKToOK( self ):
return True
def UserIsOKToCancel( self ):
return True
def WidgetJustSized( self, width_larger, height_larger ):
widget_minimum_size_hint = self.widget().minimumSizeHint()
widget_normal_size_hint = self.widget().sizeHint()
widget_size_hint = QC.QSize( max( widget_minimum_size_hint.width(), widget_normal_size_hint.width() ), max( widget_minimum_size_hint.height(), widget_normal_size_hint.height() ) )
my_size = self.size()
width_increase = 0
height_increase = 0
# + 2 because it is late and that seems to stop scrollbars lmao
if width_larger:
width_increase = max( 0, widget_size_hint.width() - my_size.width() + 2 )
if height_larger:
height_increase = max( 0, widget_size_hint.height() - my_size.height() + 2 )
if width_increase > 0 or height_increase > 0:
window = self.window()
if isinstance( window, ( ClientGUITopLevelWindows.DialogThatResizes, ClientGUITopLevelWindows.FrameThatResizes ) ):
desired_size_delta = QC.QSize( width_increase, height_increase )
ClientGUITopLevelWindows.ExpandTLWIfPossible( window, window._frame_key, desired_size_delta )
class EditPanel( ResizingScrolledPanel ):
def GetValue( self ):
raise NotImplementedError()
def CheckValid( self ):
# raises veto if not valid
self.GetValue()
class EditSingleCtrlPanel( EditPanel ):
def __init__( self, parent, ok_on_these_commands = None ):
EditPanel.__init__( self, parent )
self._control = None
if ok_on_these_commands is None:
ok_on_these_commands = set()
self._ok_on_these_commands = set( ok_on_these_commands )
#
self._vbox = QP.VBoxLayout( margin = 0 )
self.widget().setLayout( self._vbox )
self._my_shortcuts_handler = ClientGUIShortcuts.ShortcutsHandler( self, [ 'media' ] )
def GetValue( self ):
if hasattr( self._control, 'GetValue' ):
return self._control.GetValue()
elif hasattr( self._control, 'toPlainText' ):
return self._control.toPlainText()
return self._control.value()
def ProcessApplicationCommand( self, command: CAC.ApplicationCommand ):
command_processed = True
if command.IsSimpleCommand():
action = command.GetSimpleAction()
if action in self._ok_on_these_commands:
self._OKParent()
else:
command_processed = False
else:
command_processed = False
return command_processed
def SetControl( self, control ):
self._control = control
QP.AddToLayout( self._vbox, control, CC.FLAGS_EXPAND_BOTH_WAYS )
class ManagePanel( ResizingScrolledPanel ):
def CommitChanges( self ):
raise NotImplementedError()
class ReviewPanel( ResizingScrolledPanel ):
pass