Skip to content

Commit

Permalink
for #410, add emeus-vfl-parser and shoes-vfl-parser
Browse files Browse the repository at this point in the history
* independent of solver except for using standard terminalogy
  which Shoes doesn't provide. Like 'super' where we have 'canvas'
  Clever person could figure out how to get vfl constraints mapped
  to cassowary-ruby gem.
  • Loading branch information
Cecil committed Oct 24, 2018
1 parent 7cbacc5 commit 4ac78e2
Show file tree
Hide file tree
Showing 14 changed files with 1,971 additions and 44 deletions.
3 changes: 2 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,8 @@ end
#These tasks create object files:
SubDirs = ["#{rtp}/zzbase.done", "#{rtp}/http/zzdownload.done",
"#{rtp}/plot/zzplot.done", "#{rtp}/console/zzconsole.done",
"#{rtp}/types/zzwidgets.done", "#{rtp}/native/zznative.done"]
"#{rtp}/types/zzwidgets.done", "#{rtp}/layout/zzlayout.done",
"#{rtp}/native/zznative.done"]

# Windows doesn't use console - don't try to build it. Delete from dependcies
case TGT_DIR
Expand Down
4 changes: 2 additions & 2 deletions Tests/layout/cs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def initialize(identifier)
# Button1 starts 50 from the left margin.
solver.add_constraint(b1.left.cn_equal left_limit + 50)

# Button2 ends 50 from the right margin (???)
# Button2 ends 50 from the right margin
solver.add_constraint((left_limit + right_limit).cn_equal b2.left + b2.width + 50)

# Button2 starts at least 100 from the end of Button1. This is the
Expand All @@ -46,7 +46,7 @@ def initialize(identifier)

# Button1's preferred width is 87
solver.add_constraint(b1.width.cn_equal 87, Strength::StrongStrength)

puts "b1: #{b1.inspect}"
# Button2's minimum width is 113
solver.add_constraint(b2.width.cn_geq 113)

