Monday, August 22, 2022

Glimmer DSL for SWT Joins The Dark Side w/ Code Text

In Glimmer DSL for SWT v4.24.2.2, the `code_text` custom widget, which supports syntax highlighting for 204 languages, has been upgraded with support for Dark Mode, utilizing the "glimmer_dark" theme. That said, the `code_text` custom widget can utilize any custom theme built for the Rouge Ruby gem by requiring it and passing its name in the `theme` option. So, users are not limited to the "glimmer_dark" theme for Dark Mode or the "glimmer", "github", and "paiste" themes for Light Mode. However, any Dark Mode custom theme must have the word "dark" in its name or else the `code_text` custom widget will automatically force the "glimmer_dark" theme when the operating system is in Dark Mode to ensure a good look.


Even the Hello, Code Text! sample gets a different look when the operating system is in Dark Mode (ignoring whatever Light Mode theme is supplied and forcing the "glimmer_dark" theme).




Check out the Hello, Code Text! code for an example of using `code_text`.

# From: https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_SAMPLES.md#hello-code-text
require 'glimmer-dsl-swt'
class HelloCodeText
include Glimmer::UI::CustomShell
attr_accessor :ruby_code, :js_code, :html_code
before_body do
self.ruby_code = <<~RUBY
greeting = 'Hello, World!'
include Glimmer
shell {
text 'Glimmer'
label {
text greeting
font height: 30, style: :bold
}
}.open
RUBY
self.js_code = <<~JS
function greet(greeting) {
alert(greeting);
}
var greetingString = 'Hello, World!';
greet(greetingString);
var moreGreetings = ['Howdy!', 'Aloha!', 'Hey!']
for(var greeting of moreGreetings) {
greet(greeting)
}
JS
self.html_code = <<~HTML
<html>
<body>
<section class="accordion">
<form method="post" id="name">
<label for="name">
Name
</label>
<input name="name" type="text" />
<input type="submit" />
</form>
</section>
</body>
</html>
HTML
end
body {
shell {
minimum_size 640, 480
text 'Hello, Code Text!'
tab_folder {
tab_item {
fill_layout
text 'Ruby (glimmer theme)'
# Note: code_text theme is currently ignored in dark mode
code_text(language: 'ruby', theme: 'glimmer', lines: true) { # theme is currently ignored in dark mode
text <=> [self, :ruby_code]
}
}
tab_item {
fill_layout
text 'JavaScript (pastie theme)'
# Note: code_text theme is currently ignored in dark mode
code_text(:multi, :h_scroll, :v_scroll, language: 'javascript', theme: 'pastie', lines: {width: 2}) {
root {
grid_layout(2, false) {
margin_width 2
}
background Display.system_dark_theme? ? :black : :white
}
line_numbers {
background Display.system_dark_theme? ? :black : :white
}
text <=> [self, :js_code]
}
}
tab_item {
fill_layout
text 'HTML (github theme)'
# Note: code_text theme is currently ignored in dark mode
code_text(language: 'html', theme: 'github') { # default is lines: false
text <=> [self, :html_code]
}
}
}
}
}
end
HelloCodeText.launch

And, here is an example of how to build a custom Rouge theme ('github' theme):

