Skip to content

Commit

Permalink
add printer tape selection
Browse files Browse the repository at this point in the history
  • Loading branch information
piksel committed Mar 13, 2021
1 parent 70bcf96 commit f65673f
Show file tree
Hide file tree
Showing 12 changed files with 240 additions and 58 deletions.
6 changes: 5 additions & 1 deletion .idea/pytouch-cube.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 20 additions & 1 deletion build_win.ps1
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@

$APP_SCRIPT='pytouch3.py'
$ICON='pytouch3.ico'
$IMG_DATA="pytouch3.png;."

python3 -m pyinstaller --add-data 'pytouch3.png:.' $APP_SCRIPT
$VER=$(git describe)
$ZIPFILE="pytouch3-win64-$VER.zip"

Write-Host -Fore Cyan "Building archive for PyTouch Cube $VER`n"
Write-Host -Fore Cyan ":: Running PyInstaller..."
pyinstaller --noconfirm --add-data=$IMG_DATA --windowed --icon=$ICON $APP_SCRIPT

if (Test-Path dist/$ZIPFILE)
{
Write-Host -Fore Cyan ":: Removing previous archive..."
Remove-Item dist/$ZIPFILE
}
Push-Location dist/pytouch3
Write-Host -Fore Cyan ":: Compressing archive..."
7z a -bb0 "-x!opengl32sw.dll" "-x!qt5qml*.dll" "-xr!qwebgl.dll" "-xr!qminimal.dll" "-xr!qoffscreen.dll" ..\$ZIPFILE *
Pop-Location

Write-Host -Fore Cyan ":: Done!"
69 changes: 52 additions & 17 deletions gui/editor_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import logging
import pickle

from PyQt5.QtCore import Qt, QRect, QPoint, QMargins
from PyQt5.QtGui import QPixmap, QImage, QPainter, QColor, QIcon
from PyQt5.QtCore import Qt, QRect, QPoint, QMargins, QModelIndex
from PyQt5.QtGui import QPixmap, QImage, QPainter, QColor, QIcon, QBitmap
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QPushButton, QLabel, QFileDialog, QHBoxLayout, \
QGroupBox, QMessageBox, QMainWindow, QScrollArea, QSizePolicy

Expand All @@ -18,6 +18,7 @@
from .preview_image import PreviewImage
from .printer_select import PrinterSelect
from .source_items import SourceItems
from .tape_select import TapeSelect
from .top_menu import TopMenu
from .types import *

Expand Down Expand Up @@ -45,6 +46,7 @@ def __init__(self, app: QApplication):
self.current_item = None
self.print_thread = None
self.item_preview_offsets = []
self.needs_invert = False

Settings.load()

Expand Down Expand Up @@ -73,7 +75,7 @@ def __init__(self, app: QApplication):
items_layout.setAlignment(Qt.AlignLeft)

sources.item_selected.connect(self.selected_item_changed)
sources.items_changed.connect(self.update_preview)
sources.items_changed.connect(self.items_changed)

self.property_group = QGroupBox('Item properties:')
self.props_layout = QVBoxLayout()
Expand Down Expand Up @@ -129,8 +131,13 @@ def __init__(self, app: QApplication):
bottom_bar = QHBoxLayout()
bottom_bar.addWidget(QLabel('Print device:'))
bottom_bar.addWidget(self.printer_select)

self.tape_select = TapeSelect(self)
self.tape_select.currentIndexChanged.connect(self.on_tape_changed)
bottom_bar.addWidget(QLabel('Tape:'))
bottom_bar.addWidget(self.tape_select)
bottom_bar.addStretch()
# /dev/tty.PT-P300BT0607-Serial

print_button = QPushButton('Print')
print_button.setFixedWidth(100)
bottom_bar.addWidget(print_button)
Expand Down Expand Up @@ -233,6 +240,19 @@ def on_open(self):
self.current_file = file_path
self.open()

def on_tape_changed(self, index: int):
if index < 0:
return
fg, bg = self.tape_select.get_colors(index)
self.preview_image.update_colors(fg, bg)

needs_invert = sum(bg) < sum(fg)
if needs_invert != self.needs_invert:
self.needs_invert = needs_invert
self.update_preview()
else:
self.preview_image.repaint_preview()