Expand Down
54 changes: 54 additions & 0 deletions Tests/layout/test-unit.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
Vfl internal layout setup called
shoes_layout_internal_add called
shoes_layout_internal_add called
shoes_layout_internal_add called
shoes_layout_internal_size called pass: 0
shoes_layout_internal_size called pass: 1
In shoes_vfl_test
Parsing [invalid]: 'V|[backgroundBox]|'
Error: Expected ':' after vertical orientation
Parsing [invalid]: '[backgroundBox)'
Error: A predicate must follow a view name
Parsing [invalid]: '[backgroundBox(]'
Error: A predicate on a view must end with ')'
Parsing [invalid]: '[view]'
Error: Unable to find view with name 'view'
Parsing [invalid]: '[view]-'
Error: Unterminated spacing
Parsing [invalid]: '-[view]'
Error: Spacing cannot be set without a view
Parsing [invalid]: '[['
Error: View identifiers must be valid C identifiers
Parsing [invalid]: '[9ab]'
Error: View identifiers must be valid C identifiers
Parsing [invalid]: '[-a]'
Error: View identifiers must be valid C identifiers
Parsing [invalid]: '[view(>30)]'
Error: Unknown relation; must be one of '==', '>=', or '<='
Parsing [invalid]: '[view(>=30@foo)]'
Error: Priority must be a positive number or one of 'weak', 'medium', 'strong', and 'required'
Parsing [invalid]: '[view(view + wrong)]'
Error: Expected positive number as a constant
Parsing [invalid]: '[view(view.wrong)]'
Error: Attribute must be on one of 'width', 'height', 'centerX', 'centerY', 'top', 'bottom', 'left', 'right', 'start', 'end', 'baseline'
Parsing [valid]: '[button]-[textField]'
Parsing [valid]: '[button(>=50)]'
Parsing [valid]: '|-50-[purpleBox]-50-|'
Parsing [valid]: '|-[view]'
Parsing [valid]: '[view]|'
Parsing [valid]: 'V:[topField]-10-[bottomField]'
Parsing [valid]: '[maroonView][blueView]'
Parsing [valid]: '[button(100@strong)]'
Parsing [valid]: '[button1(==button2)]'
Parsing [valid]: '[flexibleButton(>=70,<=100)]'
Parsing [valid]: '|-[find]-[findNext]-[findField(>=20)]-|'
Parsing [valid]: 'H:|-8-[view1(==view2)]-12-[view2]-8-|'
Parsing [valid]: 'H:|-8-[view3]-8-|'
Parsing [valid]: 'V:|-8-[view1]-12-[view3(==view1,view2)]-8-|'
Parsing [valid]: '|-(>=0)-[view]-(>=0)-|'
Parsing [valid]: '[view(==0@500)]'
Parsing [valid]: '[view1]-(==0@500)-[view2]'
Parsing [valid]: '[view1(view2 * 2.0 + 20)]'
Parsing [valid]: '|-(metric1/2-20.0)-'
Parsing [valid]: '[view1(view1.height)]'
shoes_layout_internal_finish called
16 changes: 11 additions & 5 deletions Tests/layout/vfl1.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@
Shoes.app width: 350, height: 400, resizeable: true do
stack do
para "Before layout"
@lay = layout use: :foobar, width: 300, height: 300 do
para "First Para", name: 'Label_1'
button "one", name: 'Button_1'
button "two", name: 'Button_2'
@lay = layout use: :Vfl, width: 300, height: 300 do
para "OverConstrained", name: 'Label1'
button "one", name: 'Button1'
button "two", name: 'Button2'
end
@lay.start {
@lay.rules 'foo.vfl'
metrics = {}
lines = [
"H:|-8-[Button1(==Button2)]-12-[Button2]-8-|",
"H:|-8-[Label1]-8-|",
"V:|-8-[Button1,Button2]-12-[Label1(==Button1,Button2)]-8-|"
]
@lay.rules lines: lines, metrics: metrics
@lay.finish
}
end
Expand Down
66 changes: 66 additions & 0 deletions Tests/layout/vfl2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
class Sample
attr_accessor :widgets, :canvas

def initialize()
@widgets = {}
end

def setup(canvas, attr)
@canvas = canvas
end

def add(canvas, widget, attrs)
name = attrs && attrs[:name]
@widgets[name] = widget
end

def contents
return @widgets
end

def remove(canvas, widget, pos)
return true
end

def size(canvas, pass)
end

def clear()
end

def finish()
end
end

Shoes.app width: 350, height: 400, resizeable: true do
stack do
para "Test vfl parser"
@cls = Sample.new()
@lay = layout use: @cls, width: 300, height: 300 do
para "OverConstrained", name: 'para1'
edit_line "one", name: 'el1'
button "two", name: 'but1'
button "three", name: "but2"
button "four", name: "but3"
end
@lay.start {
metrics = {
el1: 80.7, # what does this mean?
}
lines = [
"H:|-[para1(but1)]-[but1]-|",
"H:|-[el1(but2)]-[but2]-|",
"H:[but3(but2)]-|",
"V:|-[para1(el1)]-[el1]-|",
"V:|-[but1(but2,but3)]-[but2]-[but3]-|"
]
if @lay.vfl_parse lines: lines, views: @cls.contents, metrics: metrics
constraints = @lay.vfl_constraints
# display only!
constraints.each { |c| $stderr.puts c.inspect }
@lay.finish constraints
end
}
end
para "After layout"
end
32 changes: 32 additions & 0 deletions Tests/layout/vfl3.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

