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* として扱っているので、そのまま、組込の saveload を使っても良かったのですが、括弧の無いテキスト・データの方が、編集しやすいですからね(笑)。

 以上、如何でしょうか?

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 です。必要に応じて変更して下さい。

 長くなってきたので、いつものように(笑)、スクリプトの解説は、次回に。

 以上、如何でしょうか?