def save(self):
with open(self.current_file, 'wb') as file:
pickler = pickle.Pickler(file)
Expand Down Expand Up @@ -292,13 +312,11 @@ def update_preview(self):
item_renders = []
item_preview_offsets = []
width_needed = 0
bg_color = Qt.white

curr_index = self.sources.table.currentIndex()
selected_index = curr_index.row()
items = self.sources.items.items
for i, item in enumerate(items):
selected = selected_index == i
render = item.render()
render = QBitmap(item.render())
render_error = item.get_render_error()
if render_error is not None:
continue
Expand All @@ -310,36 +328,53 @@ def update_preview(self):
dst_rect = QRect(QPoint(), sz.scaled(sz * margins.scale, Qt.KeepAspectRatio))
# dst_rect.marginsAdded(margins.getQMargins())
dst_rect.translate(width_needed, margins.vert + ((USABLE_HEIGHT - dst_rect.height()) / 2))

item_renders.append((render, dst_rect, src_rect, selected))
invert = self.needs_invert and item.get_type() in ['Image', 'Barcode', 'QRCode']
item_renders.append((render, dst_rect, src_rect, invert))
width_needed += dst_rect.width()
item_preview_offsets.append(width_needed)

x = 0
image = QImage(width_needed, USABLE_HEIGHT, QImage.Format_Mono)
image.fill(QColor(255, 255, 255))
image.fill(bg_color)
painter = QPainter(image)
for render, dst_rect, src_rect, selected in iter(item_renders):
painter.setBackgroundMode(Qt.OpaqueMode)
for render, dst_rect, src_rect, invert in iter(item_renders):
fill_rect = QRect(dst_rect.left(), 0, dst_rect.width(), USABLE_HEIGHT)
painter.fillRect(fill_rect, Qt.white)
painter.drawImage(dst_rect, render, src_rect)
painter.fillRect(fill_rect, bg_color)
if invert:
painter.setBackground(Qt.black)
painter.setPen(Qt.white)
else:
painter.setBackground(Qt.white)
painter.setPen(Qt.black)
painter.drawPixmap(dst_rect, render, src_rect)
x += fill_rect.width()
# select_rect = fill_rect.adjusted(0, USABLE_HEIGHT, 0, 2)
# painter.fillRect(select_rect, Qt.black if selected else Qt.white)
painter.end()
del painter

self.print_image = image
self.preview_image.set_item_offsets(item_preview_offsets)
self.preview_image.selected_index = selected_index
# self.preview_image.selected_index = selected_index
self.preview_image.setPixmap(QPixmap.fromImage(image))
self.preview_image.repaint()

def selected_item_changed(self, item: Optional[Printable]):
if self.current_item == item:
return
self.current_item = item
self.update_props()
self.preview_image.update_selected(self.sources.table.currentIndex().row())

def items_changed(self):
self.update_preview()
# Since an auto-selected item does not trigger the event we have to do it manually if applicable
current_row = self.sources.table.currentIndex().row()
if current_row >= 0:
current_item = self.sources.items.items[current_row]
else:
current_item = None
self.selected_item_changed(current_item)

def update_props(self):

if self.current_item is None:
Expand Down
43 changes: 33 additions & 10 deletions gui/preview_image.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from typing import Optional, List
from typing import Optional, List, Tuple

from PyQt5.QtCore import pyqtSignal, QRect, Qt
from PyQt5.QtGui import QPainter, QImage, QPixmap, QColor, QPalette
from PyQt5.QtGui import QPainter, QImage, QPixmap, QColor, QPalette, QBitmap, QRegion
from PyQt5.QtWidgets import QLabel, QWidget
from qasync import QtGui

from gui.types import Color
from labelmaker import USABLE_HEIGHT


Expand All @@ -16,16 +17,31 @@ def __init__(self, parent: Optional[QWidget]):
self.selected_index = -1
self.item_offsets: List[int] = []
self.setFixedHeight(USABLE_HEIGHT + 2)
self.fg_color = Qt.black
self.bg_color = Qt.white
self.preview_bitmap = QPixmap()

def update_selected(self, selected_index: int):
self.selected_index = selected_index
def update_colors(self, fg: Color, bg: Color, repaint=True):
self.fg_color = QColor(*fg)
self.bg_color = QColor(*bg)

def repaint_preview(self):
pixmap = self.pixmap()
if pixmap is None:
return
painter = QPainter(pixmap)
self.draw_selection(painter)
self.draw_preview(painter)
painter.end()
self.repaint()
self.repaint(self.preview_bitmap.rect())

