간단한 프로토콜 테스터를 짜는중인데 생긴건 챗 클라이언트 혹은 메신저 같이 생긴놈이다.위쪽 넓은 텍스트컨트롤에서는 서버가 보내오는 입력을 눈에 편한 형태로 보여주고 아래쪽 작은 텍스트에딧에 내가 적절히 보낼 패킷을 입력할수있다.
저 패킷 모양을 눈에 익숙하게 보여주기/입력하기 위해서
language-python 패키지 까지 가져다 썼지만 뭐 이건 중요한게 아니고..( 파서를 직접 짜는것 보다 Python 파서를 재활용하는게 더 편했다. )
어쨌건 위처럼 만들고 나니 반복되는 패킷입력을 매번 키보드로 하고 있는게 좀 한심해서 아래쪽에 버튼을 붙여야할 필요성도 생겼다. 그러니까 패킷1, 패킷2 ... 란 버튼들이 줄줄이 붙어있고 그걸 누르면 패킷이 바로 전송 되던가 아니면 입력창에 채워졌으면 편할거란 생각이 들었다.
게다가 이 버튼들은 상황따라 바뀌기 때문에(테스트할 대상에 따라 자주쓰는 패킷이 달라질테니) 코드안에 박기는 뭐하고 바이너리밖에 설정파일로 뽑아야만 했다.(동적으로 바뀐다는건 아니고 그냥 실행시 결정된다는 의미로 적었다. 나중에 동적으로 버튼을 제어할 일도 생기겠지. 그땐 흠
hslua 를 써볼까?)
뭐 필요한 사항은 대강 정리가 됐고..
이제 어떻게 했는지를 적자면
먼저 설정파일은.. 흠 맘에 드는 라이브러리를 못찾아서 (기존 라이브러리는 너무 덩치크거나, 쓰기가 좀 어색하거나..) 그냥 내가 단순히 짜버렸다. haskell 입문서 보면 나오는 간단한 수준으로 짠거라 아주 일부만 여기 적어둔다
펼쳐두기..
type Config = [(String, String)]
readConfig :: String -> Config
readConfig = map (split '=') . filter ('='`elem`) . lines'
readConfigFile :: FilePath -> IO Config
readConfigFile path = liftM readConfig $ readFile path
이제 wx 쪽 코드를 만져야 하는데.. 흠.. 다소 삽질한 끝에 아래같은 모양의 함수를 만들었다.
펼쳐두기..
makeButtonPanelFromConfigFile path parent input = do
config <- readConfigFile path
bp <- panel parent []
buttons <- forM config (\(k,v) -> button bp [text := k,
on command := set input [text := v]])
set bp [layout := row 3 (map widget buttons)]
return bp
패널을 만들어서 패널에 버튼을 적절히 박아주고 패널을 리턴하는 함수. 흠. 저 프라퍼티가 어떻게 구현된건지 함 찾아봐야 겠네. 정말 묘하구먼.
음 이건 지금 코드를 정리해서 위의 내용을 담은 최소 실행 코드. 나중에 이걸 볼때 실행되는 코드가 없으면 난감하겠지.. 소켓쪽이나 등등 많이 덜어냈기 때문에 딱히 어디 쓸수있는 코드는 아니다.
펼쳐두기..
import Graphics.UI.WX
import Network.Socket
import Control.Monad
import System.IO
main = start gui
makeButtonPanelFromConfig config parent input = do
bp <- panel parent []
buttons <- forM config (\(k,v) -> button bp [text := k,
on command := set input [text := v]])
set bp [layout := row 3 (map widget buttons)]
return bp
config = [("헤헤", "헤헤가 눌렸어"),
("히히", "히히가 눌렸어"),
("멍멍", "멍멍멍멍")]
gui = do
f <- frame [text := "저수준 프로토콜 테스터를 짜기위한 첫걸음"]
output <- textCtrl f []
input <- entry f []
bp <- makeButtonPanelFromConfig config f input
set input [on command := appendText output =<< get input text]
set f [layout := fill $ column 5 [fill $ minsize (sz 400 300) $ widget output,
hfill $ widget input,
hfill $ widget bp]]
focusOn input
댓글 없음:
댓글 쓰기