Skip to content

Use ColorPicker for all color dialogs #3815

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jan 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/windows/animated_title.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ class AnimatedTitle(QDialog):
# Path to ui file
ui_path = os.path.join(info.PATH, 'windows', 'ui', 'animated-title.ui')

def __init__(self):
super().__init__()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

# Load UI from designer & init
ui_util.load_ui(self, self.ui_path)
Expand Down
56 changes: 26 additions & 30 deletions src/windows/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,26 +67,19 @@ class Export(QDialog):

ExportStarted = pyqtSignal(str, int, int)
ExportFrame = pyqtSignal(str, int, int, int, str)
ExportEnded = pyqtSignal(str)
ExportEnded = pyqtSignal(str)

def __init__(self):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

# Create dialog class
QDialog.__init__(self)

# Load UI from designer
# Load UI from designer & init
ui_util.load_ui(self, self.ui_path)

# Init UI
ui_util.init_ui(self)

# get translations
# get translations & settings
_ = get_app()._tr

# Get settings
self.s = settings.get_settings()

# Track metrics
track_metric_screen("export-screen")

# Dynamically load tabs from settings data
Expand All @@ -113,9 +106,6 @@ def __init__(self):
# Pause playback (to prevent crash since we are fixing to change the timeline's max size)
get_app().window.actionPlay_trigger(None, force="pause")

# Clear timeline preview cache (to get more available memory)
get_app().window.timeline_sync.timeline.ClearAllCache()

# Hide audio channels
self.lblChannels.setVisible(False)
self.txtChannels.setVisible(False)
Expand All @@ -124,25 +114,31 @@ def __init__(self):
openshot.Settings.Instance().WAIT_FOR_VIDEO_PROCESSING_TASK = True
openshot.Settings.Instance().HIGH_QUALITY_SCALING = True

project_timeline = get_app().window.timeline_sync.timeline

# Clear timeline preview cache (to get more available memory)
project_timeline.ClearAllCache()

# Get the original timeline settings
width = get_app().window.timeline_sync.timeline.info.width
height = get_app().window.timeline_sync.timeline.info.height
fps = get_app().window.timeline_sync.timeline.info.fps
sample_rate = get_app().window.timeline_sync.timeline.info.sample_rate
channels = get_app().window.timeline_sync.timeline.info.channels
channel_layout = get_app().window.timeline_sync.timeline.info.channel_layout
width = project_timeline.info.width
height = project_timeline.info.height
fps = project_timeline.info.fps
sample_rate = project_timeline.info.sample_rate
channels = project_timeline.info.channels
channel_layout = project_timeline.info.channel_layout

# Create new "export" openshot.Timeline object
self.timeline = openshot.Timeline(width, height, openshot.Fraction(fps.num, fps.den),
sample_rate, channels, channel_layout)
self.timeline = openshot.Timeline(
width, height, openshot.Fraction(fps.num, fps.den),
sample_rate, channels, channel_layout)
# Init various properties
self.timeline.info.channel_layout = get_app().window.timeline_sync.timeline.info.channel_layout
self.timeline.info.has_audio = get_app().window.timeline_sync.timeline.info.has_audio
self.timeline.info.has_video = get_app().window.timeline_sync.timeline.info.has_video
self.timeline.info.video_length = get_app().window.timeline_sync.timeline.info.video_length
self.timeline.info.duration = get_app().window.timeline_sync.timeline.info.duration
self.timeline.info.sample_rate = get_app().window.timeline_sync.timeline.info.sample_rate
self.timeline.info.channels = get_app().window.timeline_sync.timeline.info.channels
self.timeline.info.sample_rate = sample_rate
self.timeline.info.channels = channels
self.timeline.info.channel_layout = channel_layout
self.timeline.info.has_audio = project_timeline.info.has_audio
self.timeline.info.has_video = project_timeline.info.has_video
self.timeline.info.video_length = project_timeline.info.video_length
self.timeline.info.duration = project_timeline.info.duration

# Load the "export" Timeline reader with the JSON from the real timeline
json_timeline = json.dumps(get_app().project._data)
Expand Down
60 changes: 32 additions & 28 deletions src/windows/title_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
# Is one even necessary, or is it safe to use xml.dom.minidom for that?
from xml.dom import minidom

