Archive for the ‘size-viewer’ Tag
newLISP で GUI する。。。または、液晶画面で大きさを見てみる。(解説編)
“液晶画面で大きさを見てみる。”は、如何だったでしょうか?
三面図の描画は、関数draw でやっていて、ここで、テキスト・ボックスに入力された文字列の解析もやっています。
数字の切り出し部分は、
(parse text {[^0-9\.]} 0)
こんな感じです。正規表現で数字とドット以外を取り除いています。
ここままだと、先頭に数字以外があると空文字列がリストにの先頭に残るので、
(map float (remove "" (parse text {[^0-9\.]} 0)))
として、空文字列を削除して、数値に変換しています。remove は、拙作ユーティリティですが、組込replace と置き換えても動作は一緒です。
この方法では、数字が全て残ってしまうので、先頭に数字の入った製品名等をいれると、それも残ってしまいます。
そこで、先頭の [] 内の文字列は削除して、数字切り出しに渡しています。
(replace {^\[[^\]]*\]} text "" 0)
拙作 remove は、文字列にも対応しているのですが、正規表現はサポートしていないので、組込replace を使っています。
3サイズの取り出しは、
(letn (size (map (fn (x) (int (div (mul x (or unit *unit*)) *pitch*))) nums)
height (first size) width (or (second size) 1) tickness (third size))
こんな風に、first, second, third を使っています。 これで、リストに数値が一個しかなくても、エラーが起きません。
3サイズが揃えば、三面図。2つだけなら、正面図。1つだけなら、線になります。
また、前回書きませんでしたが、上のコンボ・ボックスで単位に mm と inch が選べます。
それとは別に、数字の後に、" がある場合のみ、inch として扱っています。この場合、コンボ・ボックスの指定は無視されます。
この inch 自動判定は、
(find {[0-9\.]+"} text 0)
こんな感じ。今回は正規表現のオンパレードです(笑)。
グラフィック部分の解説はいらないでしょう。マニュアル通りだし、日本語マニュアルもあるし、、、
さて、Save ボタンによる保存は、リスト・ボックスのデータをそのままテキストで書き出しているだけです。
改行は、LF だけ付加していますが、Load ボタンによる読み出しでは、CR+LF にも対応しています。
(parse (read-file *fileName*) {\r*\n} 0)
スクリプト内では、リスト変数*size-list* として扱っているので、そのまま、組込の save と load を使っても良かったのですが、括弧の無いテキスト・データの方が、編集しやすいですからね(笑)。
以上、如何でしょうか?
newLISP で GUI する。。。または、液晶画面で大きさを見てみる。
今時の パソコンのディスプレイは LCD なので、CRT の頃と違い、完全にフラット。しかも、画素ピッチは正確です。
購入を検討している電子書籍ビューアの大きさの感じを掴むのに、これは使えると思い立ち、スクリプトを書きました(remove, second, third は、newlisp-utility.lsp に、include は init.lsp に定義してあります)。
; utility
(define *newlispDir* (env "NEWLISPDIR"))
(load (append *newlispDir* "/guiserver.lsp"))
(include "macro.lsp")
(include "newlisp-utility.lsp")
; define global variables
(define *pitch* 0.248)
(define *unit* 1.0)
(define *reverse* nil)
(define *tmpStr* "")
(define *addflag* nil)
(define *fileName* (append (real-path) "/"))
(define *filemask* "lst LST")
(define *description* "list file")
(define *size-list* '({[Kinde 3] 7.5" x 4.8" x 0.335"} {約高さ169.6×幅119.1×奥行10.3mm}))
; define handler
(define (openfile-action id op file)
(when file
(setq *fileName* (base64-dec file))
(if (directory? *fileName*)
(setq *fileName* (append *fileName* "/"))
(begin
(gs:set-text 'Status *fileName*)
(map add-listbox (remove "" (parse (read-file *fileName*) {\r*\n} 0)))))))
(define (savefile-action id op file)
(when file
(setq *fileName* (base64-dec file))
(if (directory? *fileName*)
(setq *fileName* (append *fileName* "/"))
(begin (gs:set-text 'Status *fileName*)
(write-file *fileName* (join *size-list* "\n"))))))
(define (open-file-dialog)
(gs:open-file-dialog 'Frame 'openfile-action *fileName* *filemask* *description*))
(define (save-file-dialog)
(let (paths (parse *fileName* {/|\\} 0))
(gs:save-file-dialog 'Frame 'savefile-action (join (chop paths) "/") (paths -1) *filemask* *description*)))
(define (find-action id pos)
(print id " caret position : ")
(if (= -1 pos) (println "End of text") (println pos)))
(define (check-action id selected)
(setq *reverse* selected)
(gs:get-text 'InputArea 'textCallBack))
(define (combo-action id idx item)
(case (base64-dec item)
("mm" (setq *unit* 1))
("inch" (setq *unit* 25.4))
(true (setq *unit* 1))))
(define (draw text)
(replace {^\[[^\]]*\]} text "" 0)
(let (unit (if (find {[0-9\.]+"} text 0) 25.4)
nums (map float (remove "" (parse text {[^0-9\.]} 0))))
(if nums
(letn (size (map (fn (x) (int (div (mul x (or unit *unit*)) *pitch*))) nums)
height (first size) width (or (second size) 1) tickness (third size))
(if *reverse* (swap width height))
(gs:delete-tag 'OBJ)
(gs:draw-rect 'OBJ 10 10 width height gs:black)
(when tickness
(gs:draw-rect 'OBJ 10 (+ 20 height) width tickness gs:black)
(gs:draw-rect 'OBJ (+ 20 width) 10 tickness height gs:black))
(gs:update)))))
(define (list-action id idx item click-count)
(when item
(let (text (base64-dec item))
(gs:set-text 'InputArea text)
(draw text))))
(define (add-listbox text)
(unless (find text *size-list*)
(push text *size-list* -1)
(gs:add-list-item 'DataList text)))
(define (textCallBack id text)
(when text
(if *addflag*
(add-listbox (base64-dec text))
(draw (base64-dec text))))
(setq *addflag* nil))
(define (text-handler id text)
(when text
(gs:get-text id 'textCallBack)))
(define (button-handler id)
(if (ends-with id "addButton") (setq *addflag* true))
(gs:get-text 'InputArea 'textCallBack))
; initialization
(gs:init)
(define FPosX 10)
(define FPosY 10)
(define FWidth 640)
(define FHeight 480)
(gs:get-fonts)
(gs:frame 'Frame FPosX FPosY FWidth FHeight "Size Viewer")
(gs:panel 'ButtonPanel)
(gs:panel 'StatusPanel)
(gs:label 'Status (real-path))
(gs:button 'Button1 'button-handler "Draw")
(gs:button 'addButton 'button-handler "Add")
(gs:button 'fileButton 'open-file-dialog "Load")
(gs:button 'saveButton 'save-file-dialog "Save")
(gs:check-box 'Rotate 'check-action "Rotate " *reverse*)
(gs:combo-box 'spec 'combo-action '("mm" "inch"))
(gs:list-box 'DataList 'list-action *size-list*)
(gs:text-field 'InputArea 'text-handler 20)
(gs:canvas 'OutputArea)
(gs:set-color 'OutputArea gs:white)
(gs:set-stroke 2.0)
(gs:add-to 'ButtonPanel 'Button1 'InputArea 'Rotate 'spec 'addButton)
; mount all on frame
(gs:set-border-layout 'Frame)
(gs:set-border-layout 'StatusPanel)
(gs:set-flow-layout 'ButtonPanel "center")
;(gs:set-flow-layout 'StatusPanel "left")
(gs:add-to 'StatusPanel 'fileButton "west" 'Status "center" 'saveButton "east")
(gs:add-to 'Frame 'ButtonPanel "north" 'OutputArea "center" 'StatusPanel "south" 'DataList "east")
(gs:set-visible 'Frame true)
; main routine
(gs:listen)
(exit)
実行画面はこんな感じ。
使い方は、真ん中上のテキスト・ボックスに3サイズを入れ、Draw ボタンを押せば、中央のパネルに三面図が表示されます。
Rotate にチェックを入れると、縦横が逆になります。
また、Add ボタンを押せば、テキスト・ボックスの内容が、右側のリスト・ボックスに追加されます。
リスト・ボックス内のリストは、下側の Save ボタンと Load ボタンで、保存・読込ができます。
もちろん、リスト・ボックス内の項目をクリックするれば、その内容がテキスト・ボックスに入り、その三面図が表示されます。
ちなみに、画素ピッチは、
(define *pitch* 0.248)
で指定しています。単位は、mm です。必要に応じて変更して下さい。
長くなってきたので、いつものように(笑)、スクリプトの解説は、次回に。
以上、如何でしょうか?