commit fad26ba9aa3964a08e218b69830644d49f18ff8f Author: Ilya Zhuravlev Date: Wed Oct 14 02:39:59 2020 -0400 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..98559c0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +venv +target +__pycache__ +*.pyc diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..36ceaca --- /dev/null +++ b/requirements.txt @@ -0,0 +1,8 @@ +altgraph==0.17 +fbs==0.9.0 +future==0.18.2 +macholib==1.14 +pefile==2019.4.18 +PyInstaller==3.4 +PyQt5==5.9.2 +sip==4.19.8 diff --git a/src/build/settings/base.json b/src/build/settings/base.json new file mode 100644 index 0000000..6c3140d --- /dev/null +++ b/src/build/settings/base.json @@ -0,0 +1,6 @@ +{ + "app_name": "Vial", + "author": "xyz", + "main_module": "src/main/python/main.py", + "version": "0.0.0" +} \ No newline at end of file diff --git a/src/build/settings/linux.json b/src/build/settings/linux.json new file mode 100644 index 0000000..7a64c95 --- /dev/null +++ b/src/build/settings/linux.json @@ -0,0 +1,6 @@ +{ + "categories": "Utility;", + "description": "", + "author_email": "", + "url": "" +} \ No newline at end of file diff --git a/src/build/settings/mac.json b/src/build/settings/mac.json new file mode 100644 index 0000000..f7bd610 --- /dev/null +++ b/src/build/settings/mac.json @@ -0,0 +1,3 @@ +{ + "mac_bundle_identifier": "" +} \ No newline at end of file diff --git a/src/main/icons/Icon.ico b/src/main/icons/Icon.ico new file mode 100644 index 0000000..3312d86 Binary files /dev/null and b/src/main/icons/Icon.ico differ diff --git a/src/main/icons/README.md b/src/main/icons/README.md new file mode 100644 index 0000000..c6c4194 --- /dev/null +++ b/src/main/icons/README.md @@ -0,0 +1,11 @@ +![Sample app icon](linux/128.png) + +This directory contains the icons that are displayed for your app. Feel free to +change them. + +The difference between the icons on Mac and the other platforms is that on Mac, +they contain a ~5% transparent margin. This is because otherwise they look too +big (eg. in the Dock or in the app switcher). + +You can create Icon.ico from the .png files with +[an online tool](http://icoconvert.com/Multi_Image_to_one_icon/). \ No newline at end of file diff --git a/src/main/icons/base/16.png b/src/main/icons/base/16.png new file mode 100755 index 0000000..f7d02dc Binary files /dev/null and b/src/main/icons/base/16.png differ diff --git a/src/main/icons/base/24.png b/src/main/icons/base/24.png new file mode 100755 index 0000000..faa6710 Binary files /dev/null and b/src/main/icons/base/24.png differ diff --git a/src/main/icons/base/32.png b/src/main/icons/base/32.png new file mode 100755 index 0000000..36b25e8 Binary files /dev/null and b/src/main/icons/base/32.png differ diff --git a/src/main/icons/base/48.png b/src/main/icons/base/48.png new file mode 100755 index 0000000..4a5dcbd Binary files /dev/null and b/src/main/icons/base/48.png differ diff --git a/src/main/icons/base/64.png b/src/main/icons/base/64.png new file mode 100755 index 0000000..4b0a423 Binary files /dev/null and b/src/main/icons/base/64.png differ diff --git a/src/main/icons/linux/1024.png b/src/main/icons/linux/1024.png new file mode 100755 index 0000000..2248377 Binary files /dev/null and b/src/main/icons/linux/1024.png differ diff --git a/src/main/icons/linux/128.png b/src/main/icons/linux/128.png new file mode 100755 index 0000000..05b2b35 Binary files /dev/null and b/src/main/icons/linux/128.png differ diff --git a/src/main/icons/linux/256.png b/src/main/icons/linux/256.png new file mode 100755 index 0000000..578fdc7 Binary files /dev/null and b/src/main/icons/linux/256.png differ diff --git a/src/main/icons/linux/512.png b/src/main/icons/linux/512.png new file mode 100755 index 0000000..0fbac4f Binary files /dev/null and b/src/main/icons/linux/512.png differ diff --git a/src/main/icons/mac/1024.png b/src/main/icons/mac/1024.png new file mode 100644 index 0000000..c1c8691 Binary files /dev/null and b/src/main/icons/mac/1024.png differ diff --git a/src/main/icons/mac/128.png b/src/main/icons/mac/128.png new file mode 100644 index 0000000..de9bee6 Binary files /dev/null and b/src/main/icons/mac/128.png differ diff --git a/src/main/icons/mac/256.png b/src/main/icons/mac/256.png new file mode 100644 index 0000000..c3a68b9 Binary files /dev/null and b/src/main/icons/mac/256.png differ diff --git a/src/main/icons/mac/512.png b/src/main/icons/mac/512.png new file mode 100644 index 0000000..b2fc07e Binary files /dev/null and b/src/main/icons/mac/512.png differ diff --git a/src/main/python/flowlayout.py b/src/main/python/flowlayout.py new file mode 100644 index 0000000..da6973d --- /dev/null +++ b/src/main/python/flowlayout.py @@ -0,0 +1,131 @@ +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +## All rights reserved. +## +## This file is part of the examples of PyQt. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +## the names of its contributors may be used to endorse or promote +## products derived from this software without specific prior written +## permission. +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## $QT_END_LICENSE$ +## +############################################################################# + + +from PyQt5.QtCore import QPoint, QRect, QSize, Qt +from PyQt5.QtWidgets import (QApplication, QLayout, QPushButton, QSizePolicy, + QWidget) + + +class FlowLayout(QLayout): + def __init__(self, parent=None, margin=0, spacing=-1): + super(FlowLayout, self).__init__(parent) + + if parent is not None: + self.setContentsMargins(margin, margin, margin, margin) + + self.setSpacing(spacing) + + self.itemList = [] + + def __del__(self): + item = self.takeAt(0) + while item: + item = self.takeAt(0) + + def addItem(self, item): + self.itemList.append(item) + + def count(self): + return len(self.itemList) + + def itemAt(self, index): + if index >= 0 and index < len(self.itemList): + return self.itemList[index] + + return None + + def takeAt(self, index): + if index >= 0 and index < len(self.itemList): + return self.itemList.pop(index) + + return None + + def expandingDirections(self): + return Qt.Orientations(Qt.Orientation(0)) + + def hasHeightForWidth(self): + return True + + def heightForWidth(self, width): + height = self.doLayout(QRect(0, 0, width, 0), True) + return height + + def setGeometry(self, rect): + super(FlowLayout, self).setGeometry(rect) + self.doLayout(rect, False) + + def sizeHint(self): + return self.minimumSize() + + def minimumSize(self): + size = QSize() + + for item in self.itemList: + size = size.expandedTo(item.minimumSize()) + + margin, _, _, _ = self.getContentsMargins() + + size += QSize(2 * margin, 2 * margin) + return size + + def doLayout(self, rect, testOnly): + x = rect.x() + y = rect.y() + lineHeight = 0 + + for item in self.itemList: + wid = item.widget() + spaceX = self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Horizontal) + spaceY = self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Vertical) + nextX = x + item.sizeHint().width() + spaceX + if nextX - spaceX > rect.right() and lineHeight > 0: + x = rect.x() + y = y + lineHeight + spaceY + nextX = x + item.sizeHint().width() + spaceX + lineHeight = 0 + + if not testOnly: + item.setGeometry(QRect(QPoint(x, y), item.sizeHint())) + + x = nextX + lineHeight = max(lineHeight, item.sizeHint().height()) + + return y + lineHeight - rect.y() diff --git a/src/main/python/main.py b/src/main/python/main.py new file mode 100644 index 0000000..8739b0c --- /dev/null +++ b/src/main/python/main.py @@ -0,0 +1,80 @@ +from fbs_runtime.application_context.PyQt5 import ApplicationContext +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QWidget, QTabWidget, QVBoxLayout, QPushButton, QLabel + +import sys + +from flowlayout import FlowLayout + +class TabbedKeycodes(QTabWidget): + + def __init__(self, parent=None): + super().__init__(parent) + self.tab_basic = QWidget() + layout = FlowLayout() + + for lbl in ["", "TODO", "Esc", "A", "B", "C", "D", "E", "F"]: + btn = QPushButton(lbl) + btn.setFixedSize(50, 50) + layout.addWidget(btn) + self.tab_basic.setLayout(layout) + + self.tab_media = QWidget() + self.tab_macro = QWidget() + + self.addTab(self.tab_basic, "Basic") + self.addTab(self.tab_media, "Media") + self.addTab(self.tab_macro, "Macro") + + +KEY_WIDTH = 40 +KEY_HEIGHT = KEY_WIDTH +KEY_SPACING = 10 + + +class KeyboardContainer(QWidget): + + def __init__(self, parent=None): + super().__init__(parent) + + self.setFixedSize(300, 300) + + for x, btn in enumerate(["Q", "W", "E", "R"]): + widget = QLabel(btn) + widget.setParent(self) + widget.setStyleSheet('background-color:red;') + widget.setAlignment(Qt.AlignCenter) + widget.setFixedSize(KEY_WIDTH, KEY_HEIGHT) + widget.move((KEY_WIDTH + KEY_SPACING) * x, 0) + + for x, btn in enumerate(["A", "S", "D", "F"]): + widget = QLabel(btn) + widget.setParent(self) + widget.setStyleSheet('background-color:red;') + widget.setAlignment(Qt.AlignCenter) + widget.setFixedSize(KEY_WIDTH, KEY_HEIGHT) + widget.move((KEY_WIDTH + KEY_SPACING) * (x + 0.25), KEY_HEIGHT + KEY_SPACING) + + +class MainWindow(QWidget): + + def __init__(self): + super().__init__() + + self.keyboard_container = KeyboardContainer() + + self.tabbed_keycodes = TabbedKeycodes() + + layout = QVBoxLayout() + layout.addWidget(self.keyboard_container) + layout.addWidget(self.tabbed_keycodes) + self.setLayout(layout) + + +if __name__ == '__main__': + appctxt = ApplicationContext() # 1. Instantiate ApplicationContext + window = MainWindow() + window.resize(1024, 768) + window.show() + exit_code = appctxt.app.exec_() # 2. Invoke appctxt.app.exec_() + sys.exit(exit_code)