from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtCore import Qt, pyqtSlot, QTimer
from PyQt5 import QtGui
from PyQt5.QtWidgets import (
QWidget, QGraphicsScene,
Expand All @@ -51,8 +51,9 @@
from classes.logger import log
from classes.app import get_app
from classes.metrics import track_metric_screen
from windows.views.titles_listview import TitlesListView
from windows.color_picker import ColorPicker
from classes.style_tools import style_to_dict, dict_to_style, set_if_existing

from windows.views.titles_listview import TitlesListView


Expand Down Expand Up @@ -368,6 +369,15 @@ def save_and_reload(self):
self.writeToFile(self.xmldoc)
self.display_svg()

@pyqtSlot(QtGui.QColor)
def color_callback(self, save_fn, refresh_fn, color):
"""Update SVG color after user selection"""
if not color or not color.isValid():
return
save_fn(color.name(), color.alphaF())
refresh_fn()
self.save_and_reload()

@staticmethod
def best_contrast(bg: QtGui.QColor) -> QtGui.QColor:
"""Choose text color for best contrast against a background"""
Expand All @@ -382,39 +392,33 @@ def btnFontColor_clicked(self):
app = get_app()
_ = app._tr

callback_func = functools.partial(
self.color_callback,
self.set_font_color_elements,
self.update_font_color_button)
# Get color from user
col = QColorDialog.getColor(self.font_color_code, self, _("Select a Color"),
QColorDialog.DontUseNativeDialog | QColorDialog.ShowAlphaChannel)

# Update SVG colors
if col.isValid():
self.set_font_color_elements(col.name(), col.alphaF())
self.update_font_color_button()

# Something changed, so update temp SVG
self.writeToFile(self.xmldoc)

# Display SVG again
self.display_svg()
log.debug("Launching color picker for %s", self.font_color_code.name())
ColorPicker(
self.font_color_code, parent=self,
title=_("Select a Color"),
extra_options=QColorDialog.ShowAlphaChannel,
callback=callback_func)

def btnBackgroundColor_clicked(self):
app = get_app()
_ = app._tr

callback_func = functools.partial(
self.color_callback,
self.set_bg_style,
self.update_background_color_button)
# Get color from user
col = QColorDialog.getColor(self.bg_color_code, self, _("Select a Color"),
QColorDialog.DontUseNativeDialog | QColorDialog.ShowAlphaChannel)

# Update SVG colors
if col.isValid():
self.set_bg_style(col.name(), col.alphaF())
self.update_background_color_button()

# Something changed, so update temp SVG
self.writeToFile(self.xmldoc)

# Display SVG again
self.display_svg()
log.debug("Launching color picker for %s", self.bg_color_code.name())
ColorPicker(
self.bg_color_code, parent=self,
title=_("Select a Color"),
extra_options=QColorDialog.ShowAlphaChannel,
callback=callback_func)

def btnFont_clicked(self):
app = get_app()
Expand Down
22 changes: 6 additions & 16 deletions src/windows/views/blender_listview.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
Qt, QObject, pyqtSlot, pyqtSignal, QThread, QTimer, QSize,
)
from PyQt5.QtWidgets import (
QApplication, QListView, QMessageBox, QColorDialog,
QApplication, QListView, QMessageBox,
QComboBox, QDoubleSpinBox, QLabel, QPushButton, QLineEdit, QPlainTextEdit,
)
from PyQt5.QtGui import QColor, QImage, QPixmap
Expand All @@ -54,7 +54,9 @@
from classes import settings
from classes.query import File
from classes.app import get_app

from windows.models.blender_model import BlenderModel
from windows.color_picker import ColorPicker


class BlenderListView(QListView):
Expand Down Expand Up @@ -228,24 +230,13 @@ def color_button_clicked(self, widget, param, index):
currentColor.setRgbF(color_value[0], color_value[1], color_value[2])
# Store our arguments for the callback to pick up again
self._color_scratchpad = (widget, param)

# Set up non-modal color dialog (to avoid blocking the eyedropper)
self.newColorDialog = QColorDialog(currentColor, self.win)
self.newColorDialog.setWindowTitle(_("Select a Color"))
self.newColorDialog.setWindowFlags(Qt.Tool)
self.newColorDialog.setOptions(QColorDialog.DontUseNativeDialog)
# Avoid signal loops
self.newColorDialog.blockSignals(True)
self.newColorDialog.colorSelected.connect(self.color_selected)
self.newColorDialog.finished.connect(self.newColorDialog.deleteLater)
self.newColorDialog.blockSignals(False)
self.newColorDialog.open()
ColorPicker(currentColor, callback=self.color_selected, parent=self.win)

@pyqtSlot(QColor)
def color_selected(self, newColor):
"""QColorDialog callback when the user chooses a color"""
"""Callback when the user chooses a color in the dialog"""
if not self._color_scratchpad:
log.warning("QColorDialog callback called without parameter to set")
log.warning("ColorPicker callback called without parameter to set")
return
(widget, param) = self._color_scratchpad
if not newColor or not newColor.isValid():
Expand Down Expand Up @@ -673,7 +664,6 @@ def __init__(self, parent, *args):
self.selected = None
self.deselected = None
self._color_scratchpad = None
self.newColorDialog = None
self.selected_template = ""
self.final_render = False

