Programming 언어/Skill

[SKILL 강좌] calculate_area : 2. callback 함수와 browser

호드맨 2017. 1. 11. 13:04

지난번 글에서 간단한 stringField 하나를 가진 (Label 은 자투리) calculator라는 창 하나를 만드는 것과 reload 함수를 통해서 코드를 하나하나 수정하면서 진행할 때 작업하기 편한 환경을 만들어 봤습니다. skill language에 생소한 경우 gui까지 따라오려면 좀 어렵겠지만 user reference manual 등을 보면서 천천히 이해하다 보면 그렇게 복잡하지만은 않다는 걸 알 수 있을 겁니다. 뭔가 output (gui 창)을 보면서 뿌듯함도 느낄 수 있을 거고요. 

이번엔 지난번 강좌를 잘 따라오셨다면 어렵지 않을 겁니다. gui 창에 몇 가지 field 들을 추가하고, 간단한 callback 함수들을 만들어 연결해 주도록 하겠습니다. callback 함수란 버튼 클릭이나 값 변경 등의 input에 대해서 바로 반응하는 함수입니다.

 

기존 cal_cellName_SF 만든 곳 뒤에 아래와 같이 추가해 봅시다.

cal_cur_button = hiCreateButton(
         ?name 'cal_cur_button
         ?buttonText "Current Cell"
         ?callback "cal_cur_button_CB()"
) ;end of cal_cur_button -- (1)

procedure(cal_cur_button_CB()
   prog(()
      calculator->cal_cellName_SF->value = deGetCellView()->cellName
   );end of prog
);end of procedure cal_cur_button_CB() -- (2)

#주석(1) : 지난 강좌에서 만든 것처럼 이번에는 Button 생성을 합니다.
#          2에서 만들 cal_cur_button_CB 함수를 callback 으로 지정합니다.
#    (2) : 1에서 만든 버튼이 눌릴 때 실행되는 함수입니다.
#          간단히 current cellName 을 StringField 에 넣어주는 역할입니다.

버튼을 만들었는데 화면상에 위치시켜야 겠죠? 지난 강의 때 calculatorID 설정부분을
아래처럼 수정해 봅시다. 물론 놓이는 좌표는 입맛에 맞게 수정하셔도 됩니다.

calculatorID = hiCreateAppForm(
         ?name 'calculator
         ?buttonLayout 'Empty
         ?formTitle "Layer Area Calculator"
         ?field list(
                   list(cal_cellName_SF     040:020 280:030 70)
                   list(cal_cur_button      315:020 100:040)
                   list(cal_Label           040:070 280:030 14)
         );end of list
         ?initialSize list(500 200)
         ?minSize list(500 200)
) ;end of calculatorID -- (3)
 
주석

#(3) : 생성한 버튼을 위치시키고 전체 창의 크기를 크게 조정했습니다.
#      initial size는 처음 떴을 때 창이고 minSize 의 경우엔 그보다 작게 만들 수
#      없도록 정하는 값입니다. 그냥 똑같이 줘버리면 창을 키울 수는 있지만 줄일
#      수는 없겠죠? 

지난번에 작성한 reload를 실행하여 봅시다. 새로운 calculator 창에 버튼이 추가된 것을 알 수 있습니다. layout (혹은 schematic이라도) view를 열었었다면 버튼을 클릭하면 가장 최근에 활성화되었던 cellName 이 stringField로 가져와집니다. 코드가 길었지만 정작 동작시킨 건 이제 이거 하나군요. 실망하지 마시고 2-2로 넘어갑시다. 나중에 Area 계산을 원하는 Net name을 가지고 있는 텍스트 파일을 통해 실행하려고 하는데 File 선택하는 Field를 하나 만들어 봅시다.

앞서 설정한 것들과 마찬가지로 Field 추가를 할 것이다. 2-1단계 에서 작성한 callback 함수 cal_cur_button_CB의 뒤쪽에 아래와 같이 추가해 보자.

 

cal_net_file_SF = hiCreateStringField(
         ?name 'cal_net_file_SF
         ?prompt "Net File "
         ?defValue ""
         ?callback ""
) ;end of cal_net_file_SF

