Last active
August 15, 2026 15:30
-
-
Save yspkm/f1185dc4c7b5b94fab386dd68ad3884d to your computer and use it in GitHub Desktop.
KLayout Dark mode
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module MyMacro | |
| include RBA | |
| # Use the platform-independent Qt Fusion style | |
| RBA::QApplication::setStyle("Fusion") | |
| palette = RBA::QPalette::new | |
| # Common colors for active, inactive and disabled states. | |
| # State-specific exceptions are defined below. | |
| role_colors = [ | |
| # Main surfaces | |
| [RBA::QPalette::Window, "#24282F"], | |
| [RBA::QPalette::Base, "#1B1F24"], | |
| [RBA::QPalette::AlternateBase, "#282D35"], | |
| [RBA::QPalette::Button, "#303640"], | |
| # Main text | |
| [RBA::QPalette::WindowText, "#D4DAE3"], | |
| [RBA::QPalette::Text, "#D4DAE3"], | |
| [RBA::QPalette::ButtonText, "#E1E6ED"], | |
| [RBA::QPalette::BrightText, "#FFFFFF"], | |
| # Borders and depth | |
| [RBA::QPalette::Light, "#4A525E"], | |
| [RBA::QPalette::Midlight, "#3B424C"], | |
| [RBA::QPalette::Mid, "#30363F"], | |
| [RBA::QPalette::Dark, "#171A1F"], | |
| [RBA::QPalette::Shadow, "#0C0E11"], | |
| # Selection | |
| [RBA::QPalette::Highlight, "#316DCA"], | |
| [RBA::QPalette::HighlightedText, "#FFFFFF"], | |
| # Tooltips | |
| [RBA::QPalette::ToolTipBase, "#343A43"], | |
| [RBA::QPalette::ToolTipText, "#F3F6F9"], | |
| # Links and placeholders | |
| [RBA::QPalette::Link, "#6CB6FF"], | |
| [RBA::QPalette::LinkVisited, "#C49AF6"], | |
| [RBA::QPalette::PlaceholderText, "#8B95A3"] | |
| ] | |
| role_colors.each do |role, hex| | |
| palette.setColor( | |
| role, | |
| RBA::QColor::new(hex) | |
| ) | |
| end | |
| # Inactive windows: | |
| # keep selections visible, but less prominent | |
| palette.setColor( | |
| RBA::QPalette::Inactive, | |
| RBA::QPalette::Highlight, | |
| RBA::QColor::new("#3B4655") | |
| ) | |
| palette.setColor( | |
| RBA::QPalette::Inactive, | |
| RBA::QPalette::HighlightedText, | |
| RBA::QColor::new("#D4DAE3") | |
| ) | |
| # Disabled controls: | |
| # visibly disabled without becoming unreadable | |
| [ | |
| RBA::QPalette::WindowText, | |
| RBA::QPalette::Text, | |
| RBA::QPalette::ButtonText | |
| ].each do |role| | |
| palette.setColor( | |
| RBA::QPalette::Disabled, | |
| role, | |
| RBA::QColor::new("#6F7885") | |
| ) | |
| end | |
| palette.setColor( | |
| RBA::QPalette::Disabled, | |
| RBA::QPalette::Button, | |
| RBA::QColor::new("#282D34") | |
| ) | |
| palette.setColor( | |
| RBA::QPalette::Disabled, | |
| RBA::QPalette::Base, | |
| RBA::QColor::new("#20242A") | |
| ) | |
| palette.setColor( | |
| RBA::QPalette::Disabled, | |
| RBA::QPalette::Highlight, | |
| RBA::QColor::new("#343B45") | |
| ) | |
| palette.setColor( | |
| RBA::QPalette::Disabled, | |
| RBA::QPalette::HighlightedText, | |
| RBA::QColor::new("#7F8996") | |
| ) | |
| RBA::QApplication::setPalette(palette) | |
| # ------------------------------------------------------------ | |
| # Macro Editor syntax theme | |
| # Low-chroma, high-readability dark theme | |
| # ------------------------------------------------------------ | |
| app = RBA::Application::instance | |
| editor_styles = <<~STYLES | |
| basic: | |
| 'Alert'=(bold:true,color:'#E78284',background:'#3A2024'), | |
| 'Attribute'=(bold:false,color:'#B8C4D4'), | |
| 'Base-N Integer'=(bold:false,color:'#D9A66C'), | |
| 'Built-in'=(bold:false,color:'#88C0D0'), | |
| 'Character'=(bold:false,color:'#A7C080'), | |
| 'Comment'=(italic:false,bold:false,color:'#8B95A5'), | |
| 'Control Flow'=(bold:false,color:'#C9A0DC'), | |
| 'Data Type'=(bold:false,color:'#B8C4D4'), | |
| 'Decimal/Value'=(bold:false,color:'#D9A66C'), | |
| 'Error'=(bold:true,color:'#E78284',background:'#3A2024'), | |
| 'Extension'=(bold:false,color:'#B8C4D4'), | |
| 'Floating Point'=(bold:false,color:'#D9A66C'), | |
| 'Function'=(bold:false,color:'#88C0D0'), | |
| 'Import'=(bold:false,color:'#C9A0DC'), | |
| 'Keyword'=(bold:false,color:'#C9A0DC'), | |
| 'Normal'=(bold:false,color:'#D8DEE9'), | |
| 'Operator'=(bold:false,color:'#C9A0DC'), | |
| 'Others'=(bold:false,color:'#D8DEE9'), | |
| 'Preprocessor'=(bold:false,color:'#A7C080'), | |
| 'Region Marker'=(bold:false,color:'#88C0D0',background:'#28313B'), | |
| 'Special Character'=(bold:false,color:'#88C0D0'), | |
| 'Special String'=(bold:false,color:'#A7C080'), | |
| 'String'=(bold:false,color:'#A7C080'), | |
| 'Variable'=(bold:false,color:'#D8DEE9'), | |
| 'Verbatim String'=(bold:false,color:'#A7C080'); | |
| ruby: | |
| 'Access Control'=(bold:false,color:'#C9A0DC'), | |
| 'Attribute Definition'=(bold:false,color:'#88C0D0'), | |
| 'Bin'=(bold:false,color:'#D9A66C'), | |
| 'Blockcomment'=(italic:false,bold:false,color:'#8B95A5'), | |
| 'Char'=(bold:false,color:'#A7C080'), | |
| 'Class Variable'=(bold:false,color:'#D8DEE9'), | |
| 'Command'=(bold:false,color:'#88C0D0'), | |
| 'Comment'=(italic:false,bold:false,color:'#8B95A5'), | |
| 'Constant'=(bold:false,color:'#B8C4D4'), | |
| 'Constant Value'=(bold:false,color:'#D9A66C'), | |
| 'Data'=(bold:false,color:'#A7C080'), | |
| 'Dec'=(bold:false,color:'#D9A66C'), | |
| 'Default globals'=(bold:false,color:'#B8C4D4'), | |
| 'Definition'=(bold:false,color:'#88C0D0'), | |
| 'Delimiter'=(bold:false,color:'#C9A0DC'), | |
| 'Error'=(bold:true,color:'#E78284',background:'#3A2024'), | |
| 'Expression'=(bold:false,color:'#D8DEE9'), | |
| 'Float'=(bold:false,color:'#D9A66C'), | |
| 'GDL input'=(bold:false,color:'#A7C080'), | |
| 'Global Constant'=(bold:false,color:'#B8C4D4'), | |
| 'Global Variable'=(bold:false,color:'#D8DEE9'), | |
| 'Here Document'=(bold:false,color:'#A7C080'), | |
| 'Hex'=(bold:false,color:'#D9A66C'), | |
| 'Instance Variable'=(bold:false,color:'#D8DEE9'), | |
| 'Kernel methods'=(bold:false,color:'#88C0D0'), | |
| 'Keyword'=(bold:false,color:'#C9A0DC'), | |
| 'Member'=(bold:false,color:'#88C0D0'), | |
| 'Message'=(bold:false,color:'#88C0D0'), | |
| 'Module mixin methods'=(bold:false,color:'#88C0D0'), | |
| 'Normal Text'=(bold:false,color:'#D8DEE9'), | |
| 'Octal'=(bold:false,color:'#D9A66C'), | |
| 'Operator'=(bold:false,color:'#C9A0DC'), | |
| 'Pseudo variable'=(bold:false,color:'#B8C4D4'), | |
| 'RDoc Value'=(italic:false,bold:false,color:'#8B95A5'), | |
| 'Raw String'=(bold:false,color:'#A7C080'), | |
| 'Region Marker'=(bold:false,color:'#88C0D0',background:'#28313B'), | |
| 'Regular Expression'=(bold:false,color:'#A7C080'), | |
| 'String'=(bold:false,color:'#A7C080'), | |
| 'Substitution'=(bold:false,color:'#88C0D0'), | |
| 'Symbol'=(bold:false,color:'#A7C080'); | |
| STYLES | |
| app.set_config("macro-editor-styles", editor_styles) | |
| # Windows에서 가장 안정적으로 읽히는 기본 monospace font | |
| app.set_config("macro-editor-font-family", "Consolas") | |
| app.set_config("macro-editor-font-size", "14") | |
| app.commit_config | |
| # ------------------------------------------------------------ | |
| # Macro Development console theme | |
| # ------------------------------------------------------------ | |
| # Re-running this macro should not leave multiple timers active. | |
| if defined?($dark_console_timer) && $dark_console_timer | |
| begin | |
| $dark_console_timer.stop | |
| rescue | |
| end | |
| end | |
| $dark_console_last_text = nil | |
| # The Macro Development window may open after this startup macro, | |
| # so periodically look for its console. | |
| $dark_console_timer = RBA::QTimer::new | |
| $dark_console_timer.interval = 500 | |
| $dark_console_timer.timeout do | |
| begin | |
| macro_dialog = RBA::QApplication::topLevelWidgets.find do |widget| | |
| widget.objectName == "MacroEditorDialog" | |
| end | |
| next unless macro_dialog | |
| console_frame = macro_dialog.findChild("console_text_frame") | |
| next unless console_frame | |
| console = console_frame.findChildren.find do |object| | |
| object.inherits("QPlainTextEdit") || | |
| object.inherits("QTextEdit") | |
| end | |
| next unless console | |
| # Apply the widget appearance once per console instance. | |
| if console.objectName != "DarkModeMacroConsole" | |
| console.objectName = "DarkModeMacroConsole" | |
| console.setStyleSheet(<<~QSS) | |
| QPlainTextEdit, QTextEdit { | |
| background-color: #0D1117; | |
| color: #C9D1D9; | |
| border: 1px solid #30363D; | |
| border-radius: 2px; | |
| padding: 5px; | |
| font-family: Consolas; | |
| font-size: 11pt; | |
| selection-background-color: #264F78; | |
| selection-color: #FFFFFF; | |
| } | |
| QSS | |
| $dark_console_last_text = nil | |
| end | |
| # KLayout inserts pure-blue and pure-red character formatting. | |
| # Recolor the document whenever new console text appears. | |
| console_text = console.toPlainText | |
| next if console_text == $dark_console_last_text | |
| cursor = RBA::QTextCursor::new(console.document) | |
| cursor.select(RBA::QTextCursor::Document) | |
| text_format = RBA::QTextCharFormat::new | |
| text_format.foreground = RBA::QBrush::new( | |
| RBA::QColor::new("#C9D1D9") | |
| ) | |
| cursor.mergeCharFormat(text_format) | |
| $dark_console_last_text = console_text | |
| rescue | |
| # The dialog may be in the middle of opening or closing. | |
| # The timer will safely retry on the next interval. | |
| end | |
| end | |
| $dark_console_timer.start | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import builtins | |
| import pya | |
| # ============================================================ | |
| # User-adjustable settings | |
| # ============================================================ | |
| FONT_FAMILY = "Consolas" | |
| EDITOR_FONT_SIZE = 14 | |
| CONSOLE_FONT_SIZE = 11 | |
| def color(value): | |
| return pya.QColor(value) | |
| # ============================================================ | |
| # 1. Application-wide dark palette | |
| # ============================================================ | |
| def apply_dark_palette(): | |
| pya.QApplication.setStyle("Fusion") | |
| palette = pya.QPalette() | |
| roles = [ | |
| # Main surfaces | |
| (pya.QPalette.Window, "#24282F"), | |
| (pya.QPalette.Base, "#1B1F24"), | |
| (pya.QPalette.AlternateBase, "#282D35"), | |
| (pya.QPalette.Button, "#303640"), | |
| # Main text | |
| (pya.QPalette.WindowText, "#D4DAE3"), | |
| (pya.QPalette.Text, "#D4DAE3"), | |
| (pya.QPalette.ButtonText, "#E1E6ED"), | |
| (pya.QPalette.BrightText, "#FFFFFF"), | |
| # Borders and depth | |
| (pya.QPalette.Light, "#4A525E"), | |
| (pya.QPalette.Midlight, "#3B424C"), | |
| (pya.QPalette.Mid, "#30363F"), | |
| (pya.QPalette.Dark, "#171A1F"), | |
| (pya.QPalette.Shadow, "#0C0E11"), | |
| # Selection | |
| (pya.QPalette.Highlight, "#316DCA"), | |
| (pya.QPalette.HighlightedText, "#FFFFFF"), | |
| # Tooltips and links | |
| (pya.QPalette.ToolTipBase, "#343A43"), | |
| (pya.QPalette.ToolTipText, "#F3F6F9"), | |
| (pya.QPalette.Link, "#78B8FF"), | |
| ] | |
| # These roles depend slightly on the bundled Qt version. | |
| for optional_role, value in ( | |
| ("LinkVisited", "#C7A0F4"), | |
| ("PlaceholderText", "#8B95A3"), | |
| ): | |
| if hasattr(pya.QPalette, optional_role): | |
| roles.append( | |
| ( | |
| getattr(pya.QPalette, optional_role), | |
| value, | |
| ) | |
| ) | |
| for role, value in roles: | |
| palette.setColor( | |
| role, | |
| color(value), | |
| ) | |
| # Inactive windows | |
| palette.setColor( | |
| pya.QPalette.Inactive, | |
| pya.QPalette.Highlight, | |
| color("#3B4655"), | |
| ) | |
| palette.setColor( | |
| pya.QPalette.Inactive, | |
| pya.QPalette.HighlightedText, | |
| color("#D4DAE3"), | |
| ) | |
| # Disabled text | |
| for role in ( | |
| pya.QPalette.WindowText, | |
| pya.QPalette.Text, | |
| pya.QPalette.ButtonText, | |
| ): | |
| palette.setColor( | |
| pya.QPalette.Disabled, | |
| role, | |
| color("#6F7885"), | |
| ) | |
| # Disabled surfaces | |
| for role, value in ( | |
| (pya.QPalette.Button, "#282D34"), | |
| (pya.QPalette.Base, "#20242A"), | |
| (pya.QPalette.Highlight, "#343B45"), | |
| (pya.QPalette.HighlightedText, "#7F8996"), | |
| ): | |
| palette.setColor( | |
| pya.QPalette.Disabled, | |
| role, | |
| color(value), | |
| ) | |
| pya.QApplication.setPalette(palette) | |
| # ============================================================ | |
| # 2. Macro Development editor theme | |
| # ============================================================ | |
| def apply_macro_editor_theme(): | |
| app = pya.Application.instance() | |
| editor_styles = r""" | |
| basic: | |
| 'Alert'=(bold:true,color:'#F7768E',background:'#3A2028'), | |
| 'Attribute'=(bold:false,color:'#B8C4D4'), | |
| 'Base-N Integer'=(bold:false,color:'#F2B880'), | |
| 'Built-in'=(bold:false,color:'#7DCFFF'), | |
| 'Character'=(bold:false,color:'#9ECE6A'), | |
| 'Comment'=(italic:false,bold:false,color:'#8B95A5'), | |
| 'Control Flow'=(bold:false,color:'#C099FF'), | |
| 'Data Type'=(bold:false,color:'#7AA2F7'), | |
| 'Decimal/Value'=(bold:false,color:'#F2B880'), | |
| 'Error'=(bold:true,color:'#F7768E',background:'#3A2028'), | |
| 'Extension'=(bold:false,color:'#7DCFFF'), | |
| 'Floating Point'=(bold:false,color:'#F2B880'), | |
| 'Function'=(bold:false,color:'#7DCFFF'), | |
| 'Import'=(bold:false,color:'#C099FF'), | |
| 'Keyword'=(bold:false,color:'#C099FF'), | |
| 'Normal'=(bold:false,color:'#D8DEE9'), | |
| 'Operator'=(bold:false,color:'#89DDFF'), | |
| 'Others'=(bold:false,color:'#D8DEE9'), | |
| 'Preprocessor'=(bold:false,color:'#E0AF68'), | |
| 'Region Marker'=(bold:false,color:'#7DCFFF',background:'#28313B'), | |
| 'Special Character'=(bold:false,color:'#7DCFFF'), | |
| 'Special String'=(bold:false,color:'#9ECE6A'), | |
| 'String'=(bold:false,color:'#9ECE6A'), | |
| 'Variable'=(bold:false,color:'#D8DEE9'), | |
| 'Verbatim String'=(bold:false,color:'#9ECE6A'); | |
| ruby: | |
| 'Access Control'=(bold:false,color:'#C099FF'), | |
| 'Attribute Definition'=(bold:false,color:'#7DCFFF'), | |
| 'Bin'=(bold:false,color:'#F2B880'), | |
| 'Blockcomment'=(italic:false,bold:false,color:'#8B95A5'), | |
| 'Char'=(bold:false,color:'#9ECE6A'), | |
| 'Class Variable'=(bold:false,color:'#D8DEE9'), | |
| 'Command'=(bold:false,color:'#7DCFFF'), | |
| 'Comment'=(italic:false,bold:false,color:'#8B95A5'), | |
| 'Constant'=(bold:false,color:'#7AA2F7'), | |
| 'Constant Value'=(bold:false,color:'#F2B880'), | |
| 'Data'=(bold:false,color:'#9ECE6A'), | |
| 'Dec'=(bold:false,color:'#F2B880'), | |
| 'Default globals'=(bold:false,color:'#E0AF68'), | |
| 'Definition'=(bold:false,color:'#7DCFFF'), | |
| 'Delimiter'=(bold:false,color:'#89DDFF'), | |
| 'Error'=(bold:true,color:'#F7768E',background:'#3A2028'), | |
| 'Expression'=(bold:false,color:'#D8DEE9'), | |
| 'Float'=(bold:false,color:'#F2B880'), | |
| 'GDL input'=(bold:false,color:'#9ECE6A'), | |
| 'Global Constant'=(bold:false,color:'#7AA2F7'), | |
| 'Global Variable'=(bold:false,color:'#D8DEE9'), | |
| 'Here Document'=(bold:false,color:'#9ECE6A'), | |
| 'Hex'=(bold:false,color:'#F2B880'), | |
| 'Instance Variable'=(bold:false,color:'#D8DEE9'), | |
| 'Kernel methods'=(bold:false,color:'#7DCFFF'), | |
| 'Keyword'=(bold:false,color:'#C099FF'), | |
| 'Member'=(bold:false,color:'#7DCFFF'), | |
| 'Message'=(bold:false,color:'#7DCFFF'), | |
| 'Module mixin methods'=(bold:false,color:'#7DCFFF'), | |
| 'Normal Text'=(bold:false,color:'#D8DEE9'), | |
| 'Octal'=(bold:false,color:'#F2B880'), | |
| 'Operator'=(bold:false,color:'#89DDFF'), | |
| 'Pseudo variable'=(bold:false,color:'#E0AF68'), | |
| 'RDoc Value'=(italic:false,bold:false,color:'#8B95A5'), | |
| 'Raw String'=(bold:false,color:'#9ECE6A'), | |
| 'Region Marker'=(bold:false,color:'#7DCFFF',background:'#28313B'), | |
| 'Regular Expression'=(bold:false,color:'#9ECE6A'), | |
| 'String'=(bold:false,color:'#9ECE6A'), | |
| 'Substitution'=(bold:false,color:'#7DCFFF'), | |
| 'Symbol'=(bold:false,color:'#E0AF68'); | |
| python: | |
| 'Builtin Function'=(bold:false,color:'#7DCFFF'), | |
| 'ClassNames'=(italic:false,bold:false,color:'#7AA2F7'), | |
| 'Comment'=(italic:false,bold:false,color:'#8B95A5'), | |
| 'Complex'=(bold:false,color:'#F2B880'), | |
| 'Decorator'=(bold:false,color:'#E0AF68'), | |
| 'Definition Keyword'=(bold:false,color:'#C099FF'), | |
| 'Error'=(bold:true,color:'#F7768E',background:'#3A2028'), | |
| 'Exceptions'=(bold:false,color:'#F7768E'), | |
| 'Extensions'=(bold:false,color:'#7DCFFF'), | |
| 'F-String'=(bold:false,color:'#9ECE6A'), | |
| 'Float'=(bold:false,color:'#F2B880'), | |
| 'Flow Control Keyword'=(bold:false,color:'#C099FF'), | |
| 'Hex'=(bold:false,color:'#F2B880'), | |
| 'Import'=(bold:false,color:'#C099FF'), | |
| 'Int'=(bold:false,color:'#F2B880'), | |
| 'Normal Text'=(bold:false,color:'#D8DEE9'), | |
| 'Octal'=(bold:false,color:'#F2B880'), | |
| 'Operator'=(bold:false,color:'#89DDFF'), | |
| 'Operator Keyword'=(bold:false,color:'#C099FF'), | |
| 'Overloaders'=(bold:false,color:'#7DCFFF'), | |
| 'Raw F-String'=(bold:false,color:'#9ECE6A'), | |
| 'Raw String'=(bold:false,color:'#9ECE6A'), | |
| 'Special Variable'=(bold:false,color:'#E0AF68'), | |
| 'String'=(bold:false,color:'#9ECE6A'), | |
| 'String Char'=(bold:false,color:'#7DCFFF'), | |
| 'String Substitution'=(bold:false,color:'#7DCFFF'); | |
| """ | |
| app.set_config( | |
| "macro-editor-styles", | |
| editor_styles, | |
| ) | |
| app.set_config( | |
| "macro-editor-font-family", | |
| FONT_FAMILY, | |
| ) | |
| app.set_config( | |
| "macro-editor-font-size", | |
| str(EDITOR_FONT_SIZE), | |
| ) | |
| try: | |
| app.commit_config() | |
| except Exception: | |
| # Some KLayout builds apply set_config immediately. | |
| pass | |
| # ============================================================ | |
| # 3. Macro Development console theme | |
| # ============================================================ | |
| CONSOLE_STYLE = f""" | |
| QPlainTextEdit, QTextEdit {{ | |
| background-color: #0D1117; | |
| color: #C9D1D9; | |
| border: 1px solid #30363D; | |
| border-radius: 2px; | |
| padding: 5px; | |
| font-family: {FONT_FAMILY}; | |
| font-size: {CONSOLE_FONT_SIZE}pt; | |
| selection-background-color: #264F78; | |
| selection-color: #FFFFFF; | |
| }} | |
| """ | |
| def install_console_theme(): | |
| # Stop the old timer when this macro is run repeatedly with F5. | |
| old_timer = getattr( | |
| builtins, | |
| "_klayout_dark_console_timer", | |
| None, | |
| ) | |
| if old_timer is not None: | |
| try: | |
| old_timer.stop() | |
| except Exception: | |
| pass | |
| state = { | |
| "last_text": None, | |
| } | |
| def refresh_console(): | |
| try: | |
| # Find the Macro Development window. | |
| macro_dialog = next( | |
| ( | |
| widget | |
| for widget in pya.QApplication.topLevelWidgets() | |
| if widget.objectName == "MacroEditorDialog" | |
| ), | |
| None, | |
| ) | |
| if macro_dialog is None: | |
| state["last_text"] = None | |
| return | |
| # Find the console container. | |
| frame = macro_dialog.findChild( | |
| "console_text_frame" | |
| ) | |
| if frame is None: | |
| return | |
| # Find the actual QPlainTextEdit/QTextEdit console. | |
| console = next( | |
| ( | |
| child | |
| for child in frame.findChildren() | |
| if child.inherits("QPlainTextEdit") | |
| or child.inherits("QTextEdit") | |
| ), | |
| None, | |
| ) | |
| if console is None: | |
| return | |
| # Apply the console widget style once. | |
| if console.objectName != "DarkModeMacroConsole": | |
| console.objectName = "DarkModeMacroConsole" | |
| console.setStyleSheet(CONSOLE_STYLE) | |
| state["last_text"] = None | |
| current_text = console.toPlainText() | |
| if current_text == state["last_text"]: | |
| return | |
| # KLayout inserts some console output using direct | |
| # per-character colors. Replace foreground only. | |
| # Bold formatting is retained. | |
| cursor = pya.QTextCursor( | |
| console.document | |
| ) | |
| cursor.select( | |
| pya.QTextCursor.Document | |
| ) | |
| text_format = pya.QTextCharFormat() | |
| text_format.foreground = pya.QBrush( | |
| color("#C9D1D9") | |
| ) | |
| cursor.mergeCharFormat( | |
| text_format | |
| ) | |
| state["last_text"] = current_text | |
| except Exception: | |
| # The Macro Development window may currently be | |
| # opening or closing. Retry on the next timer tick. | |
| pass | |
| timer = pya.QTimer() | |
| timer.interval = 400 | |
| timer.timeout = refresh_console | |
| refresh_console() | |
| timer.start() | |
| # Keep the timer and callback alive after macro execution. | |
| builtins._klayout_dark_console_timer = timer | |
| builtins._klayout_dark_console_refresh = refresh_console | |
| builtins._klayout_dark_console_state = state | |
| # ============================================================ | |
| # Apply everything | |
| # ============================================================ | |
| apply_dark_palette() | |
| apply_macro_editor_theme() | |
| install_console_theme() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment