Skip to content
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

Replace focal point selection gui with a more precise one. #3

Open
wants to merge 2 commits into
base: focalpoint
Choose a base branch
from
Open
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
8 changes: 4 additions & 4 deletions kritatoot/Toot.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ def uploadmedia(url, access_token, filename, description=None, focus=(0.0,0.0)):
focus = (0.0,0.0)

if focus[0] < -1.0 or focus[0] > 1.0:
print('Focal point out of range. Setting to (0,0)')
focus = (0.0,0.0)
print('Warning: Focal point out of range, bounding.')
focus = (min(1.0, max(-1.0, focus[0])), focus[1])

if focus[1] < -1.0 or focus[1] > 1.0:
print('Focal point out of range. Setting to (0,0)')
focus = (0.0,0.0)
print('Warning: Focal point out of range, bounding.')
focus = (focus[0], min(1.0, max(-1.0, focus[1])))

# Add a focal point, default is dead-center: (0,0)
data_focus = '''\r\n--------------------------d74496d66958873e
Expand Down
272 changes: 136 additions & 136 deletions kritatoot/UploadTab.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *


from krita import *

from .Toot import uploadmedia, postmedia, post
from .TempMedia import saveTempMedia, removeTempMedia

Expand Down Expand Up @@ -72,170 +74,165 @@ def addtext(self):
self.alttext = text

self.accept()


class FocalPointDialog(QDialog):

class focalPointWidget(QWidget):
"""
A modal dialogbox for users to supply a focal point: a location that acts
like an achor or pivot.
A widget which draws an image and you can select a focal point.
"""

def __init__(self, parent=None, focal=None):
"""
focal - (tuple) or None
"""
def __init__(self, parent = None):
super(focalPointWidget, self).__init__(parent)
self.focalPoint = [0.0, 0.0]
self.image = QImage()
self.mouseIn = False
self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)

super(FocalPointDialog, self).__init__(parent) # Py2

self.setModal(True)
def setImage(self, image = QImage()):
self.image = image
self.update()

def paintEvent(self, event):

self.MAXROW = 3
self.MAXCOL = 3
painter = QPainter(self)

# holds the (row,col) of a currently selected, but uncommitted, focal point.
# a sel focal point is commited when user clicks add.
self.tempidx = focal
image = self.image.scaled(self.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)
imageOffsetLeft = (self.width()-image.width())/2
imageOffsetTop = (self.height()-image.height())/2

# (row,col) of the last commited focal point
self.focalidx = focal
painter.setBrush(Qt.black)
painter.setPen(QPen(Qt.NoPen))
painter.drawRect(0, 0, self.width(), self.height())
painter.drawImage(imageOffsetLeft, imageOffsetTop, image)

# the focalidx, (row, col), converted to focal point coordinates (x, y)
self.focalcoords = (0.0, 0.0)
painter.save()
# Let's make this super fancy and setup an area of interest!

if self.focalidx:
self.focalcoords = self.indexToCoordinates(self.focalidx[0], self.focalidx[1])
focalXY = QPointF(((self.focalPoint[0] + 1.0) / 2), (((-1.0*self.focalPoint[1]) + 1.0) / 2))
aoi = 0.333 # The area of interest is ~ a third of the image.
offset = QPointF(aoi/2, aoi/2)
topleft = focalXY - offset
bottomright = focalXY + offset


self.focallabel = QLabel('Choose a focal point (anchor)')
# First let's draw the whiteish square in the middle.
# This is necessary for very dark images.

gridLayout = QGridLayout()
gridLayout.setHorizontalSpacing(0)
gridLayout.setVerticalSpacing(0)
white = QRect( QPoint( (topleft.x()*image.width()) + imageOffsetLeft, (topleft.y() * image.height())+imageOffsetTop), QPoint((bottomright.x()*image.width())+imageOffsetLeft, (bottomright.y()*image.height())+imageOffsetTop))
painter.setBrush(Qt.white)
painter.setOpacity(0.3)
painter.drawRect(white)

# Then draw 4 black sections to indicate the non-visible area.
# This is for very bright images.

painter.setBrush(Qt.black)
painter.drawRect(QRect(QPoint(0, 0), white.topLeft()))
painter.drawRect(QRect(white.bottomRight(), QPoint(self.width(), self.height())))
painter.drawRect(QRect(QPoint(0, white.bottom()), QPoint(white.left(), self.height())))
painter.drawRect(QRect(QPoint(white.right(), 0), QPoint(self.width(), white.top())))

self.focalbuttons = [None] * self.MAXROW
for i in range(self.MAXROW):
self.focalbuttons[i] = [None] * self.MAXCOL

for i in range(self.MAXROW):

for j in range(self.MAXCOL):
button = QToolButton()
button.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)

if self.focalidx and i == self.focalidx[0] and j == self.focalidx[1]:
button.setStyleSheet("background-color: #2588d0;")

gridLayout.addWidget(button, i, j)

button.clicked.connect(partial(self.toggleFocal, i, j))

self.focalbuttons[i][j] = button

painter.setBrush(Qt.white)
painter.setPen(Qt.white)
painter.setOpacity(1.0)
painter.drawText(5, self.height()-10, str(", ").join(format(x, "1.2f") for x in self.focalPoint))

painter.restore()


def setFocalPointFromMousePos(self, pos = QPoint()):

centerLayout = QHBoxLayout()
centerLayout.addStretch(1)
centerLayout.addLayout(gridLayout);
centerLayout.addStretch(1)
image = QSize(self.width(), self.height())
if self.image.width() != 0 and self.image.height() != 0:
if self.image.width() > self.image.height():
image = QSize(self.width(), (self.image.height()/self.image.width()) * self.height())
else:
image = QSize((self.image.width()/self.image.height()) * self.width(), self.height())

imageOffsetLeft = (self.width() - image.width() ) / 2
imageOffsetTop = (self.height() - image.height()) / 2

# controls
self.addbutton = QToolButton()
self.addbutton.setText('Add')
x = (((pos.x() - imageOffsetLeft) / image.width() ) * 2 ) - 1.0
y = (((pos.y() - imageOffsetTop) / image.height() ) * 2 ) - 1.0
self.focalPoint = [x, y * -1.0]
print(self.focalPoint)
self.update()

def mousePressEvent(self, event):

self.exitbutton = QToolButton()
self.exitbutton.setText('Cancel')
self.mouseIn = True
self.setFocalPointFromMousePos(event.pos())

controlsLayout = QHBoxLayout()
controlsLayout.addStretch(1)
controlsLayout.addWidget(self.exitbutton)
controlsLayout.addWidget(self.addbutton)
event.accept()

def mouseReleaseEvent(self, event):

mainLayout = QVBoxLayout()
self.mouseIn = False
self.setFocalPointFromMousePos(event.pos())

mainLayout.addWidget(self.focallabel)
mainLayout.addLayout(centerLayout)
mainLayout.addLayout(controlsLayout)
event.accept()

self.setLayout(mainLayout)
def mouseMoveEvent(self, event):
if (self.mouseIn == True):
self.setFocalPointFromMousePos(event.pos())
event.accept()

def sizeHint(self):
return QSize(256, 256)

def setFocalPoint(self, x, y):
self.focalPoint = [x, y]
self.update()

self.defaultStyleSheet = self.addbutton.styleSheet()
def getFocalPoint(self):
return self.focalPoint

# slots
self.addbutton.clicked.connect(self.addfocal)
self.exitbutton.clicked.connect(self.accept)

class FocalPointDialog(QDialog):
"""
A modal dialogbox for users to supply a focal point: a location that acts
like an achor or pivot.
"""

def indexToCoordinates(self, row, col):
def __init__(self, parent = None, focal = (0, 0), image = QImage()):
"""
Converts a row & col into a corresponding (x,y) tuple in
focal point space. In focal point space, x = -1.0 to 1.0
and y = -1.0 to 1.0
focal - (tuple) or None
image - (QImage) or None
"""

super(FocalPointDialog, self).__init__(parent) # Py2

# Note - hard coded values. assuming 3x3 grid
# using perimiter values except for center
if row == 0:
if col == 0:
return (-1.0, 1.0)
elif col == 1:
return (0.0, 1.0)
elif col == 2:
return (1.0, 1.0)
elif row == 1:
if col == 0:
return (-1.0, 0.0)
elif col == 1:
return (0.0, 0.0)
elif col == 2:
return (1.0, 0.0)
elif row == 2:
if col == 0:
return (-1.0, -1.0)
elif col == 1:
return (0.0, -1.0)
elif col == 2:
return (1.0, -1.0)
self.setModal(True)
self.setWindowTitle('Set Image Focalpoint')

self.focalcoords = focal


def toggleFocal(self, row, column):
"""
"""
#print("CLICKED (" + str(row) + "," + str(column) + ")")

# clear all
for i in range(self.MAXROW):
for j in range(self.MAXCOL):
self.focalbuttons[i][j].setStyleSheet(self.defaultStyleSheet)

if self.focalidx:
# already selected?
if row == self.focalidx[0] and column == self.focalidx[1]:
self.focalbuttons[row][column].setStyleSheet(self.defaultStyleSheet)
self.tempidx = None
else:
self.focalbuttons[row][column].setStyleSheet("background-color: #2588d0;")
self.tempidx = (row, column)
else:
# first time a selection has been made
self.focalbuttons[row][column].setStyleSheet("background-color: #2588d0;")
self.tempidx = (row, column)

self.focallabel = QLabel('Choose a focal point (anchor)')

mainLayout = QVBoxLayout()
mainLayout.addWidget(self.focallabel)

self.imageWidget = focalPointWidget()
self.imageWidget.setImage(image)
self.imageWidget.setFocalPoint(self.focalcoords[0], self.focalcoords[1])
mainLayout.addWidget(self.imageWidget)


# controls
# Let's replace this with a QDialogButtonBox, then that sorts itself for differences between Desktop Enviroments :)

buttons = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
buttons.accepted.connect(self.addfocal)
buttons.rejected.connect(self.accept)

mainLayout.addWidget(buttons)

self.setLayout(mainLayout)

def addfocal(self):
"""
"""

self.focalidx = self.tempidx

if self.focalidx:
# convert the row/col to actual coordinates
self.focalcoords = self.indexToCoordinates(self.focalidx[0], self.focalidx[1])
else:
self.focalcoords = (0.0, 0.0)
focal = self.imageWidget.getFocalPoint()
self.focalcoords = (focal[0], focal[1])

self.accept()

Expand Down Expand Up @@ -282,7 +279,6 @@ def __init__(self, parent=None):
self.alttext = None

# the selected row and column, if any (otherwise None)
self.selfocalidx = None
self.focalcoords = (0.0, 0.0)

# list of sites where the app is registered and authorized
Expand Down Expand Up @@ -492,16 +488,21 @@ def toggleVisibility(self):
def addFocalPoint(self):
"""
"""

focalui = FocalPointDialog(self, self.selfocalidx);
image = QImage()
doc = Krita.instance().activeDocument()
if doc is not None:
image = doc.projection(0, 0, doc.width(), doc.height())
if doc.width() > 512 and doc.height() > 512:
# This is probably not pixel art.
image = image.scaled(512, 512, Qt.KeepAspectRatio, Qt.SmoothTransformation)

focalui = FocalPointDialog(self, self.focalcoords, image);
focalui.exec_()

self.selfocalidx = focalui.focalidx

if self.selfocalidx:
self.focalcoords = focalui.focalcoords
if self.focalcoords[0] != 0.0 and self.focalcoords[1] != 0.0:
focalicon = self.icons['focal']
self.focalpoint.setIcon(focalicon)
self.focalcoords = focalui.focalcoords
else:
focalicon = self.icons['nofocal']
self.focalpoint.setIcon(focalicon)
Expand Down Expand Up @@ -628,7 +629,6 @@ def upload(self):
visibleicon = self.icons['nohide']
self.hidden.setIcon(visibleicon)

self.selfocalidx = None
self.focalcoords = (0.0, 0.0)
focalicon = self.icons['nofocal']
self.focalpoint.setIcon(focalicon)
Expand Down