# From: https://raw.githubusercontent.com/rouge-ruby/rouge/16ffecb89261cc95ae2cabdb288183f758d9116b/lib/rouge/themes/github.rb
module Rouge
module Themes
class Github < CSSTheme
name 'github'
style Comment::Multiline, :fg => '#999988', :italic => true
style Comment::Preproc, :fg => '#999999', :bold => true
style Comment::Single, :fg => '#999988', :italic => true
style Comment::Special, :fg => '#999999', :italic => true, :bold => true
style Comment, :fg => '#999988', :italic => true
style Error, :fg => '#a61717', :bg => '#e3d2d2'
style Generic::Deleted, :fg => '#000000', :bg => '#ffdddd'
style Generic::Emph, :fg => '#000000', :italic => true
style Generic::Error, :fg => '#aa0000'
style Generic::Heading, :fg => '#999999'
style Generic::Inserted, :fg => '#000000', :bg => '#ddffdd'
style Generic::Output, :fg => '#888888'
style Generic::Prompt, :fg => '#555555'
style Generic::Strong, :bold => true
style Generic::Subheading, :fg => '#aaaaaa'
style Generic::Traceback, :fg => '#aa0000'
style Keyword::Constant, :fg => '#000000', :bold => true
style Keyword::Declaration, :fg => '#000000', :bold => true
style Keyword::Namespace, :fg => '#000000', :bold => true
style Keyword::Pseudo, :fg => '#000000', :bold => true
style Keyword::Reserved, :fg => '#000000', :bold => true
style Keyword::Type, :fg => '#445588', :bold => true
style Keyword, :fg => '#000000', :bold => true
style Literal::Number::Float, :fg => '#009999'
style Literal::Number::Hex, :fg => '#009999'
style Literal::Number::Integer::Long, :fg => '#009999'
style Literal::Number::Integer, :fg => '#009999'
style Literal::Number::Oct, :fg => '#009999'
style Literal::Number, :fg => '#009999'
style Literal::String::Affix, :fg => '#000000', :bold => true
style Literal::String::Backtick, :fg => '#d14'
style Literal::String::Char, :fg => '#d14'
style Literal::String::Doc, :fg => '#d14'
style Literal::String::Double, :fg => '#d14'
style Literal::String::Escape, :fg => '#d14'
style Literal::String::Heredoc, :fg => '#d14'
style Literal::String::Interpol, :fg => '#d14'
style Literal::String::Other, :fg => '#d14'
style Literal::String::Regex, :fg => '#009926'
style Literal::String::Single, :fg => '#d14'
style Literal::String::Symbol, :fg => '#990073'
style Literal::String, :fg => '#d14'
style Name::Attribute, :fg => '#008080'
style Name::Builtin::Pseudo, :fg => '#999999'
style Name::Builtin, :fg => '#0086B3'
style Name::Class, :fg => '#445588', :bold => true
style Name::Constant, :fg => '#008080'
style Name::Decorator, :fg => '#3c5d5d', :bold => true
style Name::Entity, :fg => '#800080'
style Name::Exception, :fg => '#990000', :bold => true
style Name::Function, :fg => '#990000', :bold => true
style Name::Label, :fg => '#990000', :bold => true
style Name::Namespace, :fg => '#555555'
style Name::Tag, :fg => '#000080'
style Name::Variable::Class, :fg => '#008080'
style Name::Variable::Global, :fg => '#008080'
style Name::Variable::Instance, :fg => '#008080'
style Name::Variable, :fg => '#008080'
style Operator::Word, :fg => '#000000', :bold => true
style Operator, :fg => '#000000', :bold => true
style Text::Whitespace, :fg => '#bbbbbb'
style Text, :bg => '#f8f8f8'
end
end
end

Glimmer On!

3 comments:

Mike said...

As a programmer that has been at it for too long, dark mode and bright fonts are very appreciated. EVERY code editor needs to implement a ZOOM feature like VS Code too.

Andy Maleh said...

Thanks for your comment.

I personally never use Dark Mode, but I added the feature because someone requested it. Still, developers always had the option to build their own Rouge theme too if they wanted.

"EVERY code editor needs to implement a ZOOM feature like VS Code too."

This is left to application developers. They could augment `code_text` with that feature without much effort if they want.

Still, if you'd like that to become a built-in feature of `code_text`, this could be your chance to become a contributor to Glimmer since it's an open-source project. In fact, that's how I became a contributor to many open-source projects like the Ruby git gem and RVM. I just added what I needed to them.

Cheers.

Andy Maleh said...

Nevermind, I beat you to it and implemented the Zoom-In/Zoom-Out/Restore feature as default behavior in `code_text` in Glimmer DSL for SWT v4.24.3.1. The operations can be performed by the default CMD = / CMD - / CMD 0 shortcuts on the Mac just like they work in web browsers (CTRL = / CTRL - / CTRL 0 on Linux/Windows).

It is mentioned at the bottom of this blog post:
https://andymaleh.blogspot.com/2022/08/glimmer-dsl-for-swt-data-binding-table.html

It is demonstrated by Hello, Code Text!:
https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_SAMPLES.md#hello-code-text

It is documented in Glimmer GUI DSL Syntax guide (under Code Text Options -> default_behavior):
https://github.com/AndyObtiva/glimmer-dsl-swt/blob/master/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#code-text-custom-widget