Expand Down
46 changes: 27 additions & 19 deletions src/windows/views/properties_tableview.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,27 @@
"""

import os
from functools import partial
import functools
from operator import itemgetter
from PyQt5.QtCore import Qt, QRectF, QLocale, pyqtSignal, QTimer

from PyQt5.QtCore import Qt, QRectF, QLocale, pyqtSignal, pyqtSlot
from PyQt5.QtGui import (
QCursor, QIcon, QColor, QBrush, QPen, QPalette, QPixmap,
QPainter, QPainterPath, QLinearGradient, QFont, QFontInfo,
)
from PyQt5.QtWidgets import (
QTableView, QAbstractItemView, QMenu, QSizePolicy,
QHeaderView, QColorDialog, QItemDelegate, QStyle, QLabel,
QHeaderView, QItemDelegate, QStyle, QLabel,
QPushButton, QHBoxLayout, QFrame, QFontDialog
)

from classes.logger import log
from classes.app import get_app
from classes import info
from classes.query import Clip, Effect, Transition

from windows.models.properties_model import PropertiesModel
from windows.color_picker import ColorPicker

import openshot

Expand Down Expand Up @@ -297,6 +300,13 @@ def mouseReleaseEvent(self, event):
self.lock_selection = False
self.previous_x = -1

@pyqtSlot(QColor)
def color_callback(self, newColor: QColor):
# Set the new color keyframe
if newColor.isValid():
self.clip_properties_model.color_update(
self.selected_item, newColor)

def doubleClickedCB(self, model_index):
"""Double click handler for the property table"""

Expand All @@ -322,12 +332,11 @@ def doubleClickedCB(self, model_index):

# Show color dialog
currentColor = QColor(red, green, blue)
newColor = QColorDialog.getColor(currentColor, self, _("Select a Color"),
QColorDialog.DontUseNativeDialog)

# Set the new color keyframe
if newColor.isValid():
self.clip_properties_model.color_update(self.selected_item, newColor)
log.debug("Launching ColorPicker for %s", currentColor.name())
ColorPicker(
currentColor, parent=self, title=_("Select a Color"),
callback=self.color_callback)
return

elif property_type == "font":
# Get font from user
Expand Down Expand Up @@ -381,7 +390,7 @@ def filter_changed(self, value=None):
self.clip_properties_model.update_model(value)

def contextMenuEvent(self, event):
""" Display context menu, or release lock when menu displays """
""" Display context menu """
# Get property being acted on
index = self.indexAt(event.pos())
if not index.isValid():
Expand Down Expand Up @@ -469,6 +478,7 @@ def contextMenuEvent(self, event):
track_name = track.get("label") or _("Track %s") % display_count
self.choices.append({"name": track_name, "value": track.get("number"), "selected": False, "icon": None})
display_count -= 1
return

elif self.property_type == "font":
# Get font from user
Expand All @@ -480,7 +490,6 @@ def contextMenuEvent(self, event):
if ok and font:
fontinfo = QFontInfo(font)
self.clip_properties_model.value_updated(self.selected_item, value=fontinfo.family())
return self.contextMenuEvent(event, release=True)

elif self.property_type == "color":
# Get current value of color
Expand All @@ -490,13 +499,11 @@ def contextMenuEvent(self, event):

# Show color dialog
currentColor = QColor(red, green, blue)
newColor = QColorDialog.getColor(currentColor, self, _("Select a Color"),
QColorDialog.DontUseNativeDialog)

# Set the new color keyframe
if newColor.isValid():
self.clip_properties_model.color_update(self.selected_item, newColor)
return self.contextMenuEvent(event, release=True)
log.debug("Launching ColorPicker for %s", currentColor.name())
ColorPicker(
currentColor, parent=self, title=_("Select a Color"),
callback=self.color_callback)
return

# Define bezier presets
bezier_presets = [
Expand Down Expand Up @@ -540,7 +547,8 @@ def contextMenuEvent(self, event):
Bezier_Menu = menu.addMenu(self.bezier_icon, _("Bezier"))
for bezier_preset in bezier_presets:
preset_action = Bezier_Menu.addAction(bezier_preset[4])
preset_action.triggered.connect(partial(self.Bezier_Action_Triggered, bezier_preset))
preset_action.triggered.connect(functools.partial(
self.Bezier_Action_Triggered, bezier_preset))
Linear_Action = menu.addAction(self.linear_icon, _("Linear"))
Linear_Action.triggered.connect(self.Linear_Action_Triggered)
Constant_Action = menu.addAction(self.constant_icon, _("Constant"))
Expand Down