def update_selected(self, selected_index: int):
self.selected_index = selected_index
pixmap = self.pixmap()
if pixmap is None:
return
with QPainter(pixmap) as painter:
self.draw_selection(painter)
self.repaint(QRect(0, USABLE_HEIGHT-1, self.preview_bitmap.width(), 4))

def draw_selection(self, painter: QPainter):
select_rect = QRect(0, USABLE_HEIGHT, 0, 4)
Expand All @@ -37,15 +53,22 @@ def draw_selection(self, painter: QPainter):
painter.fillRect(select_rect, color)

def setPixmap(self, a0: QtGui.QPixmap) -> None:
self.preview_bitmap = QBitmap(a0)
img = QImage(a0.width(), a0.height() + 4, QImage.Format_RGB32)
img.fill(self.palette().color(QPalette.Background))
painter = QPainter(img)
painter.drawImage(0, 0, a0.toImage())
self.draw_selection(painter)
painter.end()
if a0.width() > 0:
with QPainter(img) as painter:
self.draw_preview(painter)
self.draw_selection(painter)
super().setPixmap(QPixmap(img))
self.repaint()

def draw_preview(self, painter: QPainter):
painter.setBackgroundMode(Qt.OpaqueMode)
painter.setBackground(self.bg_color)
painter.setPen(self.fg_color)
painter.drawPixmap(0, 0, self.preview_bitmap)

def mousePressEvent(self, ev: QtGui.QMouseEvent) -> None:
x = ev.x()
for index, offset in enumerate(self.item_offsets):
Expand Down
39 changes: 39 additions & 0 deletions gui/tape_select.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from pprint import pprint

from PyQt5.QtCore import QDir, Qt
from PyQt5.QtWidgets import QComboBox
from qasync import asyncSlot

from labels import tapes
from labelmaker.comms import list_printer_devices
from util import *
from .types import *


class TapeModel(QStandardItemModel):
def __init__(self, parent: QWidget):
super().__init__(parent)
self.colors: List[Tuple[Color, Color]] = []

def add_tape(self, label, fg, bg):
self.colors.append((fg, bg))
self.appendRow(QStandardItem(label))


class TapeSelect(QComboBox):
def __init__(self, parent: QWidget):
super().__init__(parent)
if hasattr(self, 'setPlaceholderText'):
self.setPlaceholderText('Select tape type')
self.model = TapeModel(self)
for label, fg, bg in tapes:
self.model.add_tape(label, fg, bg)
self.setModel(self.model)

index = self.findText('TZe-231,', Qt.MatchStartsWith)
if index > 0:
self.setCurrentIndex(index)

def get_colors(self, index: int):
return self.model.colors[index]

2 changes: 2 additions & 0 deletions gui/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from PyQt5.QtGui import QStandardItemModel, QStandardItem
from PyQt5.QtWidgets import QWidget

Color = Tuple[int, int, int]


class PrinterDevicesModel(QStandardItemModel):
class Columns(Enum):
Expand Down
9 changes: 0 additions & 9 deletions labelmaker/comms.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,12 @@ def __init__(self, address: str, service=None, name=None):
async def list_devices(cls) -> List[Tuple[str, PrinterDevice]]:
devices = bluetooth.discover_devices(1, flush_cache=False, lookup_names=True, lookup_class=True)

for d in devices:
pprint(d)

return [(name if not None else address, BluetoothPrinterDevice(address, service)) for address, name, service in
devices]

def test(self):
log.info(f'Scanning {self.address} for services...')
service_matches = bluetooth.find_service(address=self.address)
for d in service_matches:
pprint(d)

first_match = service_matches[0]

Expand All @@ -64,8 +59,6 @@ def test(self):

def open(self):
service_matches = bluetooth.find_service(address=self.address)
for d in service_matches:
pprint(d)

first_match = service_matches[0]

Expand Down Expand Up @@ -138,8 +131,6 @@ def list_comports(cls) -> List[ListPortInfo]:
dev_name = '{0} - {1} ({2})'.format(disp_name, name, tty)
else:
dev_name = '{0} ({1})'.format(name, tty)
print('Device:', tty, 'Address:', address)
print('Name:', dev_name)
info = ListPortInfo(tty)
info.name = dev_name
ports.append(info)
Expand Down
Loading

0 comments on commit f65673f

Please sign in to comment.