├── src └── NodeNotePackage │ ├── __init__.py │ ├── NodeNote │ ├── __init__.py │ ├── Model │ │ ├── __init__.py │ │ ├── serializable.py │ │ ├── history.py │ │ ├── constants.py │ │ ├── serialize.proto │ │ └── serialize_pb2.py │ ├── Components │ │ ├── __init__.py │ │ ├── markdown_edit.py │ │ ├── effect_cutline.py │ │ ├── effect_background.py │ │ ├── effect_water.py │ │ ├── sub_view.py │ │ ├── effect_snow.py │ │ ├── todo.py │ │ ├── port.py │ │ └── draw.py │ ├── GraphicsView │ │ ├── __init__.py │ │ └── app.py │ └── Resources │ │ ├── __init__.py │ │ ├── Images │ │ ├── up.png │ │ ├── False.png │ │ ├── Plane.png │ │ ├── Todo.png │ │ ├── True.png │ │ ├── arrow.png │ │ ├── blank.png │ │ ├── cloudy.png │ │ ├── down.png │ │ ├── eraser.png │ │ ├── flower.png │ │ ├── horse.png │ │ ├── logo.png │ │ ├── pause.png │ │ ├── point.png │ │ ├── start.png │ │ ├── video.png │ │ ├── rainbow.ico │ │ ├── spin_up.png │ │ ├── sub view.png │ │ ├── Pistachio.png │ │ ├── add_video.png │ │ ├── add_widget.png │ │ ├── delete_path.png │ │ ├── down_arrow.png │ │ ├── draw_widget.png │ │ ├── spin_down.png │ │ ├── Truth Widget.png │ │ ├── left_bar_drag.png │ │ ├── Attribute Widget.png │ │ ├── Change flowing.png │ │ ├── add_line_video.png │ │ ├── add_line_widget.PNG │ │ ├── create_new_note.png │ │ ├── file_view_create.png │ │ ├── file_view_delete.png │ │ ├── scene_background.png │ │ ├── sidebar_delete.png │ │ ├── stylesheet-vline.png │ │ ├── stylesheet-branch-end.png │ │ ├── Change Background Image.png │ │ ├── common_background_image.png │ │ ├── stylesheet-branch-more.png │ │ ├── stylesheet-branch-open.png │ │ ├── stylesheet-branch-closed.png │ │ └── background_tree.svg │ │ ├── MultiLanguages │ │ ├── zh_CN.qm │ │ └── zh_CN.ts │ │ ├── Editor │ │ ├── markdown.html │ │ └── qwebchannel.js │ │ └── Stylesheets │ │ ├── dark_style.qss │ │ └── cute_style.qss │ └── Examples │ ├── __init__.py │ └── example.py ├── MANIFEST.in ├── requirements.txt ├── make.bat ├── LICENSE.txt ├── example.spec ├── .gitignore └── README.md /src/NodeNotePackage/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Model/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Components/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/GraphicsView/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/NodeNotePackage/Examples/__init__.py: -------------------------------------------------------------------------------- 1 | VERSION = "2.7.24" 2 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include src/NodeNotePackage/NodeNote/Resources/* 2 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/__init__.py: -------------------------------------------------------------------------------- 1 | from . import * 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/requirements.txt -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/up.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/False.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/False.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/Plane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/Plane.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/Todo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/Todo.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/True.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/True.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/arrow.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/blank.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/cloudy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/cloudy.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/down.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/eraser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/eraser.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/flower.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/flower.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/horse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/horse.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/logo.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/pause.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/point.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/start.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/video.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/rainbow.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/rainbow.ico -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/spin_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/spin_up.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/sub view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/sub view.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/Pistachio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/Pistachio.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/add_video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/add_video.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/add_widget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/add_widget.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/delete_path.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/delete_path.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/down_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/down_arrow.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/draw_widget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/draw_widget.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/spin_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/spin_down.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/Truth Widget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/Truth Widget.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/left_bar_drag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/left_bar_drag.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/MultiLanguages/zh_CN.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/MultiLanguages/zh_CN.qm -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/Attribute Widget.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/Attribute Widget.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/Change flowing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/Change flowing.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/add_line_video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/add_line_video.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/add_line_widget.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/add_line_widget.PNG -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/create_new_note.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/create_new_note.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/file_view_create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/file_view_create.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/file_view_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/file_view_delete.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/scene_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/scene_background.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/sidebar_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/sidebar_delete.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-vline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-vline.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-branch-end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-branch-end.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/Change Background Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/Change Background Image.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/common_background_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/common_background_image.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-branch-more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-branch-more.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-branch-open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-branch-open.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-branch-closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nomiuo/NodeNote/HEAD/src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-branch-closed.png -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Model/serializable.py: -------------------------------------------------------------------------------- 1 | """ 2 | The Serialization base class 3 | """ 4 | 5 | 6 | class Serializable: 7 | def __init__(self): 8 | self.id = id(self) 9 | 10 | def serialize(self): 11 | raise NotImplemented() 12 | 13 | def deserialize(self, data, hashmap: dict, view=None, flag=True): 14 | raise NotImplemented() 15 | -------------------------------------------------------------------------------- /make.bat: -------------------------------------------------------------------------------- 1 | :: lanague 2 | :: pylupdate5 ./src/NodeNotePackage/NodeNote/Components/attribute.py ./src/NodeNotePackage/NodeNote/Components/window.py ./src/NodeNotePackage/NodeNote/GraphicsView/view.py ./src/NodeNotePackage/NodeNote/Components/work_dir_interface.py -ts ./src/NodeNotePackage/NodeNote/Resources/MultiLanguages/zh_CN.ts 3 | lrelease ./src/NodeNotePackage/NodeNote/Resources/MultiLanguages/zh_CN.ts 4 | 5 | :: google protoc 6 | :: protoc -I./src/NodeNotePackage/NodeNote/Model/ --python_out=./src/NodeNotePackage/NodeNote/Model/ serialize.proto 7 | 8 | :: package 9 | :: pyinstaller --noconfirm ./example.spec 10 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022-2024 nomiuo 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/GraphicsView/app.py: -------------------------------------------------------------------------------- 1 | from PyQt5.QtWidgets import QApplication 2 | from PyQt5.QtCore import QEvent 3 | 4 | from .view import View 5 | 6 | 7 | class TabletApplication(QApplication): 8 | """ 9 | Custom QApplication to avoid the tablet event bug. 10 | """ 11 | 12 | def __init__(self, argv): 13 | """ 14 | Store the main window object for event(self, a0: Event) to use. 15 | 16 | Args: 17 | argv: Only used to inherit the parent class. 18 | 19 | """ 20 | 21 | super(TabletApplication, self).__init__(argv) 22 | self._window = None 23 | 24 | def event(self, a0: QEvent) -> bool: 25 | """ 26 | catch the tablet event of QGraphicsView. 27 | 28 | Args: 29 | a0: Event loop. 30 | 31 | Returns: 32 | Inherit the parent class 33 | 34 | """ 35 | if self._window: 36 | if a0.type() in (QEvent.TabletEnterProximity, QEvent.TabletLeaveProximity): 37 | View.tablet_used = a0.type() == QEvent.TabletEnterProximity 38 | 39 | return super(TabletApplication, self).event(a0) 40 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Components/markdown_edit.py: -------------------------------------------------------------------------------- 1 | from PyQt5 import QtCore, QtGui, QtWebEngineWidgets 2 | 3 | from ..Model.constants import DEBUG_MARKDOWN 4 | 5 | 6 | class MarkdownView(QtWebEngineWidgets.QWebEngineView): 7 | def __init__(self, mainwindow, parent=None) -> None: 8 | super().__init__(parent=parent) 9 | self.mainwindow = mainwindow 10 | self.dict_id = dict() 11 | 12 | def set_id(self, dict_id): 13 | self.dict_id = dict_id 14 | 15 | 16 | class MarkdownDocument(QtCore.QObject): 17 | save_text_signal = QtCore.pyqtSignal(dict, str) 18 | change_js_markdown_signal = QtCore.pyqtSignal(str) 19 | 20 | def __init__(self, page, parent=None) -> None: 21 | super().__init__(parent=parent) 22 | self.page = page 23 | 24 | @QtCore.pyqtSlot(dict) 25 | def return_text(self, dict_id): 26 | self.page.runJavaScript(f"returnText({dict_id});") 27 | 28 | @QtCore.pyqtSlot("QJsonObject", str) 29 | def save_text(self, dict_id: "QtCore.QJsonObject", text: str): 30 | if "old_focus_item" in dict_id.keys() and "new_focus_item" in dict_id.keys(): 31 | dict_id["old_focus_item"] = int(dict_id["old_focus_item"].toDouble()) 32 | dict_id["new_focus_item"] = int(dict_id["new_focus_item"].toDouble()) 33 | 34 | if DEBUG_MARKDOWN: 35 | print(f"Write 2.show_text->{dict_id}, {text}") 36 | 37 | self.save_text_signal.emit(dict_id, text) 38 | -------------------------------------------------------------------------------- /example.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | 4 | block_cipher = None 5 | 6 | 7 | a = Analysis(['src\\NodeNotePackage\\Examples\\example.py'], 8 | pathex=['C:\\Users\\Hello\\software\\nodenote\\NodeNote'], 9 | binaries=[], 10 | datas=[("src/NodeNotePackage/NodeNote/Resources", "src/NodeNotePackage/NodeNote/Resources")], 11 | hiddenimports=[], 12 | hookspath=[], 13 | hooksconfig={}, 14 | runtime_hooks=[], 15 | excludes=[], 16 | win_no_prefer_redirects=False, 17 | win_private_assemblies=False, 18 | cipher=block_cipher, 19 | noarchive=False) 20 | pyz = PYZ(a.pure, a.zipped_data, 21 | cipher=block_cipher) 22 | 23 | exe = EXE(pyz, 24 | a.scripts, 25 | [], 26 | exclude_binaries=True, 27 | name='NodeNote', 28 | debug=False, 29 | bootloader_ignore_signals=False, 30 | strip=False, 31 | upx=True, 32 | console=False, 33 | disable_windowed_traceback=False, 34 | target_arch=None, 35 | codesign_identity=None, 36 | entitlements_file=None , icon='src\\NodeNotePackage\\NodeNote\\Resources\\Images\\rainbow.ico') 37 | coll = COLLECT(exe, 38 | a.binaries, 39 | a.zipfiles, 40 | a.datas, 41 | strip=False, 42 | upx=True, 43 | upx_exclude=[], 44 | name='NodeNote') 45 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Components/effect_cutline.py: -------------------------------------------------------------------------------- 1 | from PyQt5 import QtWidgets, QtGui, QtCore 2 | from ..Model import constants 3 | 4 | 5 | __all__ = ['EffectCutline'] 6 | 7 | 8 | class EffectCutline(QtWidgets.QGraphicsItem): 9 | 10 | def __init__(self, parent=None): 11 | """ 12 | Cutline which is used to delete the pipes. 13 | Delete logic is defined in manager. 14 | """ 15 | 16 | super(EffectCutline, self).__init__(parent) 17 | self.line_points = [] 18 | self.pen = QtGui.QPen(QtCore.Qt.white, 2) 19 | self.pen.setDashPattern([3, 2]) 20 | self.setZValue(constants.Z_VAL_CUTLINE) 21 | 22 | def boundingRect(self) -> QtCore.QRectF: 23 | if self.line_points: 24 | x__min_point = min([point.x() for point in self.line_points]) 25 | y__min_point = min([point.y() for point in self.line_points]) 26 | x__max_point = max([point.x() for point in self.line_points]) 27 | y__max_point = max([point.y() for point in self.line_points]) 28 | return QtCore.QRectF(x__min_point, y__min_point, x__max_point - x__min_point, y__max_point - y__min_point) 29 | else: 30 | return QtCore.QRectF(0, 0, 1, 1) 31 | 32 | 33 | def paint(self, painter, option, widget=None) -> None: 34 | painter.setRenderHint(QtGui.QPainter.Antialiasing) 35 | painter.setBrush(QtCore.Qt.NoBrush) 36 | painter.setPen(self.pen) 37 | 38 | poly = QtGui.QPolygonF(self.line_points) 39 | painter.drawPolyline(poly) 40 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Components/effect_background.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from ..Model import constants 4 | 5 | from PyQt5 import QtWidgets, QtCore, QtGui, QtSvg 6 | 7 | 8 | class EffectBackground(QtSvg.QGraphicsSvgItem): 9 | 10 | name = constants.background_image_path 11 | 12 | def __init__(self, view, parent=None): 13 | """ 14 | Scene svg background image. 15 | 16 | Args: 17 | view: The manager. 18 | parent: Parent item. 19 | """ 20 | 21 | super(EffectBackground, self).__init__(parent) 22 | self.view = view 23 | self.width = 1080 24 | self.height = 900 25 | self.svg = QtSvg.QSvgRenderer(os.path.join(constants.work_dir, self.name)) 26 | self.setSharedRenderer(self.svg) 27 | self.setCacheMode(QtWidgets.QGraphicsItem.ItemCoordinateCache) 28 | 29 | def resize(self, width, height): 30 | """ 31 | Change the size. 32 | 33 | Args: 34 | width: The manager width. 35 | height: The manager height. 36 | 37 | """ 38 | 39 | self.width = width 40 | self.height = height 41 | 42 | def change_svg(self, path): 43 | """ 44 | Change the svg image. 45 | 46 | Args: 47 | path: relative path of Svg image path. 48 | 49 | """ 50 | 51 | self.name = path 52 | self.svg = QtSvg.QSvgRenderer(os.path.join(constants.work_dir, path)) 53 | self.setSharedRenderer(self.svg) 54 | 55 | def boundingRect(self) -> QtCore.QRectF: 56 | return QtCore.QRectF(0, 0, self.width, self.height) 57 | 58 | def paint(self, painter: QtGui.QPainter, option: QtWidgets.QStyleOptionGraphicsItem, widget=None) -> None: 59 | super(EffectBackground, self).paint(painter, option, widget) 60 | painter.save() 61 | self.renderer().render(painter, self.boundingRect()) 62 | painter.restore() 63 | -------------------------------------------------------------------------------- /src/NodeNotePackage/Examples/example.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Example.py - run the application 4 | Copyright 2021 ye tao 5 | Distributed under MPL-2.0 license. See LICENSE for more information 6 | 7 | # v2.7.4: 8 | ## Debug: 9 | - Restore the scene rect. 10 | - Delete pipes correctly. 11 | """ 12 | 13 | import os 14 | import sys 15 | import time 16 | 17 | sys.path.insert(0, os.path.abspath(os.path.join(__file__, "../../../../"))) 18 | sys.path.insert(0, os.path.abspath(os.path.join(__file__, "../../../"))) 19 | 20 | from PyQt5.QtCore import QLocale, QTranslator, qInstallMessageHandler 21 | from PyQt5 import QtWidgets, QtCore 22 | from src.NodeNotePackage.NodeNote.Components import work_dir_interface 23 | from src.NodeNotePackage.NodeNote.GraphicsView.app import TabletApplication 24 | 25 | 26 | def message_output(msg_type, context, msg): 27 | try: 28 | if msg_type >= 2: 29 | with open("exception_log.txt", "a", encoding="utf-8") as log: 30 | log.write( 31 | f"{msg}, type: {msg_type} at {time.asctime(time.localtime(time.time()))}\n" 32 | ) 33 | except Exception as e: 34 | pass 35 | 36 | 37 | if __name__ == "__main__": 38 | qInstallMessageHandler(message_output) 39 | 40 | QtWidgets.QApplication.setAttribute( 41 | QtCore.Qt.AA_EnableHighDpiScaling, True 42 | ) # enable highdpi scaling 43 | QtWidgets.QApplication.setAttribute( 44 | QtCore.Qt.AA_UseHighDpiPixmaps, True 45 | ) # use highdpi icons 46 | 47 | app = TabletApplication(["", "--no-sandbox"]) 48 | 49 | # load language 50 | local = QLocale() 51 | lan = QLocale.language(local) 52 | trans = QTranslator() 53 | if lan == QLocale.Chinese: 54 | trans.load("src/NodeNotePackage/NodeNote/Resources/MultiLanguages/zh_CN.qm") 55 | app.installTranslator(trans) 56 | 57 | # work dir interface 58 | work_dir_widget = work_dir_interface.WorkDirInterface(app, trans) 59 | work_dir_widget.show() 60 | 61 | app.exec_() 62 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Model/history.py: -------------------------------------------------------------------------------- 1 | from ..Model import serialize_pb2 2 | from PyQt5 import QtGui, QtCore 3 | 4 | 5 | class History: 6 | """ 7 | Serialization for undo && redo. 8 | 9 | """ 10 | def __init__(self, view): 11 | """ 12 | Create the list to store Serialization. 13 | 14 | Args: 15 | view: The manager. 16 | """ 17 | 18 | self.view = view 19 | 20 | self.history_stack = [] 21 | self.history_current_step = -1 22 | self.history_limit = 50 23 | 24 | def undo(self): 25 | """ 26 | Undo. 27 | 28 | """ 29 | 30 | if self.history_current_step > 0: 31 | self.history_current_step -= 1 32 | self.restore_history() 33 | 34 | def redo(self): 35 | """ 36 | Redo. 37 | 38 | """ 39 | 40 | if self.history_current_step + 1 < len(self.history_stack): 41 | self.history_current_step += 1 42 | self.restore_history() 43 | 44 | def store_history(self, desc): 45 | """ 46 | Store the Serialization into list. 47 | 48 | Args: 49 | desc: The description of the operation. 50 | 51 | """ 52 | 53 | if self.history_current_step + 1 < len(self.history_stack): 54 | self.history_stack = self.history_stack[0: self.history_current_step] 55 | 56 | if self.history_current_step + 1 >= self.history_limit: 57 | self.history_stack = self.history_stack[1:] 58 | self.history_current_step -= 1 59 | 60 | hs = self.create_history_stamp(desc) 61 | self.history_stack.append(hs) 62 | self.history_current_step += 1 63 | 64 | def restore_history(self): 65 | """ 66 | Restore the Serialization from list. 67 | 68 | """ 69 | 70 | self.restore_history_stamp(self.history_stack[self.history_current_step]) 71 | 72 | def create_history_stamp(self, desc): 73 | """ 74 | Create Serialization. 75 | 76 | Args: 77 | desc: The description of the operation. 78 | 79 | Returns: 80 | history_stamp: The Serialization dictionary. 81 | 82 | """ 83 | view_serialization = serialize_pb2.ViewSerialization() 84 | current_scene_serialization = view_serialization.scene_serialization.add() 85 | self.view.current_scene.serialize(current_scene_serialization) 86 | history_stamp = { 87 | 'desc': desc, 88 | 'snapshot': current_scene_serialization 89 | } 90 | return history_stamp 91 | 92 | def restore_history_stamp(self, history_stamp): 93 | """ 94 | Deserialization. 95 | 96 | Args: 97 | history_stamp: The Serialization dictionary. 98 | 99 | """ 100 | 101 | # Delete items 102 | for item in self.view.current_scene.items(): 103 | item.setSelected(True) 104 | self.view.delete_widgets(QtGui.QKeyEvent(QtGui.QKeyEvent.KeyPress, QtCore.Qt.Key_Delete, QtCore.Qt.NoModifier), 105 | history_flag=True) 106 | 107 | # Serialization 108 | self.view.current_scene.deserialize(history_stamp['snapshot'], hashmap={}, view=self.view, flag=True) 109 | self.view.current_scene.deserialize(history_stamp['snapshot'], hashmap={}, view=self.view, flag=False) 110 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Components/effect_water.py: -------------------------------------------------------------------------------- 1 | from PyQt5 import QtCore, QtGui, QtWidgets 2 | 3 | __all__ = ["EffectWater"] 4 | 5 | 6 | class EffectWater(QtWidgets.QWidget): 7 | """ 8 | Lmb effect. 9 | 10 | """ 11 | def __init__(self, parent=None): 12 | """ 13 | Create Lmb effect. 14 | 15 | Args: 16 | parent: Parent item. 17 | """ 18 | 19 | super(EffectWater, self).__init__(parent) 20 | 21 | # water ui 22 | self.water_color = QtGui.QColor("#FF6699FF") 23 | self.circle_big_size = 10.0 24 | self.circle_small_size = 0.0 25 | self.design_ui() 26 | 27 | # water animation 28 | self.water_animation = QtCore.QVariantAnimation(self) 29 | 30 | def design_ui(self): 31 | """ 32 | Draw the effect. 33 | 34 | """ 35 | 36 | self.setFixedSize(QtCore.QSize(int(self.circle_big_size * 2), int(self.circle_big_size * 2))) 37 | self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool) 38 | self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True) 39 | self.setAutoFillBackground(True) 40 | palette = QtGui.QPalette() 41 | palette.setColor(QtGui.QPalette.Window, QtGui.QColor(255, 255, 255, 255)) 42 | self.setPalette(palette) 43 | self.setAttribute(QtCore.Qt.WA_DeleteOnClose) 44 | 45 | def move(self, a0) -> None: 46 | """ 47 | Moved by mouse. 48 | 49 | Args: 50 | a0: Mouse QPoint. 51 | 52 | """ 53 | 54 | true_pos = a0 - QtCore.QPoint(int(self.circle_big_size), int(self.circle_big_size)) 55 | super(EffectWater, self).move(QtCore.QPoint(true_pos.x(), true_pos.y())) 56 | 57 | def show(self): 58 | """ 59 | Show the effect. 60 | 61 | """ 62 | 63 | super(EffectWater, self).show() 64 | self.water_animation.setStartValue(0.0) 65 | self.water_animation.setEndValue(self.circle_big_size) 66 | self.water_animation.setDuration(350) 67 | self.water_animation.valueChanged.connect(self.circle_repaint) 68 | self.water_animation.finished.connect(self.close) 69 | self.water_animation.start() 70 | 71 | def circle_repaint(self, value): 72 | """ 73 | Repaint the effect. 74 | 75 | Args: 76 | value: The circle difference radius. 77 | 78 | """ 79 | 80 | self.circle_small_size = value 81 | self.update() 82 | 83 | def paintEvent(self, a0) -> None: 84 | """ 85 | Draw the effect. 86 | 87 | Args: 88 | a0: QPaintevent. 89 | 90 | """ 91 | 92 | # painter 93 | painter = QtGui.QPainter(self) 94 | painter.setRenderHint(QtGui.QPainter.Antialiasing) 95 | painter.setPen(QtCore.Qt.NoPen) 96 | painter.setBrush(QtGui.QBrush(self.water_color)) 97 | # paint two circle 98 | big_circle = QtGui.QPainterPath() 99 | big_circle.addEllipse(QtCore.QPointF(self.circle_big_size, self.circle_big_size), 100 | self.circle_big_size, self.circle_big_size) 101 | small_circle = QtGui.QPainterPath() 102 | small_circle.addEllipse(QtCore.QPointF(self.circle_big_size, self.circle_big_size), 103 | self.circle_small_size, self.circle_small_size) 104 | circle = big_circle - small_circle 105 | painter.drawPath(circle) 106 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Components/sub_view.py: -------------------------------------------------------------------------------- 1 | """ 2 | sub_view.py - Create sub view manager. 3 | """ 4 | 5 | 6 | from PyQt5 import QtWidgets, QtCore 7 | from ..GraphicsView import view 8 | from ..Model import constants, serializable 9 | 10 | 11 | __all__ = ['ProxyView'] 12 | 13 | 14 | class ProxyView(QtWidgets.QGraphicsProxyWidget, serializable.Serializable): 15 | """ 16 | Create embedded view manager. THe function is same as the root view. 17 | But Qt QGraphicsView does not support the embedded sub view, the input 18 | method is not working in some widgets, I figure out this problem in attribute 19 | widget/InputField. 20 | 21 | """ 22 | 23 | def __init__(self, root_window, parent=None): 24 | """ 25 | Create embedded view manager. 26 | 27 | Args: 28 | root_window: Main window to get the root manager. 29 | parent: Parent item. 30 | """ 31 | 32 | super(ProxyView, self).__init__(parent) 33 | 34 | # input method 35 | self.setAttribute(QtCore.Qt.WA_InputMethodEnabled, True) 36 | self.setAttribute(QtCore.Qt.WA_KeyCompression, True) 37 | self.setFocusPolicy(QtCore.Qt.WheelFocus) 38 | 39 | # new widgets 40 | self.root_window = root_window 41 | self.sub_view_widget = QtWidgets.QWidget() 42 | self.sub_view_widget_layout = QtWidgets.QVBoxLayout() 43 | self.sub_view_widget_view = view.View(self.root_window, None, False, self) 44 | # connections 45 | # init layout 46 | self.sub_view_widget_layout.setContentsMargins(0, 0, 0, 0) 47 | self.sub_view_widget_layout.setSpacing(0) 48 | # init sub view widget 49 | self.sub_view_widget_layout.addWidget(self.sub_view_widget_view) 50 | self.sub_view_widget.setLayout(self.sub_view_widget_layout) 51 | # init proxy widget 52 | self.setWidget(self.sub_view_widget) 53 | self.setZValue(constants.Z_VAL_NODE) 54 | 55 | # index 56 | self.item_row = 0 57 | self.item_column = 0 58 | 59 | def mousePressEvent(self, event: 'QtWidgets.QGraphicsSceneMouseEvent') -> None: 60 | super(ProxyView, self).mousePressEvent(event) 61 | self.root_window.view_widget.current_scene.clearSelection() 62 | self.scene().clearSelection() 63 | 64 | def serialize(self, subview_serialization=None): 65 | """ 66 | Serialization. 67 | 68 | Args: 69 | subview_serialization: Google protobuff object. 70 | 71 | """ 72 | 73 | subview_serialization.subview_id = self.id 74 | subview_serialization.size.append(self.size().width()) 75 | subview_serialization.size.append(self.size().height()) 76 | subview_serialization.subview_location.append(self.item_row) 77 | subview_serialization.subview_location.append(self.item_column) 78 | self.sub_view_widget_view.serialize(subview_serialization.subview.add()) 79 | 80 | def deserialize(self, data, hashmap: dict, view=None, flag=True): 81 | """ 82 | Deserialization. 83 | 84 | Args: 85 | data: Google protobuff object. 86 | hashmap: Hashmap. 87 | view: The manager. 88 | flag: Deserialize in two times. 89 | 90 | """ 91 | 92 | self.id = data.subview_id 93 | self.resize(data.size[0], data.size[1]) 94 | self.item_row = data.subview_location[0] 95 | self.item_column = data.subview_location[1] 96 | self.sub_view_widget_view.deserialize(data.subview[0], hashmap, view, flag) 97 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | !example.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | cover/ 54 | 55 | # Translations 56 | *.mo 57 | *.pot 58 | 59 | # Django stuff: 60 | *.log 61 | local_settings.py 62 | db.sqlite3 63 | db.sqlite3-journal 64 | 65 | # Flask stuff: 66 | instance/ 67 | .webassets-cache 68 | 69 | # Scrapy stuff: 70 | .scrapy 71 | 72 | # Sphinx documentation 73 | docs/_build/ 74 | 75 | # PyBuilder 76 | .pybuilder/ 77 | target/ 78 | 79 | # Jupyter Notebook 80 | .ipynb_checkpoints 81 | 82 | # IPython 83 | profile_default/ 84 | ipython_config.py 85 | 86 | # pyenv 87 | # For a library or package, you might want to ignore these files since the code is 88 | # intended to run in multiple environments; otherwise, check them in: 89 | # .python-version 90 | 91 | # pipenv 92 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 93 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 94 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 95 | # install all needed dependencies. 96 | #Pipfile.lock 97 | 98 | # poetry 99 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 100 | # This is especially recommended for binary packages to ensure reproducibility, and is more 101 | # commonly ignored for libraries. 102 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 103 | #poetry.lock 104 | 105 | # pdm 106 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 107 | #pdm.lock 108 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 109 | # in version control. 110 | # https://pdm.fming.dev/#use-with-ide 111 | .pdm.toml 112 | 113 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 114 | __pypackages__/ 115 | 116 | # Celery stuff 117 | celerybeat-schedule 118 | celerybeat.pid 119 | 120 | # SageMath parsed files 121 | *.sage.py 122 | 123 | # Environments 124 | .env 125 | .venv 126 | env/ 127 | venv/ 128 | ENV/ 129 | env.bak/ 130 | venv.bak/ 131 | 132 | # Spyder project settings 133 | .spyderproject 134 | .spyproject 135 | 136 | # Rope project settings 137 | .ropeproject 138 | 139 | # mkdocs documentation 140 | /site 141 | 142 | # mypy 143 | .mypy_cache/ 144 | .dmypy.json 145 | dmypy.json 146 | 147 | # Pyre type checker 148 | .pyre/ 149 | 150 | # pytype static type analyzer 151 | .pytype/ 152 | 153 | # Cython debug symbols 154 | cython_debug/ 155 | 156 | # IDE 157 | .idea/ 158 | .vsocode/ 159 | 160 | # Software 161 | **/LASTDIR.json 162 | 163 | # SELF 164 | LASTDIR.json 165 | RunNodeNote.sh 166 | **/exception_log.txt -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Model/constants.py: -------------------------------------------------------------------------------- 1 | """ 2 | The model parameters. 3 | """ 4 | 5 | import os 6 | 7 | from PyQt5.QtWidgets import QGraphicsItem 8 | from PyQt5 import QtWidgets, QtGui, QtCore 9 | 10 | # === DIR === 11 | work_dir = os.path.join(os.path.dirname(__file__), "../") 12 | 13 | # === UI === 14 | # attribute widget ui 15 | input_text_font = QtWidgets.QApplication([]).font() 16 | input_text_font_color = QtGui.QColor(0, 0, 0, 255) 17 | attribute_color = QtGui.QColor(254, 253, 254, 255) 18 | attribute_selected_color = QtGui.QColor(255, 255, 255, 30) 19 | attribute_border_color = QtGui.QColor(46, 57, 66, 255) 20 | attribute_selected_border_color = QtGui.QColor(254, 207, 42, 255) 21 | attribute_width_flag = -1 22 | # logic widget ui 23 | logic_background_color = QtGui.QColor(240, 251, 158, 255) 24 | logic_selected_background_color = QtGui.QColor(255, 255, 255, 30) 25 | logic_border_color = QtGui.QColor(46, 57, 66, 255) 26 | logic_selected_border_color = QtGui.QColor(254, 207, 42, 255) 27 | # pipe widget ui 28 | pipe_width = 2 29 | pipe_color = QtGui.QColor(225, 192, 241, 255) 30 | pipe_selected_color = QtGui.QColor(0, 153, 121, 255) 31 | pipe_font = QtWidgets.QApplication([]).font() 32 | pipe_font_color = QtGui.QColor(0, 0, 0, 255) 33 | # port widget ui 34 | port_width = 10.0 35 | port_color = QtGui.QColor(255, 255, 255, 255) 36 | port_border_color = QtGui.QColor(255, 255, 255, 255) 37 | port_hovered_color = QtGui.QColor(118, 184, 182, 255) 38 | port_hovered_border_color = QtGui.QColor(99, 180, 255, 255) 39 | port_activated_color = QtGui.QColor(14, 45, 59, 255) 40 | port_activated_border_color = QtGui.QColor(107, 166, 193, 255) 41 | # draw widget ui 42 | draw_color = QtGui.QColor(QtCore.Qt.red) 43 | draw_pen_width = 10 44 | # background image 45 | background_image_path = "Resources/Images/background_tree.svg" 46 | flowing_image = 'Resources/Images/flower.png' 47 | # view flag 48 | view_line_flag = True 49 | view_undo_flag = True 50 | view_flowing_flag = True 51 | # scene flag 52 | scene_background_image_flag = False 53 | # style 54 | style_path = "Resources/Stylesheets/cute_style.qss" 55 | 56 | # === DEBUG === 57 | DEBUG_EFFECT_SNOW = False 58 | DEBUG_TUPLE_NODE_SCALE = False 59 | DEBUG_VIEW_CHANGE_SCALE = False 60 | DEBUG_DRAW_PIPE = False 61 | DEBUG_TEXT_CHANGED = False 62 | DEBUG_PYTHON_SYNTAXHIGHTLIGHTER = False 63 | DEBUG_RICHTEXT = False 64 | DEBUG_CUT_LINE = False 65 | DEBUG_COLLIDING = False 66 | DEBUG_HISTORY = False 67 | DEBUG_DESERIALIZE = False 68 | DEBUG_FONT = False 69 | DEBUG_FILE_SAVE = False 70 | DEBUG_ATTRIBUTE_INDEX = False 71 | DEBUG_MARKDOWN = False 72 | 73 | # === DRAW STACK ORDER === 74 | Z_VAL_PIPE = 2 75 | Z_VAL_PIPE_DONE = 4 76 | Z_VAL_NODE = 3 77 | Z_VAL_PORT = 3 78 | Z_VAL_CUTLINE = 5 79 | Z_VAL_CONTAINERS = 6 80 | 81 | # === NODE === 82 | NODE_WIDTH = 150 83 | NODE_HEIGHT = 70 84 | NODE_LAYOUT_MARGINS = 5 85 | NODE_ICON_SIZE = 24 86 | NODE_SEL_COLOR = (255, 255, 255, 30) 87 | NODE_SEL_BORDER_COLOR = (254, 207, 42, 255) 88 | 89 | # === ITEM CACHE MODE === 90 | ITEM_CACHE_MODE = QGraphicsItem.DeviceCoordinateCache 91 | 92 | # === NODE TYPE === 93 | INPUT_NODE_TYPE = 0 94 | OUTPUT_NODE_TYPE = 1 95 | 96 | # === DRAW LINE === 97 | MODE_NOOP = 1 98 | MODE_PIPE_DRAG = 2 99 | MODE_PIPE_CUT = 3 100 | MODE_CONTAINER = 4 101 | 102 | # === PIPE === 103 | PIPE_STATUS_NEW = 0 104 | PIPE_STATUS_CHANGE = 1 105 | 106 | # === PIPE START STATUS === 107 | INPUT_NODE_START = 0 108 | OUTPUT_NODE_START = 1 109 | 110 | # === COLLIDING === 111 | COLLIDING_ATTRIBUTE = 0 112 | COLLIDING_PIPE = 1 113 | COLLIDING_NONE = 2 114 | 115 | # === PIPE MOVE === 116 | PIPE_FIRST = 0 117 | PIPE_MOVEING = 1 118 | PIPE_COMMON = 2 119 | PIPE_UPDATE = 3 120 | 121 | # === MOVE === 122 | down = 0 123 | up = 1 124 | left = 2 125 | right = 3 126 | 127 | 128 | def init_path(path): 129 | """ 130 | Init work dir 131 | 132 | Agrs: 133 | paht: work dir. 134 | 135 | """ 136 | global work_dir 137 | 138 | work_dir = path 139 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Components/effect_snow.py: -------------------------------------------------------------------------------- 1 | import random 2 | import os 3 | 4 | from PyQt5 import QtCore, QtGui, QtWidgets, sip 5 | from ..Model import constants 6 | 7 | 8 | class EffectSkyWidget(QtWidgets.QWidget): 9 | 10 | def __init__(self, view_widget, parent=None): 11 | """ 12 | Create the sky contains flowing image. 13 | 14 | Args: 15 | view_widget: The manager. 16 | parent: Parent item. 17 | """ 18 | 19 | super(EffectSkyWidget, self).__init__(parent) 20 | self.view_widget = view_widget 21 | self.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents) 22 | self.path_list = list() 23 | self.index = 0 24 | self.timer = QtCore.QTimer() 25 | self.timer.timeout.connect(self.snow_create) 26 | self.timer.start(6000) 27 | 28 | def snow_create(self): 29 | """ 30 | Create flowing image. 31 | 32 | """ 33 | 34 | # DEBUG 35 | if constants.DEBUG_EFFECT_SNOW: 36 | print("1-Debug: snow_create function running") 37 | # create snow widget and its path 38 | snow_widget = SnowWidget(self) 39 | opacity_snow = QtWidgets.QGraphicsOpacityEffect(snow_widget) 40 | run_path = QtCore.QPropertyAnimation(snow_widget, b"pos") 41 | opacity_path = QtCore.QPropertyAnimation(opacity_snow, b"opacity") 42 | self.path_list.append(QtCore.QParallelAnimationGroup()) 43 | self.snow_falling(snow_widget, run_path, opacity_path, self.path_list[self.index]) 44 | self.index += 1 45 | 46 | def snow_falling(self, snow_widget, run_path, opacity_path, path_group): 47 | """ 48 | Falling image. 49 | 50 | Args: 51 | snow_widget: The flowing image. 52 | run_path: The flowing path. 53 | opacity_path: The opacity. 54 | path_group: The start object. 55 | 56 | """ 57 | 58 | # DEBUG 59 | if constants.DEBUG_EFFECT_SNOW: 60 | print("2-Debug: snow_falling function running") 61 | # pos and size 62 | start_x = random.randint(0, int(self.width())) 63 | start_y = random.randint(0, int(self.height())) 64 | random_size = random.randint(0, 9) 65 | width = 24 if random_size >= 6 else (18 if random_size >= 3 else 12) 66 | height = 24 if random_size >= 6 else (18 if random_size >= 3 else 12) 67 | snow_widget.setGeometry(start_x, start_y, width, height) 68 | snow_widget.setVisible(True) 69 | 70 | # fall speed 71 | fall_time_run_path = random.randint(25000, 30000) 72 | fall_time_opacity_path = random.randint(25000, 30000) 73 | run_path.setStartValue(QtCore.QPoint(start_x, start_y)) 74 | run_path.setEndValue(QtCore.QPoint(start_x, self.height())) 75 | run_path.setDuration(fall_time_run_path) 76 | run_path.setEasingCurve(QtCore.QEasingCurve.InOutCubic) 77 | opacity_path.setStartValue(1) 78 | opacity_path.setEndValue(0) 79 | opacity_path.setDuration(fall_time_opacity_path) 80 | path_group.addAnimation(run_path) 81 | path_group.addAnimation(opacity_path) 82 | 83 | # falling 84 | path_group.start() 85 | path_group.finished.connect(lambda: self.snow_end(snow_widget, path_group)) 86 | 87 | def snow_end(self, snow_widget, path_group): 88 | """ 89 | Delete the finished image. 90 | 91 | Args: 92 | snow_widget: 93 | path_group: 94 | 95 | Returns: 96 | 97 | """ 98 | sip.delete(snow_widget) 99 | self.index -= 1 100 | self.path_list.remove(path_group) 101 | if constants.DEBUG_EFFECT_SNOW: 102 | print("3-Debug: delete snow widget successfully") 103 | 104 | 105 | class SnowWidget(QtWidgets.QWidget): 106 | image_path = constants.flowing_image 107 | 108 | def __init__(self, parent=None): 109 | """ 110 | Create flowing image. 111 | 112 | Args: 113 | parent: Parent item. 114 | """ 115 | 116 | super(SnowWidget, self).__init__(parent) 117 | 118 | def change_image_path(self, path): 119 | """ 120 | Change the flowing image. 121 | 122 | Args: 123 | path: relative path of The flowing image path. 124 | 125 | """ 126 | 127 | self.image_path = path 128 | self.update() 129 | 130 | def paintEvent(self, event): 131 | """ 132 | Draw the flowing image. 133 | 134 | Args: 135 | event: QPaintevent. 136 | 137 | """ 138 | 139 | super().paintEvent(event) 140 | painter = QtGui.QPainter(self) 141 | painter.drawPixmap(self.rect(), QtGui.QPixmap(os.path.join(constants.work_dir, self.image_path)), QtCore.QRect()) 142 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Editor/markdown.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 146 | 147 | 161 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Components/todo.py: -------------------------------------------------------------------------------- 1 | """ 2 | todo.py - Todo widget is used to keep track of your plan. 3 | 4 | """ 5 | 6 | import os 7 | import time 8 | 9 | from PyQt5 import QtWidgets, QtCore, QtGui 10 | 11 | from ..Components.attribute import AttributeWidget, BaseWidget 12 | from ..Model import serializable, constants 13 | 14 | 15 | __all__ = ['Todo'] 16 | 17 | 18 | class Todo(BaseWidget, serializable.Serializable): 19 | """ 20 | Todo widget with: 21 | - Plan text input. 22 | - Used time all time. 23 | - Used time this time. 24 | 25 | """ 26 | 27 | close_flag = False # Used to store time when the note window was closed 28 | 29 | def __init__(self, parent=None): 30 | """ 31 | Create the Todo widget 32 | 33 | Args: 34 | parent: Parent item. 35 | """ 36 | 37 | super(BaseWidget, self).__init__(parent) 38 | self.context_flag = False 39 | self.parent_item = parent 40 | 41 | # common setting 42 | self.setZValue(constants.Z_VAL_NODE) 43 | self.setFlags(QtWidgets.QGraphicsItem.ItemIsSelectable) 44 | 45 | # widget 46 | self.central_layout = QtWidgets.QGraphicsLinearLayout(QtCore.Qt.Vertical) 47 | self.control_layout = QtWidgets.QGraphicsLinearLayout(QtCore.Qt.Horizontal) 48 | 49 | self.edit = QtWidgets.QLineEdit("task") 50 | 51 | self.time_show = QtWidgets.QLabel("0:0:0 + 0:0:0") 52 | self.time_show.setObjectName("todo_label") 53 | self.time_show.setMinimumWidth(135) 54 | 55 | self.start_png = QtGui.QIcon(QtGui.QPixmap(os.path.abspath(os.path.join(constants.work_dir, 56 | r'Resources/Images/start.png'))).scaled( 57 | 10, 58 | 10, 59 | QtCore.Qt.IgnoreAspectRatio, 60 | QtCore.Qt.SmoothTransformation 61 | )) 62 | self.pause_png = QtGui.QIcon(QtGui.QPixmap(os.path.abspath(os.path.join(constants.work_dir, 63 | r'Resources/Images/pause.png'))).scaled( 64 | 10, 65 | 10, 66 | QtCore.Qt.IgnoreAspectRatio, 67 | QtCore.Qt.SmoothTransformation 68 | )) 69 | self.time_button = QtWidgets.QToolButton() 70 | self.time_button.setIcon(self.start_png) 71 | 72 | self.graphics_edit = QtWidgets.QGraphicsProxyWidget() 73 | self.graphics_edit.setWidget(self.edit) 74 | 75 | self.graphics_show = QtWidgets.QGraphicsProxyWidget() 76 | self.graphics_show.setWidget(self.time_show) 77 | 78 | self.graphics_button = QtWidgets.QGraphicsProxyWidget() 79 | self.graphics_button.setWidget(self.time_button) 80 | 81 | self.central_layout.addItem(self.graphics_edit) 82 | self.central_layout.addItem(self.control_layout) 83 | self.control_layout.addItem(self.graphics_show) 84 | self.control_layout.addItem(self.graphics_button) 85 | self.setLayout(self.central_layout) 86 | 87 | # control 88 | self.start = True 89 | self.total_time = 0 90 | self.start_time = 0 91 | self.use_time = 0 92 | self.timer = QtCore.QTimer(self) 93 | self.timer.timeout.connect(self.time_update) 94 | self.time_button.pressed.connect(self.turn_start if self.start else self.turn_pause) 95 | 96 | # layout 97 | self.item_row = 0 98 | self.item_column = 0 99 | 100 | def paint(self, painter: QtGui.QPainter, option, widget=None) -> None: 101 | """ 102 | Draw the border. 103 | 104 | Args: 105 | painter: draw pen 106 | option: None 107 | widget: None 108 | 109 | """ 110 | 111 | painter.save() 112 | pen = QtGui.QPen(AttributeWidget.border_color, 0.5) 113 | selected_pen = QtGui.QPen(AttributeWidget.selected_border_color, 0.5) 114 | painter.setPen(pen if not self.isSelected() else selected_pen) 115 | painter.setBrush(QtCore.Qt.NoBrush) 116 | painter.drawRoundedRect(0, 0, self.size().width(), self.size().height(), 5, 5) 117 | 118 | painter.restore() 119 | 120 | def turn_start(self): 121 | """ 122 | Start clock of this time. 123 | 124 | """ 125 | 126 | self.time_button.setIcon(self.pause_png) 127 | self.timer.start(1000) 128 | self.start_time = time.time() 129 | self.time_button.pressed.connect(self.turn_pause) 130 | 131 | def turn_pause(self): 132 | """ 133 | End clock of this time. 134 | 135 | """ 136 | 137 | self.time_button.setIcon(self.start_png) 138 | self.timer.stop() 139 | self.time_button.pressed.connect(self.turn_start) 140 | self.total_time += self.use_time 141 | self.start_time = time.time() 142 | self.time_update() 143 | 144 | def time_update(self): 145 | """ 146 | Update the the text of the time. 147 | 148 | """ 149 | 150 | total_time_hour = int(self.total_time // 60 // 60) 151 | total_time_min = int((self.total_time // 60) - 60 * total_time_hour) 152 | total_time_sec = int(self.total_time - 60 * 60 * total_time_hour - 60 * total_time_min) 153 | 154 | self.use_time = time.time() - self.start_time 155 | use_time_hour = int(self.use_time // 60 // 60) 156 | use_time_min = int((self.use_time // 60) - 60 * use_time_hour) 157 | use_time_sec = int(self.use_time - 60 * 60 * use_time_hour - 60 * use_time_min) 158 | 159 | self.time_show.setText('%s:%s:%s' % (total_time_hour, total_time_min, total_time_sec) + 160 | ' + %s:%s:%s' % (use_time_hour, use_time_min, use_time_sec)) 161 | 162 | def serialize(self, todo_serialization=None): 163 | """ 164 | Serialization. 165 | 166 | Args: 167 | todo_serialization: Google protobuf object. 168 | 169 | """ 170 | 171 | todo_serialization.todo_id = self.id 172 | todo_serialization.task = self.edit.text() 173 | if not self.close_flag: 174 | todo_serialization.time = self.total_time 175 | else: 176 | self.total_time += self.use_time 177 | todo_serialization.time = self.total_time 178 | 179 | todo_serialization.todo_location.append(self.item_row) 180 | todo_serialization.todo_location.append(self.item_column) 181 | 182 | def deserialize(self, data, hashmap: dict, view=None, flag=True): 183 | """ 184 | Deserialization. 185 | 186 | Args: 187 | data: Google protobuf object. 188 | hashmap: Hashmap. 189 | view: The manager. 190 | flag: Serialization times. 191 | 192 | """ 193 | 194 | self.id = data.todo_id 195 | self.edit.setText(data.task) 196 | self.total_time = data.time 197 | self.item_row = data.todo_location[0] 198 | self.item_column = data.todo_location[1] 199 | 200 | self.start_time = time.time() 201 | self.time_update() 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This project is being refactored...V3 is on the way. V3 will use PySide6. 2 | 3 | 4 | 15 | 16 | # **NodeNote** 17 | 18 | # 1. 如何运行 19 | 20 | > 输入框架IME最好选择`搜狗输入法` 21 | 22 | ## 1. 不同平台的方式 23 | 24 | ### 1. 使用脚本方式运行 25 | 1. 安装`python`: `Python版本` 3.9 26 | 2. 安装依赖: `pip install -r requirements.txt` 27 | 3. 运行脚本: `python example.py` 28 | 29 | ### 2. 使用可执行文件运行(路径应为纯英文路径, 不要包含特殊字符) 30 | - Windows: 运行`NodeNote.exe` 31 | - Mac: 运行`NodeNote.app` 32 | - Linux: 33 | 1. 安装依赖: `sudo apt install libxcb-xinerama0` << `(Unbuntu)` 34 | 2. 运行`NodeNote`二进制文件 35 | 36 | ## 2. 打开后的工作区介绍 37 | 38 | > 1. 进入工作区: 现版本采用工作区结构, 39 |  40 | - 双击上次打开的目录可以直接打开目录 41 | - 也可以选择打开工作区目录按钮, 选择你的文件夹 42 | 43 | > 2. 工作区结构: 第一次打开空白工作区会生成以下文件 44 |  45 | - `.NOTENOTE`: 记录你创建工作区的时间以及保存你上次打开过的文件 46 | - `Resources`: 程序运行所需的资源文件 47 | - `Notes`: 创建笔记所在的目录, 您的`.note`格式笔记最好都创建在该文件夹, 因为如果没有上次打开的文件, 则在该目录检索, 如果没有检索到, 则在该目录新建一个`.note`格式文件 48 | - `History`: 运行时的文件每隔3分钟会自动备份一份到该文件夹, 如果资源过大可以定时清理! 一个`.note`小型的话大概只有`几KB`. 49 | - `Documents`: 您的markdown文件备份 50 | - `Attachments`: 当你使用节点的附件功能时, 会自动拉取该文件到这个文件夹 51 | - `Assets`: 您的笔记所用到的图片都保存在这个文件夹 52 | 53 | > 过去版本迁移 54 | - 将根目录的`Assests`移动到工作区目录 55 | - 将您的`.note`文件移动到`Notes`即可 56 | 57 | # 2. 如何使用小部件 58 | ## 1. `Alt+Q`或者`鼠标右键` 创建`属性控件`: 支持富文本, markdown, 以及其他小部件的嵌套 59 | > 支持的嵌套类型 60 |  61 | - 嵌套自身 62 | - 嵌套子图: 相当于一个存在于当前场景的自由的子场景 63 | - 嵌套`todo控件`: 64 | - 用于你的任务控制, 点开始按钮则开始计时, 左侧是总时间, 右侧是你开始计时之后的时间. 65 | - 结束计时后, 会将你的右侧时间加到左侧总时间上. 66 | - 嵌套`附件控件`: 67 | - `cover`是你的附件图片,可以自定义; 68 | - `File`是你要添加的附件.添加完成后, 会将你的附件拉到当前目录的`Attachments`中. 69 | - 添加完成后, 双击图片则会调用系统默认的打开程序打开你的附件. 70 | 71 | > 支持的富文本操作: 72 | 73 | 您可以选中节点内的富文本拖拽到其他地方 74 | 75 | |Python高亮 : `Ctrl+9`| 清空对齐格式: `Ctrl+P` | 加粗: `Ctrl+W` | 76 | | --- | --- | --- | 77 | | 左对齐 : `Ctrl+[` |右对齐 : `Ctrl+]` | 居中对齐 : `Ctrl+ \ ` | 78 | | 斜体 : `Ctrl+Q` | 下划线 : `Ctrl+R` | 删除线: `Ctrl+/` | 79 | | 增大字体: `Ctrl+G` | 缩小字体: `Ctrl+H` | 改变字体颜色: `Ctrl+N` | 80 | | 超链接: `Ctrl+M` | 数学公式[格式参见](https://wizardforcel.gitbooks.io/matplotlib-user-guide/content/4.6.html): `Ctrl+I` | 清空所有格式: `Ctrl + L`| 81 | | 撤销上一步: `Crtl+Z` | 恢复上一步: `Ctrl+Y` | 创建一个表格: `Ctrl+1` | 82 | | 增加一行表格: `Ctrl+3` | 增加一列表格 : `Ctrl+2` | 删除一行表格 : `Ctrl+5` | 83 | | 删除一列表格 : `Ctrl+4` | 选中表格后合并表格行列: `Ctrl+6` | 合并表格后拆分已合并内容: `Ctrl+7` | 84 | | 添加一个列表 : `Ctrl+8` | 改变插入图片的大小 : `Ctrl+U` | 文字向后缩进或向前缩进: `Tab` or `Ctrl+Tab`| 85 | | 复制html内容: `Ctrl+C` | 复制纯文本内容: `Ctrl+Shift+C` | 粘贴: `Ctrl+V` | 86 | 87 | > 支持的Markdown操作: 88 |  89 | 90 | - 选中小部件后在侧边栏进行编辑, 当退出侧边栏时, 会自动保存`markdown`到数据库以及备份文件中 91 | - 支持的Markdown类型有: 所有基本`markdown`以及`UML`, `代码块高亮`, `LaTeX`, `绘图` 具体可以移步该项目 >> [tui.editor](https://github.com/nhn/tui.editor) 92 | - 插入图片请使用相对路径: `../Assets/您的图片` 93 | 94 | > 支持的节点无限画布: 95 |  96 | 97 | - 其样式对应于Draw Widget的样式 98 | - 您可以通过`W/A/S/D`扩展画布的大小 99 | 100 | > 支持的真值 101 | 102 | - 可以注意到每个节点都有四个端口, 上面两个是真值为真的输入输出端口, 下面两个是真值为假的输入输出端口 103 | - 通过按照相应真值的端口进行连线, 结合下面的逻辑部件, 可以表示出你想要的逻辑. 104 | 105 | > 支持的复制节点以及粘贴 106 | - 您可以使用`Alt+R`复制该节点以及其内部所有内容 107 | - 然后可以通过`Alt+T`粘贴其到任意一个场景中 108 | 109 | > 支持的扩大与缩小: 用`Shift+鼠标左键` 扩大与缩小 110 | 111 | 112 | ## 2. `Alt+W`或`鼠标右键`创建`逻辑控件`: 使用两个与或非门进行逻辑的控制 113 | 114 |  115 | - 上面的是输入的`与或非门`, 下面的是输出的`与或非门` 116 | - 当你有多个输入的时候 117 | - 调整输入成`或门`, 则表示所有输入, 仅需一个成立, 则输出成立 118 | - 调整输入成`与门`, 则表示所有输入, 全部都得成立, 则输出成立 119 | - 调整输入成`非门`, 则表示将输入结果逆反, 例如你从`逻辑部件`的真值为假的端口连到`逻辑控件`, 则逆反后为真 120 | - 当你有多个输出的时候 121 | - 调整输出成`或门`, 则表示所有输出, 仅有部分成立 122 | - 调整输出成`与门`, 则表示所有输出, 全部都成立 123 | - 调整输出成`非门`, 则表示将输出结果逆反 124 | 125 | ## 3. `Alt+E`或`鼠标右键`创建`绘画部件` 126 | 127 |  128 | 129 | - 请先连接数位板 130 | - 支持橡皮擦功能, 现在数位板驱动中, 将你的笔其中一个按钮设置为橡皮擦. 131 | 132 | ## 4. 通过`双击其他部件端口`创建连线 133 | - 连线选中后可以通过两个`控制点`控制连线的位置 134 | 135 |  136 | - 可以在`属性控件`上按`Ctrl+0`生成与之相关所有连线的`ui动画`, 观察逻辑流向 137 | 138 |  139 | 140 | - 也可以在`连线`上单独使用`Ctrl+0`生成选中`连线`的逻辑动画 141 | 142 | 143 | ## 5. 结合上述所有部件的碰撞检测 144 |  145 | 146 | - 您可以拖动`属性部件`碰撞其他部件 147 | - 直接拖动到其他`属性部件`: 将自身添加进其他`属性部件`的当前行 148 | - 拖动到其他`属性部件`时, 按住`Ctrl`: 将自身添加进其他`属性部件`的下一行 149 | - 拖动到`连线`: 自动插入该部件到连线的中间 150 | - 您可以在`属性部件`中进行碰撞检测 151 | - 删除`属性控件`的子控件会生成一个雪花图案, 通过碰撞雪花图案, 可以替代其位置 152 | - 您可以使用右键的上下文菜单调整自身在其他`属性控件`内的位置 153 | 154 | ## 6. 综合上述的逻辑控件和属性控件的功能 155 | - 您可以按`Ctrl+up/down/left/right`实现辅助对齐功能 156 |  157 | 158 | - 您可以按`Ctrl+1/2/3/4/5/6/7/8` 移动当前鼠标位置对应左右上下的部件移动50px 159 | 160 | 161 | # 3. 如何使用场景 162 | 163 | ## 1. 创建子场景 164 | - 每个`子场景`都与一个`属性控件`绑定, 您可以通过`Alt+鼠标左键`点击小部件, 创建其子场景. 165 | 166 |  167 | 168 | - 创建子场景后, 会在侧边栏的目录中生成你的索引, 您可以通过索引找到相应的子场景 169 | - 可以通过`Alt+Z`返回上一次的场景 170 | - 可以通过`Alt+X`返回父场景 171 | 172 | ## 2. `属性控件`与其他`属性控件`跨越场景的超链接跳转 173 |  174 |  175 | - 通过`Alt+C`复制该节点的`id` 176 | - 在其他节点中输入该`id`, 通过`Ctrl+M`将其变为超链接 177 | - 变为超链接后, 您可以自由修改其`id`字符串, 存储的跳转信息不会因为其字符串改变而改变了 178 | 179 | ## 3. 场景小部件的批量坐标移动 180 | `shift + w/a/s/d/j/k/l` 181 | 182 | ## 4. 基本设置 183 | - 扩大场景(左右上下): `alt + 1/2/3/4` 184 | - 缩小场景(左右上下): `alt + 5/6/7/8` 185 | - 打开辅助线功能(默认开启): `F1` 186 | - 打开Undo&&Redo功能(默认开启): `F2` 187 | - 打开飘落的图片特效(默认开启): `F11` 188 | - 打开搜索栏: `Ctrl+F` 189 | - 缩放视图: `Ctrl +-` 190 | - 打开缩略图: `Shift+B` 191 |  192 | 193 | # 4. 文件分享与导出操作 194 | ## 1. 导出该场景到`.note`文件 195 | - 不导出该场景下的子场景, 仅导出该场景的内容: `Shift+S` 196 | - 导出该场景下的所有递归子场景: `Alt+S` 197 | ## 2. 导出该场景到`png`图片 198 | - 导出该场景所有内容: `Ctrl+Alt+P` 199 | - 导出该场景选中部件的内容: `Ctrl+Shift+P` 200 | 201 | # 5. UI的操作 202 | - 您可以通过`Ctrl+B`打开`侧边栏` 203 | - 侧边栏拥有文件夹视图: 您可以通过右键上下文菜单`创建`或`删除`文件, 以及通过鼠标左键切换`.note`文件 204 | - 场景+Markdown视图: 这是您该`.note`笔记的结构 205 | - 样式自定义视图: 您可以通过该视图自定义所有样式 206 | - 目前的窗口样式可以通过`qss`文件进行修改, 我只做了一个, 感兴趣的朋友可以参照`Resources/Stylesheets`目录下的`qss`仿照一个, 然后可以通过样式按钮加载你写的`qss`文件. 207 | - 其他部件样式支持`所有场景`, `当前场景`, `选中部件`样式的修改 208 | - 您可以通过`Alt+G`调整侧边栏到左边或上边 209 | - 您可以通过拉动侧边栏以及内部的条进行调整大小 210 | 211 | # 6. 最后 212 | > 感谢您使用`NodeNote`, 如果遇到任何问题或想提建, 欢迎创建一个`issue` 213 | 214 | > 如果有朋友想参与项目, 非常欢迎. 目前要是有人能多写几个`qss样式表`就好了哈哈哈哈. 215 | 1. `fork`该仓库 216 | 2. 修改代码 217 | 3. 创建新`brand` 218 | 4. `push`到我的`main`分支 219 | 5. 我会根据实际情况进行合并分支 220 | 221 | 222 | # 版本更替 223 | 224 | ## 后续规划 225 | 代码重构, 增加双链, 除了网格布局新增其他布局样式, 绘图功能强化. 226 | 227 | ## v2.36.21: 228 | - [x] 侧边栏画板 229 | - [x] 对齐功能 230 | - [x] 动画演示变成树的遍历 231 | - [x] 修复了序列化的一个错误 232 | - [x] 修复线条的编辑框下上文菜单的点击 233 | - [x] 所有场景的背景色更新sub view内的 234 | - [x] effect cutline 计算boundingRect() 235 | - [x] 修复搜索的错误 236 | - [x] 修复还没建立线条就删除的错误 237 | - [x] 修复了错误的majax解析闪退 238 | 239 | ## v2.37.22: 240 | - [x] 修复了bug 241 | - [x] 增加了场景内的根据当前鼠标坐标批量移动小部件的功能 242 | 243 | ## v2.37.23: 244 | - [x] 修复了一些bug 245 | 246 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Model/serialize.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | 4 | // define the package name which is not necessary for Python to avoid collision 5 | // in other languages 6 | package NodeNote; 7 | 8 | // port serialization 9 | message PortSerialization { 10 | int64 port_id = 1; 11 | int32 port_type = 2; 12 | bool port_truth = 3; 13 | 14 | // pipes 15 | repeated int64 pipes_id = 4; 16 | 17 | // ui 18 | float port_width = 5; 19 | repeated int64 port_color = 6; 20 | 21 | // flag 22 | repeated bool port_flag = 7; 23 | } 24 | 25 | // define the root view serialization data 26 | message ViewSerialization { 27 | // scene serialization 28 | message SceneSerialization { 29 | // scene id 30 | int64 scene_id = 1; 31 | 32 | // attribute widget serialization 33 | message AttrSerialization { 34 | // attribute widget id 35 | int64 attr_id = 1; 36 | 37 | // geometry 38 | repeated float size = 2; 39 | repeated float position = 3; 40 | 41 | // contents 42 | string contents = 4; 43 | 44 | repeated PortSerialization attr_port = 5; 45 | 46 | // connections serialization 47 | repeated int64 next_attr_id = 6; 48 | repeated int64 next_logic_id = 7; 49 | repeated int64 last_attr_id = 8; 50 | repeated int64 last_logic_id = 9; 51 | repeated int64 sub_attr = 10; 52 | 53 | message FileSerialization { 54 | int64 file_id = 1; 55 | string text = 2; 56 | string cover = 3; 57 | optional string file = 4; 58 | repeated int32 file_location = 5; 59 | } 60 | repeated FileSerialization file_serialization = 11; 61 | 62 | message SubviewSerialization { 63 | int64 subview_id = 1; 64 | repeated float size = 2; 65 | repeated int32 subview_location = 3; 66 | repeated ViewSerialization subview = 4; 67 | } 68 | repeated SubviewSerialization subview_serialization = 12; 69 | 70 | message TodoSerialization { 71 | int64 todo_id = 1; 72 | string task = 2; 73 | float time = 3; 74 | repeated int32 todo_location = 4; 75 | } 76 | repeated TodoSerialization todo_serialization = 13; 77 | 78 | message NoneSerialization { 79 | int64 none_id = 1; 80 | repeated int32 none_pos = 2; 81 | } 82 | repeated NoneSerialization none_serialization = 14; 83 | 84 | repeated SceneSerialization sub_scene_serialization = 15; 85 | 86 | bool highlighter = 16; 87 | 88 | repeated int32 attr_location = 17; 89 | repeated int32 next_location = 18; 90 | 91 | // ui 92 | string self_attr_font_family = 19; 93 | int32 self_attr_font_size = 20; 94 | repeated int64 self_attr_color = 21; 95 | 96 | // flag 97 | repeated bool attr_flag = 22; 98 | 99 | optional bool mouse_flag = 23; 100 | optional double mouse_text_width = 24; 101 | 102 | } 103 | repeated AttrSerialization attr_serialization = 2; 104 | 105 | // logic widget serialization 106 | message LogicSerialization { 107 | int64 logic_id = 1; 108 | repeated float logic_position = 2; 109 | repeated int32 logic_truth = 3; 110 | repeated PortSerialization logic_port = 4; 111 | 112 | // connections 113 | repeated int64 logic_next_attr = 5; 114 | repeated int64 logic_next_logic = 6; 115 | repeated int64 logic_last_attr = 7; 116 | repeated int64 logic_last_logic = 8; 117 | 118 | // ui 119 | repeated int64 logic_color = 9; 120 | 121 | // flag 122 | repeated bool logic_flag = 10; 123 | } 124 | repeated LogicSerialization logic_serialization = 3; 125 | 126 | // pipe widget serialization 127 | message PipeSerialization { 128 | int64 pipe_id = 1; 129 | repeated int64 pipe_port_id = 2; 130 | string pipe_text = 3; 131 | 132 | // control point 133 | repeated float start_point = 4; 134 | repeated float end_point = 5; 135 | bool source_move_status = 6; 136 | bool destination_move_status = 7; 137 | repeated float offset_start_point = 8; 138 | repeated float offset_destination_point = 9; 139 | 140 | // ui 141 | float self_pipe_width = 10; 142 | repeated int64 self_pipe_color = 11; 143 | 144 | // flag 145 | repeated bool pipe_flag = 12; 146 | 147 | // v2.8.2 148 | // font 149 | optional string pipe_font_family = 15; 150 | optional int32 pipe_font_size = 16; 151 | } 152 | repeated PipeSerialization pipe_serialization = 4; 153 | 154 | // container widget serialization 155 | message DrawSerialization { 156 | int64 draw_id = 1; 157 | repeated float draw_size = 2; 158 | repeated float draw_pos = 3; 159 | 160 | string path = 4; 161 | } 162 | repeated DrawSerialization draw_serialization = 5; 163 | 164 | // ui serialization 165 | string background_image = 6; 166 | 167 | // attribute widget ui 168 | optional string scene_attr_font_family = 7; 169 | optional int32 scene_attr_font_size = 8; 170 | optional int64 scene_attr_style_font_color = 9; 171 | optional int64 scene_attr_style_background_color = 10; 172 | optional int64 scene_attr_style_selected_background_color = 11; 173 | optional int64 scene_attr_style_border_color = 12; 174 | optional int64 scene_attr_style_selected_border_color = 13; 175 | 176 | // logic widget ui 177 | optional int64 scene_logic_style_background_color = 14; 178 | optional int64 scene_logic_style_selected_background_color = 15; 179 | optional int64 scene_logic_style_border_color = 16; 180 | optional int64 scene_logic_style_selected_border_color = 17; 181 | 182 | 183 | // pipe widget ui 184 | optional float scene_pipe_width = 18; 185 | optional int64 scene_pipe_style_background_color = 19; // 2 items of list 186 | optional int64 scene_pipe_style_selected_background_color = 20; // 2 items of list 187 | 188 | 189 | // port widget ui 190 | float scene_port_width = 21; 191 | optional int64 scene_port_style_color = 22; 192 | optional int64 scene_port_style_border_color = 23; 193 | optional int64 scene_port_style_hovered_color = 24; 194 | optional int64 scene_port_style_hovered_border_color = 25; 195 | optional int64 scene_port_style_activated_color = 26; 196 | optional int64 scene_port_style_activated_border_color = 27; 197 | 198 | // scene rect 199 | optional float x = 28; 200 | optional float y = 29; 201 | optional float width = 30; 202 | optional float height = 31; 203 | 204 | // v2.8.2 205 | // pipe font 206 | optional string scene_pipe_font_family = 32; 207 | optional int32 scene_pipe_font_size = 33; 208 | optional int64 scene_pipe_font_color = 34; 209 | 210 | // v.2.10-> 211 | optional bool background_image_flag = 35; 212 | } 213 | 214 | repeated SceneSerialization scene_serialization = 1; 215 | int64 current_scene_id = 2; 216 | 217 | // used time serialization 218 | // optional float use_time = 3; 219 | // optional float last_time = 4; 220 | 221 | // ui serialization 222 | optional string image_path = 5; 223 | 224 | // attribute widget ui 225 | string all_attr_font_family = 6; 226 | int32 all_attr_font_size = 7; 227 | repeated int64 all_attr_color = 8; // 5 items of list 228 | 229 | // logic widget ui 230 | repeated int64 all_logic_color = 9; // 4 items of list 231 | 232 | // pipe widget ui 233 | float all_pipe_width = 10; 234 | repeated int64 all_pipe_color = 11; // 2 items of list 235 | 236 | // port widget ui 237 | float all_port_width = 12; 238 | repeated int64 all_port_color = 13; // 6 items of list 239 | 240 | // draw widget ui 241 | float all_draw_width = 14; 242 | int64 all_draw_color = 15; 243 | 244 | // text width 245 | optional double text_width = 16; 246 | 247 | // flag 248 | optional bool line_flag = 17; 249 | optional bool undo_flag = 18; 250 | 251 | // v2.8.2版本 252 | // pipe font type 253 | optional string all_pipe_font_family = 19; 254 | optional int32 all_pipe_font_size = 20; 255 | 256 | // flowing image flag 257 | optional bool flowing_flag = 21; 258 | 259 | // v2.10-> 260 | optional string all_background_image = 22; 261 | 262 | // style path 263 | optional string style_path = 23; 264 | } 265 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Components/port.py: -------------------------------------------------------------------------------- 1 | from PyQt5 import QtGui, QtCore, QtWidgets 2 | from ..Model import constants, serializable 3 | 4 | __all__ = ["Port"] 5 | 6 | 7 | class Port(QtWidgets.QGraphicsWidget, serializable.Serializable): 8 | """ 9 | The port contains pipes. 10 | 11 | """ 12 | 13 | width = constants.port_width 14 | color = constants.port_color 15 | border_color = constants.port_border_color 16 | hovered_color = constants.port_hovered_color 17 | hovered_border_color = constants.port_hovered_border_color 18 | activated_color = constants.port_activated_color 19 | activated_border_color = constants.port_activated_border_color 20 | 21 | def __init__(self, port_type, port_truth, parent): 22 | """ 23 | Create pipes. 24 | 25 | Args: 26 | port_type: Input 0 or output type 1. 27 | port_truth: TRUE 1 or FALSE 0. 28 | parent: Parent item. 29 | """ 30 | 31 | super(Port, self).__init__(parent) 32 | self.port_type = port_type 33 | self.port_truth = port_truth 34 | # BASIC SETTINGS 35 | self.setAcceptHoverEvents(True) 36 | self.setFlags(self.ItemSendsScenePositionChanges | self.ItemIsSelectable) 37 | self.setZValue(constants.Z_VAL_PORT) 38 | 39 | # STORE PIPES 40 | self.pipes = list() 41 | 42 | # DRAW PARAMETERS 43 | self.border_size = 1 44 | self.hovered = False 45 | 46 | # Style init 47 | self.width_flag = False 48 | self.color_flag = False 49 | self.border_color_flag = False 50 | self.hovered_color_flag = False 51 | self.hovered_border_color_flag = False 52 | self.activated_color_flag = False 53 | self.activated_border_color_flag = False 54 | 55 | def get_node(self): 56 | """ 57 | Return the node which contains this port. 58 | 59 | """ 60 | 61 | return self.parentItem() 62 | 63 | def add_pipes(self, pipe_widget): 64 | """ 65 | Add pipes in this storage. 66 | 67 | Args: 68 | pipe_widget: The added pipe widget. 69 | 70 | """ 71 | 72 | self.pipes.append(pipe_widget) 73 | 74 | def remove_pipes(self, pipe_widget): 75 | """ 76 | Delete pipes from this storage. 77 | 78 | Args: 79 | pipe_widget: The deleted pipe widget. 80 | 81 | """ 82 | 83 | if pipe_widget in self.pipes: 84 | self.pipes.remove(pipe_widget) 85 | 86 | def update_pipes_position(self): 87 | """ 88 | Update the geometry of pipes. 89 | 90 | """ 91 | 92 | for pipe in self.pipes: 93 | if pipe: 94 | pipe.update_position() 95 | else: 96 | self.pipes.remove(pipe) 97 | 98 | def start_pipes_animation(self): 99 | """ 100 | Turn on rolling ball effect by ctrl 0. 101 | 102 | """ 103 | 104 | for pipe in self.pipes: 105 | pipe.perform_evaluation_feedback() 106 | 107 | def end_pipes_animation(self): 108 | """ 109 | Turn off rolling ball effect by ctrl 0. 110 | 111 | """ 112 | 113 | for pipe in self.pipes: 114 | pipe.end_evaluation_feedback() 115 | 116 | def sizeHint(self, which: QtCore.Qt.SizeHint, constraint: QtCore.QSizeF = ...) -> QtCore.QSizeF: 117 | # Width init 118 | if self.scene(): 119 | if hasattr(self.scene(), "port_style_width") and self.scene().port_style_width and not self.width_flag: 120 | self.width = self.scene().port_style_width 121 | return QtCore.QSizeF(self.width, self.width) 122 | 123 | def paint(self, painter: QtGui.QPainter, option: QtWidgets.QStyleOptionGraphicsItem, widget=None) -> None: 124 | """ 125 | Draw port widget. 126 | 127 | Args: 128 | painter: Draw pen. 129 | option: None. 130 | widget: None. 131 | 132 | """ 133 | 134 | # Color init 135 | if self.scene().port_style_color and not self.color_flag: 136 | self.color = self.scene().port_style_color 137 | if self.scene().port_style_border_color and not self.border_color_flag: 138 | self.border_color = self.scene().port_style_border_color 139 | if self.scene().port_style_hovered_color and not self.hovered_color_flag: 140 | self.hovered_color = self.scene().port_style_hovered_color 141 | if self.scene().port_style_hovered_border_color and not self.hovered_border_color_flag: 142 | self.hovered_border_color = self.scene().port_style_hovered_border_color 143 | if self.scene().port_style_activated_color and not self.activated_color_flag: 144 | self.activated_color = self.scene().port_style_activated_color 145 | if self.scene().port_style_activated_border_color and not self.activated_border_color_flag: 146 | self.activated_border_color = self.scene().port_style_activated_border_color 147 | 148 | # Size init 149 | if self.scene().port_style_width and not self.width_flag: 150 | self.width = self.scene().port_style_width 151 | self.setMaximumSize(self.width, self.width) 152 | self.updateGeometry() 153 | 154 | # SIZE 155 | rect_width = self.width / 1.8 156 | rect_height = self.width / 1.8 157 | rect_x = self.boundingRect().center().x() - (rect_width / 2) 158 | rect_y = self.boundingRect().center().y() - (rect_height / 2) 159 | port_rect = QtCore.QRectF(rect_x, rect_y, rect_width, rect_height) 160 | 161 | # COLOR 162 | if self.hovered: 163 | color = self.hovered_color 164 | border_color = self.hovered_border_color 165 | elif self.pipes: 166 | color = self.activated_color 167 | border_color = self.activated_border_color 168 | else: 169 | color = self.color 170 | border_color = self.border_color 171 | 172 | # PAINTER 173 | pen = QtGui.QPen(border_color, 1.8) 174 | painter.setPen(pen) 175 | painter.setBrush(color) 176 | painter.drawEllipse(port_rect) 177 | 178 | # OTHER OPTIONS 179 | if self.pipes and not self.hovered: 180 | painter.setBrush(border_color) 181 | w = port_rect.width() / 2.5 182 | h = port_rect.height() / 2.5 183 | rect = QtCore.QRectF(port_rect.center().x() - w / 2, 184 | port_rect.center().y() - h / 2, 185 | w, h) 186 | border_color = self.border_color 187 | pen = QtGui.QPen(border_color, 1.6) 188 | painter.setPen(pen) 189 | painter.setBrush(border_color) 190 | painter.drawEllipse(rect) 191 | elif self.hovered: 192 | if len(self.pipes) >= 2: 193 | pen = QtGui.QPen(border_color, 1.4) 194 | painter.setPen(pen) 195 | painter.setBrush(color) 196 | w = port_rect.width() / 1.8 197 | h = port_rect.height() / 1.8 198 | else: 199 | painter.setBrush(border_color) 200 | w = port_rect.width() / 3.5 201 | h = port_rect.height() / 3.5 202 | rect = QtCore.QRectF(port_rect.center().x() - w / 2, 203 | port_rect.center().y() - h / 2, 204 | w, h) 205 | painter.drawEllipse(rect) 206 | 207 | def hoverEnterEvent(self, event: QtWidgets.QGraphicsSceneHoverEvent) -> None: 208 | self.hovered = True 209 | super(Port, self).hoverEnterEvent(event) 210 | 211 | def hoverLeaveEvent(self, event: QtWidgets.QGraphicsSceneHoverEvent) -> None: 212 | self.hovered = False 213 | super(Port, self).hoverLeaveEvent(event) 214 | 215 | def serialize(self, port_serialization=None): 216 | """ 217 | Serialization. 218 | 219 | Args: 220 | port_serialization: Google protobuff object. 221 | 222 | """ 223 | 224 | # port 225 | port_serialization.port_id = self.id 226 | port_serialization.port_type = self.port_type 227 | port_serialization.port_truth = self.port_truth 228 | 229 | # pipes 230 | for pipe_widget in self.pipes: 231 | if pipe_widget: 232 | port_serialization.pipes_id.append(pipe_widget.id) 233 | else: 234 | self.pipes.remove(pipe_widget) 235 | 236 | # ui 237 | port_serialization.port_width = self.width 238 | port_serialization.port_color.append(self.color.rgba()) 239 | port_serialization.port_color.append(self.border_color.rgba()) 240 | port_serialization.port_color.append(self.hovered_color.rgba()) 241 | port_serialization.port_color.append(self.hovered_border_color.rgba()) 242 | port_serialization.port_color.append(self.activated_color.rgba()) 243 | port_serialization.port_color.append(self.activated_border_color.rgba()) 244 | 245 | # flag 246 | port_serialization.port_flag.append(self.width_flag) 247 | port_serialization.port_flag.append(self.color_flag) 248 | port_serialization.port_flag.append(self.border_color_flag) 249 | port_serialization.port_flag.append(self.hovered_color_flag) 250 | port_serialization.port_flag.append(self.hovered_border_color_flag) 251 | port_serialization.port_flag.append(self.activated_color_flag) 252 | port_serialization.port_flag.append(self.activated_border_color_flag) 253 | 254 | def deserialize(self, data, hashmap: dict, view=None, flag=True): 255 | """ 256 | Deserialization. 257 | 258 | Args: 259 | data: Google protobuff object. 260 | hashmap: Hashmap. 261 | view: The manager. 262 | flag: two times Deserialization. 263 | 264 | """ 265 | 266 | if flag: 267 | # id and hashmap 268 | self.id = data.port_id 269 | hashmap[data.port_id] = self 270 | 271 | # style 272 | self.width = data.port_width 273 | 274 | self.color = QtGui.QColor() 275 | self.color.setRgba(data.port_color[0]) 276 | 277 | self.border_color = QtGui.QColor() 278 | self.border_color.setRgba(data.port_color[1]) 279 | 280 | self.hovered_color = QtGui.QColor() 281 | self.hovered_color.setRgba(data.port_color[2]) 282 | 283 | self.hovered_border_color = QtGui.QColor() 284 | self.hovered_border_color.setRgba(data.port_color[3]) 285 | 286 | self.activated_color = QtGui.QColor() 287 | self.activated_color.setRgba(data.port_color[4]) 288 | 289 | self.activated_border_color = QtGui.QColor() 290 | self.activated_border_color.setRgba(data.port_color[5]) 291 | 292 | # flag 293 | self.width_flag = data.port_flag[0] 294 | self.color_flag = data.port_flag[1] 295 | self.border_color_flag = data.port_flag[2] 296 | self.hovered_color_flag = data.port_flag[3] 297 | self.hovered_border_color_flag = data.port_flag[4] 298 | self.activated_color_flag = data.port_flag[5] 299 | self.activated_border_color_flag = data.port_flag[6] 300 | 301 | else: 302 | # deserialize pipes 303 | pass 304 | -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Stylesheets/dark_style.qss: -------------------------------------------------------------------------------- 1 | * { 2 | color: #FFFFFF; 3 | 4 | } 5 | 6 | /* this is work dir interface */ 7 | QWidget{ 8 | background-color: #212121; 9 | } 10 | 11 | /* this is the mainwindow */ 12 | QMainWindow { 13 | background-color: #212121; 14 | margin: 2px; 15 | spacing: 3px; 16 | } 17 | QMainWindow::separator { 18 | background: #424242; 19 | width: 10px; 20 | height: 10px; 21 | } 22 | QMainWindow::separator:hover { 23 | background: #424242; 24 | } 25 | 26 | /* this is scroll area */ 27 | QScrollBar:horizontal { 28 | border: 2px solid grey; 29 | background: #616161; 30 | height: 8px; 31 | margin: 0px 20px 0 20px; 32 | } 33 | QScrollBar::handle:horizontal { 34 | background: #616161; 35 | min-width: 20px; 36 | } 37 | QScrollBar::add-line:horizontal { 38 | border: 2px solid grey; 39 | background: #757575; 40 | width: 20px; 41 | subcontrol-position: right; 42 | subcontrol-origin: margin; 43 | } 44 | 45 | QScrollBar::sub-line:horizontal { 46 | border: 2px solid grey; 47 | background: #757575; 48 | width: 20px; 49 | subcontrol-position: left; 50 | subcontrol-origin: margin; 51 | } 52 | 53 | QScrollBar::left-arrow:horizontal, QScrollBar::right-arrow:horizontal { 54 | border: 2px solid grey; 55 | width: 3px; 56 | height: 3px; 57 | background: white; 58 | } 59 | QScrollBar:vertical { 60 | border: 2px solid grey; 61 | background: #616161; 62 | width: 8px; 63 | margin: 22px 0 22px 0; 64 | } 65 | QScrollBar::handle:vertical { 66 | background: #616161; 67 | min-height: 20px; 68 | } 69 | QScrollBar::add-line:vertical { 70 | border: 2px solid grey; 71 | background: #616161; 72 | height: 20px; 73 | subcontrol-position: bottom; 74 | subcontrol-origin: margin; 75 | } 76 | 77 | QScrollBar::sub-line:vertical { 78 | border: 2px solid grey; 79 | background: #757575; 80 | height: 20px; 81 | subcontrol-position: top; 82 | subcontrol-origin: margin; 83 | } 84 | QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical { 85 | border: 2px solid grey; 86 | width: 3px; 87 | height: 3px; 88 | background: white; 89 | } 90 | 91 | 92 | /* this is the toolbar */ 93 | QToolBar{ 94 | background-color: #424242; 95 | margin: 2px; 96 | padding: 2px; 97 | border-style: solid; 98 | border-width: 2px; 99 | border-color: #616161; 100 | spacing: 3px; 101 | } 102 | QToolBar::handle { /* moved image */ 103 | image: url("src/NodeNotePackage/NodeNote/Resources/Images/left_bar_drag.png"); 104 | spacing: 3px; 105 | } 106 | 107 | 108 | /* this is tab widget of toolbar*/ 109 | QTabWidget::pane { /* the tab widget frame */ 110 | border-width: 5px; 111 | border-style: solid; 112 | border-color: #757575; 113 | } 114 | QTabWidget::tab-bar { /* the tab bar of tags */ 115 | left: 10px; 116 | } 117 | QTabBar::tab { /* the common tags */ 118 | color: #fafafa; 119 | border-style: solid; 120 | border-color: #757575; 121 | border-width: 2px; 122 | border-bottom-color: rgb(254, 210, 190); 123 | min-width: 8ex; 124 | padding: 2px; 125 | } 126 | QTabBar::tab:selected, QTabBar::tab:hover { /* the common tags selected or hovered*/ 127 | background: #424242; 128 | } 129 | QTabBar::tab:selected { 130 | border-color: #9e9e9e; 131 | border-bottom-color: #616161; /* same as pane color */ 132 | } 133 | QTabBar::tab:!selected { 134 | margin-top: 2px; /* make non-selected tabs look smaller */ 135 | } 136 | 137 | 138 | /* this is work dir */ 139 | /* this is scene list */ 140 | QTreeView, QTreeWidget { 141 | alternate-background-color: #616161; 142 | background-color: #424242; 143 | show-decoration-selected: 1; 144 | border-width: 0px; 145 | border-style: solid; 146 | border-color: #eeeeee; 147 | } 148 | 149 | QTreeView::item, QTreeWidget::item { 150 | border: 1px solid #eeeeee; 151 | border-top-color: transparent; 152 | border-bottom-color: transparent; 153 | 154 | } 155 | 156 | QTreeView::item:hover, QTreeWidget::item:hover { 157 | background: #424242; 158 | border: 1px solid #bfcde4; 159 | } 160 | 161 | QTreeView::item:selected, QTreeWidget::item:selected { 162 | border: 1px solid #567dbc; 163 | background: #424242; 164 | } 165 | 166 | QTreeView::item:selected:active, QTreeWidget::item:selected:active{ 167 | background: #424242; 168 | } 169 | 170 | QTreeView::item:selected:!active, QTreeWidget::item:selected:!active { 171 | background: #424242; 172 | } 173 | 174 | QTreeView::branch, QTreeWidget::branch { 175 | background: #FFD2B6; 176 | } 177 | 178 | QTreeView::branch:has-siblings:!adjoins-item, QTreeWidget::branch:has-siblings:!adjoins-item { 179 | background: #E2D14E; 180 | } 181 | 182 | QTreeView::branch:has-siblings:adjoins-item, QTreeWidget::branch:has-siblings:adjoins-item { 183 | background: #76B8B6; 184 | } 185 | 186 | QTreeView::branch:!has-children:!has-siblings:adjoins-item, QTreeWidget::branch:!has-children:!has-siblings:adjoins-item { 187 | background: #b9d644; 188 | } 189 | 190 | QTreeView::branch:closed:has-children:has-siblings, QTreeWidget::branch:closed:has-children:has-siblings { 191 | background: #FCD554; 192 | } 193 | 194 | QTreeView::branch:has-children:!has-siblings:closed, QTreeWidget::branch:has-children:!has-siblings:closed { 195 | background: #DAC3A4; 196 | } 197 | 198 | QTreeView::branch:open:has-children:has-siblings, QTreeWidget::branch:open:has-children:has-siblings { 199 | background: #E0EEB3; 200 | } 201 | 202 | QTreeView::branch:open:has-children:!has-siblings, QTreeWidget::branch:open:has-children:!has-siblings { 203 | background: #949D6F; 204 | } 205 | QTreeView::branch:has-siblings:!adjoins-item, QTreeWidget::branch:has-siblings:!adjoins-item { 206 | border-image: url("src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-vline.png") 0; 207 | } 208 | 209 | QTreeView::branch:has-siblings:adjoins-item , QTreeWidget::branch:has-siblings:adjoins-item { 210 | border-image: url("src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-branch-more.png") 0; 211 | } 212 | 213 | QTreeView::branch:!has-children:!has-siblings:adjoins-item , QTreeWidget::branch:!has-children:!has-siblings:adjoins-item { 214 | border-image: url("src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-branch-end.png") 0; 215 | } 216 | 217 | QTreeView::branch:has-children:!has-siblings:closed, QTreeWidget::branch:has-children:!has-siblings:closed, 218 | QTreeView::branch:closed:has-children:has-siblings, QTreeWidget::branch:closed:has-children:has-siblings { 219 | border-image: none; 220 | image: url("src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-branch-closed.png"); 221 | } 222 | 223 | QTreeView::branch:open:has-children:!has-siblings, QTreeWidget::branch:open:has-children:!has-siblings, 224 | QTreeView::branch:open:has-children:has-siblings, QTreeWidget::branch:open:has-children:has-siblings { 225 | border-image: none; 226 | image: url("src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-branch-open.png"); 227 | } 228 | 229 | 230 | /* this is combox */ 231 | QComboBox { 232 | color: white; 233 | font: 12px; 234 | border: 1px solid rgba(255, 255, 255, 50); 235 | border-radius: 0px; 236 | margin-left: 2px; 237 | margin-right: 2px; 238 | margin-top: 1px; 239 | margin-bottom: 1px; 240 | padding-left: 4px; 241 | padding-right: 4px; 242 | } 243 | QComboBox:hover { 244 | border: 1px solid rgba(255, 255, 255, 80); 245 | } 246 | QComboBox:editable { 247 | background: white; 248 | } 249 | QComboBox:!editable, QComboBox::drop-down:editable { 250 | background: #424242; 251 | } 252 | QComboBox:!editable:on, QComboBox::drop-down:editable:on { 253 | background: #424242; 254 | } 255 | QComboBox::drop-down { 256 | background: #424242; 257 | border-left: 1px solid rgba(80, 80, 80, 255); 258 | width: 20px; 259 | } 260 | QComboBox::down-arrow { 261 | image: url("src/NodeNotePackage/NodeNote/Resources/Images/down_arrow.png"); 262 | } 263 | QComboBox::down-arrow:on { 264 | top: 1px; 265 | left: 1px; 266 | } 267 | QComboBox QAbstractItemView , QListView { 268 | background: #424242; 269 | border: 0px solid rgba(0, 0, 0, 0); 270 | } 271 | QListView::item { 272 | color: rgb(255, 255, 255); 273 | background: #424242; 274 | border-bottom: 1px solid rgb(170, 19, 19); 275 | border-radius: 0px; 276 | margin: 0px; 277 | padding: 2px; 278 | } 279 | QListView::item:selected { 280 | color: rgb(255, 255, 255); 281 | background: #424242; 282 | border-bottom: 1px solid rgb(180, 103, 103); 283 | border-radius: 0px; 284 | margin:0px; 285 | padding: 2px; 286 | } 287 | 288 | /* this is pushbutton */ 289 | QPushButton { 290 | background-color: #424242; 291 | border-style: outset; 292 | border-width: 1px; 293 | border-radius: 10px; 294 | border-color: beige; 295 | font: bold 12px italic large; 296 | padding: 6px; 297 | } 298 | 299 | QPushButton:pressed { 300 | background-color: #424242; 301 | border-style: inset; 302 | } 303 | 304 | /* this is label */ 305 | QLabel { 306 | background-color: #424242; 307 | border-style: outset; 308 | border-width: 1px; 309 | border-radius: 10px; 310 | border-color: beige; 311 | font: bold 12px italic large; 312 | padding: 6px; 313 | } 314 | QLabel#title_label { 315 | color: white; 316 | background-color: #424242; 317 | border-style: outset; 318 | border-width: 1px; 319 | border-radius: 10px; 320 | border-color: beige; 321 | font: bold 14px italic large; 322 | padding: 6px; 323 | } 324 | QLabel#color_label { 325 | background-color: #ffcc00; 326 | border-style: outset; 327 | border-width: 1px; 328 | border-radius: 10px; 329 | border-color: beige; 330 | font: bold 12px italic large; 331 | padding: 6px; 332 | } 333 | QLabel#font_label { 334 | background-color: #424242; 335 | border-style: outset; 336 | border-width: 1px; 337 | border-radius: 10px; 338 | border-color: beige; 339 | font: bold 12px italic large; 340 | padding: 6px; 341 | } 342 | QLabel#todo_label, QLabel#file_label { 343 | background-color: #424242; 344 | border-style: outset; 345 | border-width: 1px; 346 | border-color: beige; 347 | border-radius: 0px; 348 | font: bold 12px italic large; 349 | padding: 6px; 350 | } 351 | 352 | /* this is spin box */ 353 | QDoubleSpinBox { 354 | color: #FFFFFF; 355 | selection-background-color: #424242; 356 | border: 2px solid blue; 357 | border-radius: 5px; 358 | padding-left: 2px; 359 | padding-top: 2px; 360 | background-color: #424242; 361 | } 362 | QDoubleSpinBox::up-button {subcontrol-origin:border; 363 | subcontrol-position:right; 364 | image: url("src/NodeNotePackage/NodeNote/Resources/Images/spin_up.png"); 365 | width: 16px; 366 | height: 16px; 367 | } 368 | QDoubleSpinBox::down-button{subcontrol-origin:border; 369 | subcontrol-position:left; 370 | border-image: url("src/NodeNotePackage/NodeNote/Resources/Images/spin_down.png"); 371 | width: 16px; 372 | height: 16px; 373 | } 374 | 375 | 376 | /* this is for searching */ 377 | QLineEdit { 378 | border: 2px solid gray; 379 | border-radius: 0px; 380 | padding: 0 8px; 381 | background: beige; 382 | selection-background-color: darkgray; 383 | } 384 | 385 | /* this is menu */ 386 | QMenu { 387 | background-color: #616161; /* sets background of the menu */ 388 | border: 1px solid black; 389 | } 390 | QMenu::item { 391 | background-color: transparent; 392 | } 393 | QMenu::item:selected { 394 | background-color: #757575; 395 | } 396 | 397 | /* this is logic widget */ 398 | QGroupBox { 399 | background-color: rgba(0, 0, 0, 0); 400 | margin-top: 1px; 401 | padding-top: 10px; 402 | padding-bottom: 2px; 403 | padding-left: 5px; 404 | padding-right: 5px; 405 | font-size: 8pt; 406 | } 407 | QGroupBox::title { 408 | subcontrol-origin: margin; 409 | subcontrol-position: top center; 410 | color: rgba(0, 0, 0, 255); 411 | padding: 0px; 412 | left:-4px; 413 | } -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/Stylesheets/cute_style.qss: -------------------------------------------------------------------------------- 1 | /* this is work dir interface */ 2 | QWidget#work_dir_interface{ 3 | background-color: #E0EEB3; 4 | } 5 | 6 | /* this is the mainwindow */ 7 | QMainWindow { 8 | background-color: #b1000f; 9 | margin: 2px; 10 | spacing: 3px; 11 | } 12 | QMainWindow::separator { 13 | background: yellow; 14 | width: 10px; 15 | height: 10px; 16 | } 17 | QMainWindow::separator:hover { 18 | background: red; 19 | } 20 | 21 | /* this is scroll area */ 22 | QScrollBar:horizontal { 23 | border: 2px solid grey; 24 | background: #FFC6BF; 25 | height: 8px; 26 | margin: 0px 20px 0 20px; 27 | } 28 | QScrollBar::handle:horizontal { 29 | background: #FF7FAE; 30 | min-width: 20px; 31 | } 32 | QScrollBar::add-line:horizontal { 33 | border: 2px solid grey; 34 | background: #8333E9; 35 | width: 20px; 36 | subcontrol-position: right; 37 | subcontrol-origin: margin; 38 | } 39 | 40 | QScrollBar::sub-line:horizontal { 41 | border: 2px solid grey; 42 | background: #8333E9; 43 | width: 20px; 44 | subcontrol-position: left; 45 | subcontrol-origin: margin; 46 | } 47 | 48 | QScrollBar::left-arrow:horizontal, QScrollBar::right-arrow:horizontal { 49 | border: 2px solid grey; 50 | width: 3px; 51 | height: 3px; 52 | background: white; 53 | } 54 | QScrollBar:vertical { 55 | border: 2px solid grey; 56 | background: #FFC6BF; 57 | width: 8px; 58 | margin: 22px 0 22px 0; 59 | } 60 | QScrollBar::handle:vertical { 61 | background: #FF7FAE; 62 | min-height: 20px; 63 | } 64 | QScrollBar::add-line:vertical { 65 | border: 2px solid grey; 66 | background: #8333E9; 67 | height: 20px; 68 | subcontrol-position: bottom; 69 | subcontrol-origin: margin; 70 | } 71 | 72 | QScrollBar::sub-line:vertical { 73 | border: 2px solid grey; 74 | background: #8333E9; 75 | height: 20px; 76 | subcontrol-position: top; 77 | subcontrol-origin: margin; 78 | } 79 | QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical { 80 | border: 2px solid grey; 81 | width: 3px; 82 | height: 3px; 83 | background: white; 84 | } 85 | 86 | QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical { 87 | background: none; 88 | } 89 | 90 | /* this is the toolbar */ 91 | QToolBar{ 92 | background-color: rgb(246, 237, 170); 93 | margin: 2px; 94 | padding: 2px; 95 | border-style: solid; 96 | border-width: 2px; 97 | border-color: rgb(253, 248, 147); 98 | spacing: 3px; 99 | } 100 | QToolBar::handle { /* moved image */ 101 | image: url("src/NodeNotePackage/NodeNote/Resources/Images/left_bar_drag.png"); 102 | spacing: 3px; 103 | } 104 | 105 | 106 | /* this is tab widget of toolbar*/ 107 | QTabWidget::pane { /* the tab widget frame */ 108 | border-width: 5px; 109 | border-style: solid; 110 | border-color: rgb(254, 210, 190); 111 | } 112 | QTabWidget::tab-bar { /* the tab bar of tags */ 113 | left: 10px; 114 | } 115 | QTabBar::tab { /* the common tags */ 116 | border-style: solid; 117 | border-color: #FCA53C; 118 | border-width: 2px; 119 | border-bottom-color: rgb(254, 210, 190); 120 | min-width: 8ex; 121 | padding: 2px; 122 | } 123 | QTabBar::tab:selected, QTabBar::tab:hover { /* the common tags selected or hovered*/ 124 | background: qlineargradient(x1: 0, y1: 0, x2: 0.8, y2: 1, 125 | stop: 0 #FFD2B6, stop: 0.4 #FCA52C, 126 | stop: 0.2 #FEFBC8, stop: 1.0 #F6EDAB); 127 | } 128 | QTabBar::tab:selected { 129 | border-color: rgb(255, 192, 241); 130 | border-bottom-color: rgb(254, 210, 190); /* same as pane color */ 131 | } 132 | QTabBar::tab:!selected { 133 | margin-top: 2px; /* make non-selected tabs look smaller */ 134 | } 135 | 136 | 137 | /* this is work dir */ 138 | /* this is scene list */ 139 | QTreeView, QTreeWidget { 140 | alternate-background-color: rgb(240, 251, 158); 141 | background-color: rgb(245, 250, 199); 142 | show-decoration-selected: 1; 143 | border-width: 0px; 144 | border-style: solid; 145 | border-color: rgb(254, 210, 190); 146 | } 147 | 148 | QTreeView::item, QTreeWidget::item { 149 | border: 1px solid #FCD554; 150 | border-top-color: transparent; 151 | border-bottom-color: transparent; 152 | 153 | } 154 | 155 | QTreeView::item:hover, QTreeWidget::item:hover { 156 | background: qlineargradient(x1: 0, y1: 0, x2: 0.8, y2: 1, 157 | stop: 0 #FFD2B6, stop: 0.4 #FCA52C, 158 | stop: 0.2 #FEFBC8, stop: 1.0 #F6EDAB); 159 | border: 1px solid #bfcde4; 160 | } 161 | 162 | QTreeView::item:selected, QTreeWidget::item:selected { 163 | border: 1px solid #567dbc; 164 | background: qlineargradient(x1: 0, y1: 0, x2: 0.8, y2: 1, 165 | stop: 0 #F29627, stop: 0.4 #FCA52C, 166 | stop: 0.2 #FEFBC8, stop: 1.0 #F6EDAB); 167 | } 168 | 169 | QTreeView::item:selected:active, QTreeWidget::item:selected:active{ 170 | background: qlineargradient(x1: 0, y1: 0, x2: 0.8, y2: 1, 171 | stop: 0 #F0FB9E, stop: 0.4 #E6C1BD, 172 | stop: 0.2 #FCD554, stop: 1.0 #FFD2B6); 173 | } 174 | 175 | QTreeView::item:selected:!active, QTreeWidget::item:selected:!active { 176 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6b9be8, stop: 1 #577fbf); 177 | } 178 | 179 | QTreeView::branch, QTreeWidget::branch { 180 | background: #FFD2B6; 181 | } 182 | 183 | QTreeView::branch:has-siblings:!adjoins-item, QTreeWidget::branch:has-siblings:!adjoins-item { 184 | background: #E2D14E; 185 | } 186 | 187 | QTreeView::branch:has-siblings:adjoins-item, QTreeWidget::branch:has-siblings:adjoins-item { 188 | background: #76B8B6; 189 | } 190 | 191 | QTreeView::branch:!has-children:!has-siblings:adjoins-item, QTreeWidget::branch:!has-children:!has-siblings:adjoins-item { 192 | background: #b9d644; 193 | } 194 | 195 | QTreeView::branch:closed:has-children:has-siblings, QTreeWidget::branch:closed:has-children:has-siblings { 196 | background: #FCD554; 197 | } 198 | 199 | QTreeView::branch:has-children:!has-siblings:closed, QTreeWidget::branch:has-children:!has-siblings:closed { 200 | background: #DAC3A4; 201 | } 202 | 203 | QTreeView::branch:open:has-children:has-siblings, QTreeWidget::branch:open:has-children:has-siblings { 204 | background: #E0EEB3; 205 | } 206 | 207 | QTreeView::branch:open:has-children:!has-siblings, QTreeWidget::branch:open:has-children:!has-siblings { 208 | background: #949D6F; 209 | } 210 | QTreeView::branch:has-siblings:!adjoins-item, QTreeWidget::branch:has-siblings:!adjoins-item { 211 | border-image: url("src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-vline.png") 0; 212 | } 213 | 214 | QTreeView::branch:has-siblings:adjoins-item , QTreeWidget::branch:has-siblings:adjoins-item { 215 | border-image: url("src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-branch-more.png") 0; 216 | } 217 | 218 | QTreeView::branch:!has-children:!has-siblings:adjoins-item , QTreeWidget::branch:!has-children:!has-siblings:adjoins-item { 219 | border-image: url("src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-branch-end.png") 0; 220 | } 221 | 222 | QTreeView::branch:has-children:!has-siblings:closed, QTreeWidget::branch:has-children:!has-siblings:closed, 223 | QTreeView::branch:closed:has-children:has-siblings, QTreeWidget::branch:closed:has-children:has-siblings { 224 | border-image: none; 225 | image: url("src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-branch-closed.png"); 226 | } 227 | 228 | QTreeView::branch:open:has-children:!has-siblings, QTreeWidget::branch:open:has-children:!has-siblings, 229 | QTreeView::branch:open:has-children:has-siblings, QTreeWidget::branch:open:has-children:has-siblings { 230 | border-image: none; 231 | image: url("src/NodeNotePackage/NodeNote/Resources/Images/stylesheet-branch-open.png"); 232 | } 233 | 234 | 235 | /* this is combox */ 236 | QComboBox { 237 | color: white; 238 | font: 12px; 239 | border: 1px solid rgba(255, 255, 255, 50); 240 | border-radius: 0px; 241 | margin-left: 2px; 242 | margin-right: 2px; 243 | margin-top: 1px; 244 | margin-bottom: 1px; 245 | padding-left: 4px; 246 | padding-right: 4px; 247 | } 248 | QComboBox:hover { 249 | border: 1px solid rgba(255, 255, 255, 80); 250 | } 251 | QComboBox:editable { 252 | background: white; 253 | } 254 | QComboBox:!editable, QComboBox::drop-down:editable { 255 | background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, 256 | stop: 0 #005AA7, stop: 1.0 #FFFDE4); 257 | } 258 | QComboBox:!editable:on, QComboBox::drop-down:editable:on { 259 | background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, 260 | stop: 0 #C6FFDD, stop: 0.4 #FBD786, stop: 1.0 #f7797d); 261 | } 262 | QComboBox::drop-down { 263 | background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, 264 | stop: 0 #C6FFDD, stop: 0.4 #FBD786, stop: 1.0 #f7797d); 265 | border-left: 1px solid rgba(80, 80, 80, 255); 266 | width: 20px; 267 | } 268 | QComboBox::down-arrow { 269 | image: url("src/NodeNotePackage/NodeNote/Resources/Images/down_arrow.png"); 270 | } 271 | QComboBox::down-arrow:on { 272 | top: 1px; 273 | left: 1px; 274 | } 275 | QComboBox QAbstractItemView , QListView { 276 | background: rgb(209, 211, 88); 277 | border: 0px solid rgba(0, 0, 0, 0); 278 | } 279 | QListView::item { 280 | color: rgb(255, 255, 255); 281 | background: rgb(230, 189, 189); 282 | border-bottom: 1px solid rgb(170, 19, 19); 283 | border-radius: 0px; 284 | margin: 0px; 285 | padding: 2px; 286 | } 287 | QListView::item:selected { 288 | color: rgb(255, 255, 255); 289 | background: rgb(216, 170, 208); 290 | border-bottom: 1px solid rgb(180, 103, 103); 291 | border-radius: 0px; 292 | margin:0px; 293 | padding: 2px; 294 | } 295 | 296 | /* this is pushbutton */ 297 | QPushButton { 298 | background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, 299 | stop: 0 #C6FFDD, stop: 0.4 #FBD786, stop: 1.0 #f7797d); 300 | border-style: outset; 301 | border-width: 1px; 302 | border-radius: 10px; 303 | border-color: beige; 304 | font: bold 12px italic large; 305 | padding: 6px; 306 | } 307 | 308 | QPushButton:pressed { 309 | background-color: rgb(224, 0, 0); 310 | border-style: inset; 311 | } 312 | 313 | /* this is label */ 314 | QLabel { 315 | background-color: rgba(255, 204, 0, 200); 316 | border-style: outset; 317 | border-width: 1px; 318 | border-radius: 10px; 319 | border-color: beige; 320 | font: bold 12px italic large; 321 | padding: 6px; 322 | } 323 | QLabel#title_label { 324 | color: white; 325 | background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, 326 | stop: 0 #2980B9, stop: 0.4 #6DD5FA, stop: 1.0 #FFFFFF); 327 | border-style: outset; 328 | border-width: 1px; 329 | border-radius: 10px; 330 | border-color: beige; 331 | font: bold 14px italic large; 332 | padding: 6px; 333 | } 334 | QLabel#color_label { 335 | background-color: #ffcc00; 336 | border-style: outset; 337 | border-width: 1px; 338 | border-radius: 10px; 339 | border-color: beige; 340 | font: bold 12px italic large; 341 | padding: 6px; 342 | } 343 | QLabel#font_label { 344 | background-color: rgba(153, 0, 255, 200); 345 | border-style: outset; 346 | border-width: 1px; 347 | border-radius: 10px; 348 | border-color: beige; 349 | font: bold 12px italic large; 350 | padding: 6px; 351 | } 352 | QLabel#todo_label, QLabel#file_label { 353 | background-color: rgba(200, 200, 200, 100); 354 | border-style: outset; 355 | border-width: 1px; 356 | border-color: beige; 357 | border-radius: 0px; 358 | font: bold 12px italic large; 359 | padding: 6px; 360 | } 361 | 362 | /* this is spin box */ 363 | QDoubleSpinBox { 364 | color: rgb(43, 41, 42); 365 | selection-background-color: rgb(139, 26, 45); 366 | border: 2px solid blue; 367 | border-radius: 5px; 368 | padding-left: 2px; 369 | padding-top: 2px; 370 | background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, 371 | stop: 0 #C6FFDD, stop: 0.4 #FBD786, stop: 1.0 #f7797d); 372 | } 373 | QDoubleSpinBox::up-button {subcontrol-origin:border; 374 | subcontrol-position:right; 375 | image: url("src/NodeNotePackage/NodeNote/Resources/Images/spin_up.png"); 376 | width: 16px; 377 | height: 16px; 378 | } 379 | QDoubleSpinBox::down-button{subcontrol-origin:border; 380 | subcontrol-position:left; 381 | border-image: url("src/NodeNotePackage/NodeNote/Resources/Images/spin_down.png"); 382 | width: 16px; 383 | height: 16px; 384 | } 385 | 386 | 387 | /* this is for searching */ 388 | QLineEdit { 389 | border: 2px solid gray; 390 | border-radius: 0px; 391 | padding: 0 8px; 392 | background: beige; 393 | selection-background-color: darkgray; 394 | } 395 | 396 | /* this is menu */ 397 | QMenu { 398 | background-color: #F3C892; /* sets background of the menu */ 399 | border: 1px solid black; 400 | } 401 | QMenu::item { 402 | background-color: transparent; 403 | } 404 | QMenu::item:selected { 405 | background-color: #FF7F3F; 406 | } 407 | 408 | /* this is logic widget */ 409 | QGroupBox { 410 | background-color: rgba(0, 0, 0, 0); 411 | margin-top: 1px; 412 | padding-top: 10px; 413 | padding-bottom: 2px; 414 | padding-left: 5px; 415 | padding-right: 5px; 416 | font-size: 8pt; 417 | } 418 | QGroupBox::title { 419 | subcontrol-origin: margin; 420 | subcontrol-position: top center; 421 | color: rgba(0, 0, 0, 180); 422 | padding: 0px; 423 | left:-4px; 424 | } -------------------------------------------------------------------------------- /src/NodeNotePackage/NodeNote/Resources/MultiLanguages/zh_CN.ts: -------------------------------------------------------------------------------- 1 | 2 |