cal_net_file_button = hiCreateButton(
         ?name 'cal_net_file_button
         ?buttonText "..."
         ?callback "ddsFileBrowseCB(calculator 'cal_net_file_SF)"
) ;end of cal_net_file_button -- (4)

# 주석
# (4) : String Field 부분은 앞 단계와 유사하지만 button 의 callback 에는 새로운 함수가 있다.
# ddsFileBrowseCB 라는 제공되는 callback 함수인데 파일 browser 를 통해 선택한 파일을
# calculator 의 'cal_net_file_SF 값에다 넣어준다.
# 마찬가지로 변경된 field 정보들을 반영하기 위해 calculatorID 부분을 수정해 주자.

calculatorID = hiCreateAppForm(
         ?name 'calculator
         ?buttonLayout 'Empty
         ?formTitle "Layer Area Calculator"
         ?field list(
                   list(cal_cellName_SF      040:020 280:030 70)
                   list(cal_cur_button       315:020 100:040)
                   list(cal_net_file_SF      040:060 380:030 70)
                   list(cal_net_file_button  415:060 040:040)
                   list(cal_Label            040:110 280:030 14)
         );end of list
         ?initialSize list(500 200)
         ?minSize list(500 200)
) ;end of calculatorID

다시 reload 하여 실행해보자. 생각한 대로 string field와 button 이 잘 추가되어 있는 걸 확인할 수 있고, '...' 버튼을 눌러보면 browser 가 떠서 파일을 선택하면 Net File의 값으로 잘 들어가는 걸 확인할 수 있다. 이번 강좌 글은 길이만 길었지 다 하고 나서 돌아보면 정말 별 거 없다. callback 함수 ddsFileBrowseCB는 유용하니 잘 알아두자. 옵션들도 꽤 있을 건데 default로 써도 쓰는데 문제는 없다.

수정한 부분을 포함하여 현재까지의 전체 코드는 아래와 같다. 위의 진행 과정에서와 띄어쓰기나 주석처리 정도만 다르니 참고하기 바란다. 아직 70 line 밖에 안된다.. (!!!)

 

# 완료까지 script
#
# calculator.il 파일 전문

cal_cellName_SF = hiCreateStringField(
        ?name 'cal_cellName_SF
        ?prompt "Cell Name"
        ?defValue ""
        ?callback ""
) ;end of cal_cellName_SF

cal_cur_button = hiCreateButton(
        ?name 'cal_cur_button
        ?buttonText "Current Cell"
        ?callback "cal_cur_button_CB()"
) ;end of cal_cur_button

procedure(cal_cur_button_CB()
   prog(()
      calculator->cal_cellName_SF->value = deGetCellView()->cellName
   );end of prog
);end of procedure cal_cur_button_CB()

cal_net_file_SF = hiCreateStringField(
        ?name 'cal_net_file_SF
        ?prompt "Net File "
        ?defValue ""
        ?callback ""
) ;end of cal_net_file_SF

cal_net_file_button = hiCreateButton(
        ?name 'cal_net_file_button
        ?buttonText "..."
        ?callback "ddsFileBrowseCB(calculator 'cal_net_file_SF)"
) ;end cal_net_file_button

cal_Label = hiCreateLabel(
        ?name 'cal_Label
        ?labelText "skill programming!\nhttp://hodman.tistory.com"
) ;end of cal_Label

calculatorID = hiCreateAppForm(
          ?name 'calculator
          ?buttonLayout 'Empty
          ?formTitle "Layer Area Calculator"
          ?fields 
             list(
                list(cal_cellName_SF        040:020 280:030 70)
                list(cal_cur_button         315:020 100:040)
                list(cal_net_file_SF        040:060 380:030 70)
                list(cal_net_file_button    415:060 040:040)
                list(cal_Label              040:110 280:030 14)
             );end of list

          ?initialSize list(500 200)
          ?minSize list(500 200)
);end of calculatorID

procedure(calculator()
   prog(()
      hiDisplayForm(calculator '(100 100))
   );end of prog
);end of procedure calculator()

procedure(reload()
   prog(()
      if(hiIsFormDisplayed(calculatorID) then
         hiFormCancel(calculator)
      ); end of if
      hiRegTimer("load(\"/user/hodman/private/skill/calculator.il\")" 1)
      hiRegTimer("calculator()" 10)
   );end of prog
);end of procedure reload()