mirror of
https://github.com/LorenEteval/Furious.git
synced 2026-10-04 21:08:04 +03:00
Replace editor checkboxes with Fluent switches
Signed-off-by: Loren Eteval <loren.eteval@proton.me>
This commit is contained in:
@@ -29,7 +29,7 @@ from Furious.Qt import (
|
||||
GuiEditorItemBasicRemark,
|
||||
GuiEditorItemProxyHttp,
|
||||
GuiEditorItemProxySocks,
|
||||
GuiEditorItemTextCheckBox,
|
||||
GuiEditorItemTextSwitch,
|
||||
GuiEditorItemTextSpinBox,
|
||||
GuiEditorWidgetQDialog,
|
||||
GuiEditorWidgetQGroupBox,
|
||||
@@ -290,7 +290,7 @@ class ExternalCoreShutdownTimeoutInput(GuiEditorItemTextSpinBox):
|
||||
self.setValue(value if isinstance(value, int) else 5)
|
||||
|
||||
|
||||
class ExternalCoreApplicationTun2socksInput(GuiEditorItemTextCheckBox):
|
||||
class ExternalCoreApplicationTun2socksInput(GuiEditorItemTextSwitch):
|
||||
"""Bind this profile's host-managed tun2socks participation flag."""
|
||||
|
||||
def __init__(self):
|
||||
|
||||
@@ -188,7 +188,7 @@ class GuiHy1ItemSpeedDownMbps(GuiEditorItemTextSpinBox):
|
||||
self.setValue(96)
|
||||
|
||||
|
||||
class GuiHy1ItemTLSInsecure(GuiEditorItemTextCheckBox):
|
||||
class GuiHy1ItemTLSInsecure(GuiEditorItemTextSwitch):
|
||||
"""Represent GUI hy1 item TLS insecure."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
@@ -607,7 +607,7 @@ class GuiHy2ItemTLSTextInput(GuiEditorItemTextInput):
|
||||
self.setText(value)
|
||||
|
||||
|
||||
class GuiHy2ItemTLSInsecure(GuiEditorItemTextCheckBox):
|
||||
class GuiHy2ItemTLSInsecure(GuiEditorItemTextSwitch):
|
||||
"""Represent GUI hy2 item TLS insecure."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
@@ -374,7 +374,7 @@ class GuiVTLSItemTLSXXXTextInput(GuiEditorItemTextInput):
|
||||
self.setText('')
|
||||
|
||||
|
||||
class GuiVTLSItemTLSAllowInsecure(GuiEditorItemTextCheckBox):
|
||||
class GuiVTLSItemTLSAllowInsecure(GuiEditorItemTextSwitch):
|
||||
"""Represent GUI vtls item TLS allow insecure."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
@@ -34,7 +34,7 @@ __all__ = [
|
||||
'GuiEditorItemTextInput',
|
||||
'GuiEditorItemTextSpinBox',
|
||||
'GuiEditorItemTextComboBox',
|
||||
'GuiEditorItemTextCheckBox',
|
||||
'GuiEditorItemTextSwitch',
|
||||
'GuiEditorItemBasicRemark',
|
||||
'GuiEditorItemProxyHttp',
|
||||
'GuiEditorItemProxySocks',
|
||||
@@ -146,18 +146,22 @@ class GuiEditorItemTextComboBox(EditorWidgetBinding):
|
||||
return self._title, self._input
|
||||
|
||||
|
||||
class GuiEditorItemTextCheckBox(EditorWidgetBinding):
|
||||
"""Represent GUI editor item text check box."""
|
||||
class GuiEditorItemTextSwitch(EditorWidgetBinding):
|
||||
"""Represent one labeled, compact Fluent switch in an editor form."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the GuiEditorItemTextCheckBox."""
|
||||
"""Initialize the editor label and its form-sized switch."""
|
||||
title = kwargs.pop('title', '')
|
||||
translatable = kwargs.pop('translatable', True)
|
||||
parent = kwargs.pop('parent', None)
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self._input = AppQCheckBox(_(title), translatable=translatable, parent=parent)
|
||||
if translatable:
|
||||
title = _(title)
|
||||
|
||||
self._title = AppQLabel(title, translatable=translatable, parent=parent)
|
||||
self._input = AppQSwitch(parent=parent, compact=True)
|
||||
|
||||
def isChecked(self) -> bool:
|
||||
"""Return whether checked."""
|
||||
@@ -169,7 +173,7 @@ class GuiEditorItemTextCheckBox(EditorWidgetBinding):
|
||||
|
||||
def widgets(self):
|
||||
"""Return the widgets owned by this editor item."""
|
||||
return (self._input,)
|
||||
return self._title, self._input
|
||||
|
||||
|
||||
class GuiEditorItemBasicRemark(GuiEditorItemTextInput):
|
||||
|
||||
+3
-15
@@ -36,7 +36,6 @@ import functools
|
||||
|
||||
__all__ = [
|
||||
'moveToCenter',
|
||||
'AppQCheckBox',
|
||||
'AppQSwitch',
|
||||
'AppQComboBox',
|
||||
'AppQComboBoxSeparatorDelegate',
|
||||
@@ -88,31 +87,20 @@ def moveToCenter(widget, parent=None):
|
||||
widget.move(geometry.topLeft())
|
||||
|
||||
|
||||
class AppQCheckBox(Mixins.QTranslatable, QCheckBox):
|
||||
"""Represent app q check box."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the AppQCheckBox."""
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def retranslate(self):
|
||||
"""Refresh translated text for the app q check box."""
|
||||
self.setText(_(self.text()))
|
||||
|
||||
|
||||
class AppQSwitch(Mixins.ThemeAware, QCheckBox):
|
||||
"""Paint one compact, animated Fluent-style binary switch."""
|
||||
|
||||
ControlSize = QtCore.QSize(38, 22)
|
||||
CompactControlSize = QtCore.QSize(34, 20)
|
||||
AnimationDuration = 160
|
||||
|
||||
def __init__(self, parent=None):
|
||||
def __init__(self, parent=None, *, compact=False):
|
||||
"""Initialize the reusable switch and its owned thumb animation."""
|
||||
super().__init__(parent)
|
||||
|
||||
self.setObjectName('SettingsToggle')
|
||||
self.setCursor(QtCore.Qt.CursorShape.PointingHandCursor)
|
||||
self.setFixedSize(self.ControlSize)
|
||||
self.setFixedSize(self.CompactControlSize if compact else self.ControlSize)
|
||||
|
||||
self._thumbPosition = 0.0
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ from .EditorWidgets import (
|
||||
GuiEditorItemBasicRemark,
|
||||
GuiEditorItemProxyHttp,
|
||||
GuiEditorItemProxySocks,
|
||||
GuiEditorItemTextCheckBox,
|
||||
GuiEditorItemTextSwitch,
|
||||
GuiEditorItemTextComboBox,
|
||||
GuiEditorItemTextInput,
|
||||
GuiEditorItemTextSpinBox,
|
||||
@@ -51,7 +51,6 @@ from .QtGui import (
|
||||
)
|
||||
from .QtNetwork import AppQNetworkAccessManager
|
||||
from .QtWidgets import (
|
||||
AppQCheckBox,
|
||||
AppQComboBox,
|
||||
AppQComboBoxSeparatorDelegate,
|
||||
AppQDialog,
|
||||
@@ -104,7 +103,6 @@ __all__ = [
|
||||
'AppHue',
|
||||
'AppQAction',
|
||||
'AppQActionGroup',
|
||||
'AppQCheckBox',
|
||||
'AppQComboBox',
|
||||
'AppQComboBoxSeparatorDelegate',
|
||||
'AppQDialog',
|
||||
@@ -142,7 +140,7 @@ __all__ = [
|
||||
'GuiEditorItemBasicRemark',
|
||||
'GuiEditorItemProxyHttp',
|
||||
'GuiEditorItemProxySocks',
|
||||
'GuiEditorItemTextCheckBox',
|
||||
'GuiEditorItemTextSwitch',
|
||||
'GuiEditorItemTextComboBox',
|
||||
'GuiEditorItemTextInput',
|
||||
'GuiEditorItemTextSpinBox',
|
||||
|
||||
@@ -65,8 +65,8 @@ class _SubscriptionEditorDialog(AppQTransientDialog):
|
||||
|
||||
self.remarkEdit = QLineEdit(subscription.get('remark', ''))
|
||||
self.urlEdit = QLineEdit(subscription.get('webURL', ''))
|
||||
self.enabledCheckBox = QCheckBox()
|
||||
self.enabledCheckBox.setChecked(subscription.get('enabled', True))
|
||||
self.enabledSwitch = AppQSwitch()
|
||||
self.enabledSwitch.syncChecked(subscription.get('enabled', True))
|
||||
self.autoUpdateComboBox = AppQComboBox()
|
||||
self.proxyComboBox = AppQComboBox()
|
||||
self.userAgentEdit = QLineEdit(subscription.get('userAgent', ''))
|
||||
@@ -113,26 +113,34 @@ class _SubscriptionEditorDialog(AppQTransientDialog):
|
||||
form.setColumnStretch(1, 1)
|
||||
form.setColumnStretch(3, 1)
|
||||
|
||||
self.remarkLabel = AppQLabel(_('Remark'))
|
||||
self.urlLabel = AppQLabel(_('URL'))
|
||||
self.enabledLabel = AppQLabel(_('Enabled'))
|
||||
self.autoUpdateLabel = AppQLabel(_('Auto Update'))
|
||||
self.proxyLabel = AppQLabel(_('Auto Update Use Proxy'))
|
||||
self.userAgentLabel = AppQLabel(_('User Agent'))
|
||||
self.filterLabel = AppQLabel(_('Profile Filter (Regex)'))
|
||||
(
|
||||
self.remarkLabel,
|
||||
self.urlLabel,
|
||||
self.enabledLabel,
|
||||
self.autoUpdateLabel,
|
||||
self.proxyLabel,
|
||||
self.userAgentLabel,
|
||||
self.filterLabel,
|
||||
) = (
|
||||
AppQLabel(_('Remark')),
|
||||
AppQLabel(_('URL')),
|
||||
AppQLabel(_('Enabled')),
|
||||
AppQLabel(_('Auto Update')),
|
||||
AppQLabel(_('Auto Update Use Proxy')),
|
||||
AppQLabel(_('User Agent')),
|
||||
AppQLabel(_('Profile Filter (Regex)')),
|
||||
)
|
||||
|
||||
enabledControl = QWidget()
|
||||
|
||||
enabledLayout = QHBoxLayout(enabledControl)
|
||||
enabledLayout = QHBoxLayout()
|
||||
enabledLayout.setContentsMargins(0, 0, 0, 0)
|
||||
enabledLayout.setSpacing(10)
|
||||
enabledLayout.addWidget(self.enabledLabel)
|
||||
enabledLayout.addWidget(self.enabledCheckBox)
|
||||
enabledLayout.addWidget(self.enabledSwitch)
|
||||
enabledLayout.addStretch(1)
|
||||
|
||||
form.addWidget(self.remarkLabel, 0, 0)
|
||||
form.addWidget(self.remarkEdit, 0, 1)
|
||||
form.addWidget(enabledControl, 0, 2, 1, 2)
|
||||
form.addLayout(enabledLayout, 0, 2, 1, 2)
|
||||
form.addWidget(self.urlLabel, 1, 0)
|
||||
form.addWidget(self.urlEdit, 1, 1, 1, 3)
|
||||
form.addWidget(self.autoUpdateLabel, 2, 0)
|
||||
@@ -194,7 +202,7 @@ class _SubscriptionEditorDialog(AppQTransientDialog):
|
||||
return {
|
||||
'remark': self.remarkEdit.text().strip(),
|
||||
'webURL': self.urlEdit.text().strip(),
|
||||
'enabled': self.enabledCheckBox.isChecked(),
|
||||
'enabled': self.enabledSwitch.isChecked(),
|
||||
'autoupdate': self.autoUpdateComboBox.currentData() or '',
|
||||
'proxy': self.proxyComboBox.currentData() or '',
|
||||
'userAgent': self.userAgentEdit.text().strip(),
|
||||
|
||||
@@ -106,11 +106,11 @@ class GuiTUNSettingsItemSpinBoxBufferSizeXXX(GuiEditorItemTextSpinBox):
|
||||
self.setValue(oldValue)
|
||||
|
||||
|
||||
class GuiTUNSettingsItemCheckBoxXXX(GuiEditorItemTextCheckBox):
|
||||
"""Represent GUI TUN settings item check box xxx."""
|
||||
class GuiTUNSettingsItemSwitchXXX(GuiEditorItemTextSwitch):
|
||||
"""Represent GUI TUN settings item switch xxx."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize the GuiTUNSettingsItemCheckBoxXXX."""
|
||||
"""Initialize the GuiTUNSettingsItemSwitchXXX."""
|
||||
self.key = kwargs.pop('key', '')
|
||||
self.default = kwargs.pop('default', 'False')
|
||||
|
||||
@@ -245,7 +245,7 @@ class GuiTUNSettingsGroupBoxBasic(GuiEditorWidgetQGroupBox):
|
||||
title=_('Bypass Tun2socks Adapter Interface IP (separated by commas)'),
|
||||
key='bypassTUNAdapterInterfaceIP',
|
||||
),
|
||||
GuiTUNSettingsItemCheckBoxXXX(
|
||||
GuiTUNSettingsItemSwitchXXX(
|
||||
title=_(
|
||||
'Disable Primary Adapter Interface DNS (Mitigating DNS leaks on Windows)'
|
||||
),
|
||||
@@ -280,7 +280,7 @@ class GuiTUNSettingsGroupBoxMemory(GuiEditorWidgetQGroupBox):
|
||||
start=1,
|
||||
end=4,
|
||||
),
|
||||
GuiTUNSettingsItemCheckBoxXXX(
|
||||
GuiTUNSettingsItemSwitchXXX(
|
||||
title=_('TCP Receive Buffer Auto-tuning'),
|
||||
key='tcpAutoTuning',
|
||||
default='False',
|
||||
|
||||
@@ -36,7 +36,7 @@ from Furious.Controllers.SettingsController import (
|
||||
)
|
||||
from Furious.Frozenlib import AppSettings
|
||||
from Furious.Models import ProfileMetadata, ServerProfile
|
||||
from Furious.Qt import AppQMessageBox
|
||||
from Furious.Qt import AppQMessageBox, AppQSwitch
|
||||
from Furious.Service import (
|
||||
APPLICATION_LOG_CATEGORY,
|
||||
CORE_LOG_CATEGORY,
|
||||
@@ -108,6 +108,12 @@ class EditorMappingTest(unittest.TestCase):
|
||||
{'TOKEN': 'one=two', 'UNICODE': '测试'},
|
||||
)
|
||||
self.assertTrue(editor._applicationTun2socksInput.isChecked())
|
||||
|
||||
tunLabel, tunSwitch = editor._applicationTun2socksInput.widgets()
|
||||
|
||||
self.assertTrue(tunLabel.text())
|
||||
self.assertIsInstance(tunSwitch, AppQSwitch)
|
||||
self.assertEqual(tunSwitch.size(), AppQSwitch.CompactControlSize)
|
||||
self.assertTrue(editor._tunRemoteAddressInput.widgets()[1].isEnabled())
|
||||
self.assertEqual(editor._tunRemoteAddressInput.text(), '2001:db8::42')
|
||||
self.assertEqual(len(editor.groupBoxSequence()), 1)
|
||||
@@ -152,6 +158,12 @@ class EditorMappingTest(unittest.TestCase):
|
||||
|
||||
values = dialog.subscription()
|
||||
|
||||
self.assertIsInstance(dialog.enabledSwitch, AppQSwitch)
|
||||
self.assertEqual(dialog.enabledSwitch.size(), AppQSwitch.ControlSize)
|
||||
self.assertEqual(
|
||||
dialog.enabledSwitch.parentWidget().objectName(),
|
||||
'SubscriptionEditorForm',
|
||||
)
|
||||
self.assertEqual(values['remark'], 'Fixture subscription')
|
||||
self.assertEqual(values['webURL'], 'https://example.test/subscription')
|
||||
self.assertFalse(values['enabled'])
|
||||
|
||||
Reference in New Issue
Block a user