Shoes.app width: 350, height: 400, resizeable: true do
stack do
para "Vfl layout"
@lay = layout use: :Vfl, width: 300, height: 300 do
para "OverConstrained", name: 'para1'
edit_line "one", name: 'el1'
button "two", name: 'but1'
button "three", name: "but2"
button "four", name: "but3"
end
@lay.start {
metrics = {
'el1' => 80 # what does this mean or do or should be?
}
lines = [
"H:|-[para1(but1)]-[but1]-|",
"H:|-[el1(but2)]-[but2]-|",
"H:[but3(but2)]-|",
"V:|-[para1(el1)]-[el1]-|",
"V:|-[but1(but2,but3)]-[but2]-[but3]-|"
]
if @lay.vfl_parse lines: lines, metrics: metrics
constraints = @lay.vfl_constraints
# display purposes only?
constraints.each { |c| $stderr.puts c.inspect }
@lay.finish constraints
end
}
end
para "After layout"
end
21 changes: 19 additions & 2 deletions make/subsys.rb
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,23 @@
touch "#{tp}/plot/zzplot.done"
end

# Layout
mkdir_p "#{tp}/layout", verbose: false
lay_src = FileList['shoes/layout/*.c']
lay_hdr = FileList['shoes/layout/*.h']
lay_obj = []
lay_src.each do |c|
fnm = File.basename(c, ".*")
o = "#{tp}/layout/#{fnm}.o"
lay_obj << o
file o => [c] + lay_hdr do
sh "#{CC} -o #{o} -I. -c #{LINUX_CFLAGS} #{c}"
end
end
file "#{tp}/layout/zzlayout.done" => lay_obj do
touch "#{tp}/layout/zzlayout.done"
end

# Console
mkdir_p "#{tp}/console", verbose: false
#if RUBY_PLATFORM =~ /darwin/
Expand Down Expand Up @@ -152,7 +169,7 @@
end
end

# Too keep the main Rakefile almost legible, create some file tasks here for detecting
# To keep the main Rakefile almost legible, create some file tasks here for detecting
# updates to static/manual-en.txt and lib/shoes.rb, lib/shoes/*.rb after shoes is 'setup'
# but BEFORE new_so/new_link is called - an OSX requirement
# Also handle sample/*/*.rb changes
Expand All @@ -171,7 +188,7 @@
touch "#{tp}/copyonly/zzshoesrb.done"
end

# update lib/shoes/*.rb if changed. And ssl certs file.
# update lib/shoes/*.rb if changed. And ssl certs file.
if CROSS && TGT_DIR != 'minlin' && TGT_DIR != 'minbsd' && (! TGT_DIR[/minosx/])
shoesrblib = FileList["lib/shoes/*.rb"]
shoesrblib << "lib/shoes/cacert.pem"
Expand Down
60 changes: 60 additions & 0 deletions shoes/layout/emeus-vfl-parser-private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#pragma once

#include <glib.h>
#include "emeus-types-private.h"

G_BEGIN_DECLS

#define VFL_ERROR (vfl_error_quark ())

typedef enum {
VFL_ERROR_INVALID_SYMBOL,
VFL_ERROR_INVALID_ATTRIBUTE,
VFL_ERROR_INVALID_VIEW,
VFL_ERROR_INVALID_METRIC,
VFL_ERROR_INVALID_PRIORITY,
VFL_ERROR_INVALID_RELATION
} VflError;

typedef struct _VflParser VflParser;

typedef struct {
const char *view1;
const char *attr1;
OperatorType relation;
const char *view2;
const char *attr2;
double constant;
double multiplier;
double strength;
} VflConstraint;

GQuark vfl_error_quark (void);

VflParser *vfl_parser_new (int hspacing,
int vspacing,
GHashTable *metrics,
GHashTable *views);
void vfl_parser_free (VflParser *parser);

void vfl_parser_set_default_spacing (VflParser *parser,
int hspacing,
int vspacing);

void vfl_parser_set_metrics (VflParser *parser,
GHashTable *metrics);
void vfl_parser_set_views (VflParser *parser,
GHashTable *views);

bool vfl_parser_parse_line (VflParser *parser,
const char *line,
gssize len,
GError **error);

int vfl_parser_get_error_offset (VflParser *parser);
int vfl_parser_get_error_range (VflParser *parser);

VflConstraint *vfl_parser_get_constraints (VflParser *parser,
int *n_constraints);

G_END_DECLS
Loading

0 comments on commit 4ac78e2

Please sign in to comment.