From f3635dc57912dc9426350cc75c95f6a1edbd07b0 Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Sat, 31 May 2014 22:49:28 -0700 Subject: [PATCH] got it to draw the keyboard :) really slow --- {doc => firmware}/references.md | 0 layout-gen/Boards.elm | 214 ++++++++++++++++++++++++++++++++ layout-gen/main.elm | 157 +++++++++++++++++------ layout-gen/references.md | 27 ++++ 4 files changed, 363 insertions(+), 35 deletions(-) rename {doc => firmware}/references.md (100%) create mode 100644 layout-gen/Boards.elm create mode 100644 layout-gen/references.md diff --git a/doc/references.md b/firmware/references.md similarity index 100% rename from doc/references.md rename to firmware/references.md diff --git a/layout-gen/Boards.elm b/layout-gen/Boards.elm new file mode 100644 index 0000000..092fc94 --- /dev/null +++ b/layout-gen/Boards.elm @@ -0,0 +1,214 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2014 Ben Blazak +-- Released under The MIT License (see "doc/licenses/MIT.md") +-- Project located at +------------------------------------------------------------------------------- + +{-| Keyboard definitions +-} + + +module Boards where + + +------------------------------------------------------------------------------- +-- values +------------------------------------------------------------------------------- + + +{-| A list of the keyboards defined +-} +all : [Board] +all = [ ergodox ] + + +------------------------------------------------------------------------------- +-- types and default values +------------------------------------------------------------------------------- + + +{-| A type for keys in our keyboard + +Fields: +- `name`: The name of the key (so we can reference it) +- `size`: The width of the key (in multiples of the standard 1x1 key, which + takes up 1 grid block) +- `position`: The position of the center of the key on the grid, with `(0,0)` + being the top left of the board, positive x extending right, and positive y + extending down +- `rotation`: The rotation of the key (in degrees) +- `value`: A name corresponding to the assigned keycode for this key +- `configuration`: The configuration of the board to which this key belongs + - 0: This key belongs to all configurations +-} +type Key = { name: String + , size: Float + , position: (Float,Float) + , rotation: Float + , value: String + , configuration: Int + } + +defaultKey : Key +defaultKey = { name = "" + , size = 1 + , position = (0,0) + , rotation = 0 + , value = "" + , configuration = 0 + } + + +{-| A type for keyboards (`Keyboard` is already used, in Elm) + +Fields: +- `name`: The display name +- `size`: The horizontal and vertical size of the board, in grid squares +- `keys`: A list of keys, making up the keyboard +-} +type Board = { name: String + , size: (Float,Float) + , keys: [Key] + } + + +------------------------------------------------------------------------------- +-- board definitions +------------------------------------------------------------------------------- + + +{-| Definition for the ErgoDox Keyboard + +From the firmware source: + + /* left hand, spatial positions */ + k50,k51,k52,k53,k54,k55,k56, + k40,k41,k42,k43,k44,k45,k46, + k30,k31,k32,k33,k34,k35, + k20,k21,k22,k23,k24,k25,k26, + k10,k11,k12,k13,k14, + k05,k06, + k15,k16,k04, + k03,k02,k01, + + /* right hand, spatial positions * + k57,k58,k59,k5A,k5B,k5C,k5D, + k47,k48,k49,k4A,k4B,k4C,k4D, + k38,k39,k3A,k3B,k3C,k3D, + k27,k28,k29,k2A,k2B,k2C,k2D, + k19,k1A,k1B,k1C,k1D, + k07,k08, + k09,k17,k18, + k0C,k0B,k0A ) +-} + + +ergodox : Board +ergodox = { name = "ErgoDox", size = (18,8), keys = [ + + -- left hand, roughly from upper left to bottom right + + { defaultKey | name <- "k50", position <- (0.25,0), size <- 1.5 } + , { defaultKey | name <- "k51", position <- (1.5,0) } + , { defaultKey | name <- "k52", position <- (2.5,0) } + , { defaultKey | name <- "k53", position <- (3.5,0) } + , { defaultKey | name <- "k54", position <- (4.5,0) } + , { defaultKey | name <- "k55", position <- (5.5,0) } + , { defaultKey | name <- "k56", position <- (6.5,0) } + + , { defaultKey | name <- "k40", position <- (0.25,1), size <- 1.5 } + , { defaultKey | name <- "k41", position <- (1.5,1) } + , { defaultKey | name <- "k42", position <- (2.5,1) } + , { defaultKey | name <- "k43", position <- (3.5,1) } + , { defaultKey | name <- "k44", position <- (4.5,1) } + , { defaultKey | name <- "k45", position <- (5.5,1) } + , { defaultKey | name <- "k46", position <- (6.5,1.25), size <- 1.5, rotation <- 90 } + + , { defaultKey | name <- "k30", position <- (0.25,2), size <- 1.5 } + , { defaultKey | name <- "k31", position <- (1.5,2) } + , { defaultKey | name <- "k32", position <- (2.5,2) } + , { defaultKey | name <- "k33", position <- (3.5,2) } + , { defaultKey | name <- "k34", position <- (4.5,2) } + , { defaultKey | name <- "k35", position <- (5.5,2) } + + , { defaultKey | name <- "k20", position <- (0.25,3), size <- 1.5 } + , { defaultKey | name <- "k21", position <- (1.5,3) } + , { defaultKey | name <- "k22", position <- (2.5,3) } + , { defaultKey | name <- "k23", position <- (3.5,3) } + , { defaultKey | name <- "k24", position <- (4.5,3) } + , { defaultKey | name <- "k25", position <- (5.5,3) } + , { defaultKey | name <- "k26", position <- (6.5,2.75), size <- 1.5, rotation <- 90 } + + , { defaultKey | name <- "k10", position <- (0.5,4) } + , { defaultKey | name <- "k11", position <- (1.5,4) } + , { defaultKey | name <- "k12", position <- (2.5,4) } + , { defaultKey | name <- "k13", position <- (3.5,4) } + , { defaultKey | name <- "k14", position <- (4.5,4) } + + , { defaultKey | name <- "k05", position <- (6.5,5) } + , { defaultKey | name <- "k06", position <- (7.5,5) } + + , { defaultKey | name <- "k15", position <- (5.5,6), configuration <- 2 } + , { defaultKey | name <- "k16", position <- (6.5,6), configuration <- 2 } + , { defaultKey | name <- "k04", position <- (7.5,6) } + + , { defaultKey | name <- "k03", position <- (5.5,6.5), size <- 2, rotation <- 90, configuration <- 1 } + , { defaultKey | name <- "k02", position <- (6.5,6.5), size <- 2, rotation <- 90, configuration <- 1 } + , { defaultKey | name <- "k03", position <- (5.5,7), configuration <- 2 } + , { defaultKey | name <- "k02", position <- (6.5,7), configuration <- 2 } + , { defaultKey | name <- "k01", position <- (7.5,7) } + + -- right hand, roughly from upper left to bottom right + + , { defaultKey | name <- "k57", position <- (10.5,0) } + , { defaultKey | name <- "k58", position <- (11.5,0) } + , { defaultKey | name <- "k59", position <- (12.5,0) } + , { defaultKey | name <- "k5A", position <- (13.5,0) } + , { defaultKey | name <- "k5B", position <- (14.5,0) } + , { defaultKey | name <- "k5C", position <- (15.5,0) } + , { defaultKey | name <- "k5D", position <- (16.75,0), size <- 1.5 } + + , { defaultKey | name <- "k47", position <- (10.5,1.25), size <- 1.5, rotation <- -90 } + , { defaultKey | name <- "k48", position <- (11.5,1) } + , { defaultKey | name <- "k49", position <- (12.5,1) } + , { defaultKey | name <- "k4A", position <- (13.5,1) } + , { defaultKey | name <- "k4B", position <- (14.5,1) } + , { defaultKey | name <- "k4C", position <- (15.5,1) } + , { defaultKey | name <- "k4D", position <- (16.75,1), size <- 1.5 } + + , { defaultKey | name <- "k38", position <- (11.5,2) } + , { defaultKey | name <- "k39", position <- (12.5,2) } + , { defaultKey | name <- "k3A", position <- (13.5,2) } + , { defaultKey | name <- "k3B", position <- (14.5,2) } + , { defaultKey | name <- "k3C", position <- (15.5,2) } + , { defaultKey | name <- "k3D", position <- (16.75,2), size <- 1.5 } + + , { defaultKey | name <- "k27", position <- (10.5,2.75), size <- 1.5, rotation <- -90 } + , { defaultKey | name <- "k28", position <- (11.5,3) } + , { defaultKey | name <- "k29", position <- (12.5,3) } + , { defaultKey | name <- "k2A", position <- (13.5,3) } + , { defaultKey | name <- "k2B", position <- (14.5,3) } + , { defaultKey | name <- "k2C", position <- (15.5,3) } + , { defaultKey | name <- "k2D", position <- (16.75,3), size <- 1.5 } + + , { defaultKey | name <- "k19", position <- (12.5,4) } + , { defaultKey | name <- "k1A", position <- (13.5,4) } + , { defaultKey | name <- "k1B", position <- (14.5,4) } + , { defaultKey | name <- "k1C", position <- (15.5,4) } + , { defaultKey | name <- "k1D", position <- (16.5,4) } + + , { defaultKey | name <- "k07", position <- (9.5,5) } + , { defaultKey | name <- "k08", position <- (10.5,5) } + + , { defaultKey | name <- "k09", position <- (9.5,6) } + , { defaultKey | name <- "k17", position <- (10.5,6), configuration <- 2 } + , { defaultKey | name <- "k18", position <- (11.5,6), configuration <- 2 } + + , { defaultKey | name <- "k0C", position <- (9.5,7) } + , { defaultKey | name <- "k0B", position <- (10.5,6.5), size <- 2, rotation <- -90, configuration <- 1 } + , { defaultKey | name <- "k0A", position <- (11.5,6.5), size <- 2, rotation <- -90, configuration <- 1 } + , { defaultKey | name <- "k0B", position <- (10.5,7), configuration <- 2 } + , { defaultKey | name <- "k0A", position <- (11.5,7), configuration <- 2 } + + ]} + diff --git a/layout-gen/main.elm b/layout-gen/main.elm index 513ad9d..2a93124 100644 --- a/layout-gen/main.elm +++ b/layout-gen/main.elm @@ -1,52 +1,139 @@ +------------------------------------------------------------------------------- +-- Copyright (c) 2014 Ben Blazak +-- Released under The MIT License (see "doc/licenses/MIT.md") +-- Project located at +------------------------------------------------------------------------------- + +{-| A web-based UI for generating keyboard layouts for the firmware +-} + + import Window +import Dict + +import Boards --- our grid's aspect ratio -aspectRatio : (Int, Int) -aspectRatio = (3,2) --- to scale our aspect ratio -aspectScale : Int -aspectScale = 7 +------------------------------------------------------------------------------- +-- values and signals +------------------------------------------------------------------------------- --- the number of columns in our grid -columns : Int -columns = aspectScale * (fst aspectRatio) --- the number of rows in our grid -rows : Int -rows = aspectScale * (snd aspectRatio) +{-| The number of columns and rows in our grid --- to generate various transparencies of lightBlue -lightBlueN : Float -> Color -lightBlueN n = rgba 114 159 207 (1/n) +Notes: +- The list gives the aspect ratio (of width to height) +- The number gives the scale of the aspect ratio, relative to the window size +-} +[columns, rows] = map ((*) 5) [4,3] --- TODO: document what i mean by (x,y) (after i figure it out) -background : (Int, Int) -> Element -background (width,height) = +{-| The edge length of a square in our grid +-} +edgeSignal : Signal Float +edgeSignal = + let function = \(width,height) -> min (toFloat width / columns) + (toFloat height / rows) + in lift function Window.dimensions + + +------------------------------------------------------------------------------- +-- groups of forms +------------------------------------------------------------------------------- + +background : (Int, Int) -> Float -> [Form] +background (width,height) edge = let (w,h) = (toFloat width, toFloat height) - (r,c) = (toFloat rows, toFloat columns) - step = min (w/c) (h/r) + ruleLines = True + lineStyle = dashed lightBlue + ruleLineStyle = dotted charcoal + + -- x and y represent the horizontal and vertical scaling factors + line (x,y) style offset = + segment (-x*w/2,-y*h/2) (x*w/2,y*h/2) + |> traced style + |> move (y*offset*edge, x*offset*edge) - line (x,y) color offset = - segment (-x*w,-y*h) (x*w,y*h) |> traced (dashed color) - |> move (y*offset*step, x*offset*step) lines (x,y) = let dimension = if x == 0 then w else h - in map (\n -> line (x/2,y/2) - (lightBlueN <| toFloat (mod (n+1) 2 + 1) * 3) - (toFloat n)) - [floor (-dimension/step) .. floor (dimension/step)] - crossBox = [ line (0,1) charcoal 0, line (1,0) charcoal 0, - line (0,1) charcoal ( c/2), line (0,1) charcoal (-c/2), - line (1,0) charcoal ( r/2), line (1,0) charcoal (-r/2) ] + in map (\n -> line (x,y) lineStyle (toFloat n/2) + |> alpha (1 / (toFloat (mod (n+1) 2 + 1) * 3))) + [floor (-dimension/edge)*2 .. floor (dimension/edge)*2] - in color lightGray <| collage width height ( - crossBox ++ - lines (0,1) ++ lines (1,0) - ) + vLines = lines (0,1) + hLines = lines (1,0) + + rLines = + let boxLine (x,y) offset = line (x,y) ruleLineStyle offset + in [ boxLine (0,1) (-columns/2), boxLine (1,0) (-rows/2) +-- , boxLine (0,1) 0, boxLine (1,0) 0 + , boxLine (0,1) (columns/2), boxLine (1,0) (rows/2) + ] + + in hLines ++ vLines ++ if ruleLines then rLines else [] + + +keyboardTestDraw : Float -> [Form] +keyboardTestDraw edge = + let lineStyle = + let temp = solid lightBlue + in { temp | width <- 5, cap <- Round, join <- Smooth } + + -- grab just 1 Board, and use only 1 configuration + keyboard = head <| filter (\n -> n.name == "ErgoDox") Boards.all + configuration = 1 + + -- s = scaling factor (from 1 square of the grid) + -- p = position of the center of the rectangle on the grid + formKey k = + let (sizeX, sizeY) = (k.size*edge, edge) + (posX, posY) = ((fst k.position)*edge, (snd k.position)*edge) + in map (move (posX, posY) . rotate (degrees k.rotation)) + [ rect sizeX sizeY |> outlined lineStyle + , toForm <| plainText k.name + ] + + -- convert positions to be relative to center of the page + keys = + let convertPosition (x,y) = ( x - (fst keyboard.size) / 2, + -y + (snd keyboard.size) / 2 ) + in map (\n -> { n | position <- convertPosition n.position }) + keyboard.keys + |> filter ( \n -> n.configuration == 0 + || n.configuration == configuration ) + + in foldl1 (++) (map formKey keys) + +-- leftHand = (map (\n -> ((1.5,1),(-8.25,8-n)))[0..3]) -- left 1.5x +-- ++ (map (\n -> ((1,1),(-7+n,8)))[0..5]) -- top 1x +-- ++ (map (\n -> ((1,1),(-7+n,7)))[0..4]) -- next 1x +-- ++ (map (\n -> ((1,1),(-7+n,6)))[0..4]) -- next 1x +-- ++ (map (\n -> ((1,1),(-7+n,5)))[0..4]) -- next 1x +-- ++ (map (\n -> ((1,1),(-8+n,4)))[0..4]) -- bottom 1x +-- ++ (map (\n -> ((1,1.5),(-2,6.75-n*1.5)))[0..1]) -- right 1.5x +-- ++ (map (\n -> ((1,2),(-3+n,1.5)))[0..1]) -- thumb 2x +-- ++ (map (\n -> ((1,1),(-2+n,3)))[0..1]) -- t thumb 1x +-- ++ (map (\n -> ((1,1),(-1-n,2)))[0..0]) -- m thumb 1x +-- ++ (map (\n -> ((1,1),(-1-n,1)))[0..0]) -- b thumb 1x +-- +-- rightHand = map (\((a,b),(c,d)) -> ((a,b),(-c,d))) leftHand +-- +-- in map (\((a,b),(c,d)) -> key (a,b) (c-0.5,d-3)) (leftHand ++ rightHand) + + +------------------------------------------------------------------------------- +-- putting it all together +------------------------------------------------------------------------------- + +scene : (Int, Int) -> Float -> Element +scene (width,height) edge = + let backgroundColor = lightGray + in layers [ collage width height [] |> color backgroundColor + , collage width height (background (width,height) edge) + , collage width height (keyboardTestDraw edge) + ] main : Signal Element -main = background <~ Window.dimensions +main = scene <~ Window.dimensions ~ edgeSignal diff --git a/layout-gen/references.md b/layout-gen/references.md new file mode 100644 index 0000000..f8287a0 --- /dev/null +++ b/layout-gen/references.md @@ -0,0 +1,27 @@ +## Elm Stuff + +* [Official Documentation] + (http://elm-lang.org) + + * [Standard Libaries] + (http://library.elm-lang.org/catalog/elm-lang-Elm/0.12.3/) + * [Examples] + (http://elm-lang.org/Examples.elm) + * [Syntax: a Quick Tour] + (http://elm-lang.org/learn/Syntax.elm) + * [Types] + (http://elm-lang.org/learn/Getting-started-with-Types.elm) + * [Changes in Elm 0.10] + (http://elm-lang.org/blog/announce/0.10.elm) + +* [What does the “Just” syntax mean in Haskell?] + (http://stackoverflow.com/questions/18808258/what-does-the-just-syntax-mean-in-haskell/18809252#18809252) + Haskell is very similar to Elm in some ways, so I think this applies. + + +------------------------------------------------------------------------------- + +Copyright © 2014 Ben Blazak +Released under The MIT License (see "doc/licenses/MIT.md") +Project located at +