티스토리 툴바

BLOG main image
분류 전체보기 (463)
Random (335)
컴퓨터 (37)
Favorites (20)
사진 (9)
아포리즘 (8)
자전거 (33)
여행 (21)

Twitter Updates

    follow me on Twitter
    «   2012/02   »
          1 2 3 4
    5 6 7 8 9 10 11
    12 13 14 15 16 17 18
    19 20 21 22 23 24 25
    26 27 28 29      
    162,105 Visitors up to today!
    Today 10 hit, Yesterday 22 hit
    rss
    2008/03/25 16:36

    Cocoa의 기본 컨트롤에 TextView가 있습니다. API 목록의 함수 이름들을 둘러봤는데 매우 많은 기능을 가지고 있어 웬만한 워드프로세서도 만들수 있을 것 같습니다. TextView에서 다른 파일의 drop을 구현해 보고자 했는데 원래 커스텀 컨트롤에서 drag & drop을 구현하려면 여러가지 함수를 구현해야 합니다만, Interface Builder에서 붙여놓기만 해도 기본적인 drop을 받습니다.

    파일을 받았는지의 여부와 어떤 파일을 받았는지를 알아내는 것이 문제가 되겠는데요… XCode의 문서에는 특별한 언급이 없는 것 같습니다. RubyCocoa에서 다음과 같이 서브클래싱으로 알아낼수 있었습니다.

    
    class SubContent < OSX::NSTextView  
      # ns_overrides :performDragOperation_, :concludeDragOperation_
      # def performDragOperation(sender)
      #    p 'PerformDragOperation', sender
      #    super_performDragOperation(sender)
      # end
      # 
      def concludeDragOperation(sender)
         # p 'ConcludeDragOperation', sender
         super_concludeDragOperation(sender)
         range = selectedRanges[0].rangeValue
         source = string[range.location...(range.location+range.length)].to_s
         if Media.is_picture?(source) then
           insertText('!file://'+source+'!')
         elsif File.exist?(source) and File.ftype(source) == 'file' then
           insertText('file://'+source)
         end
         Media.find_or_create(source)
         setSelectedRange([0,0])
       end
    end
    
    • 1행에서 SubContent란 클래스를 NSTextView에서 서브클래싱하고 있습니다.
    • 2행은 원래 서브클래싱을 하려면 원래 클래스를 오버라이드하는 함수를 ns_overrides로 지정해 주어야 합니다만, 요즘 버전의 rubycocoa에서는 필요없게 되었습니다.
    • drag은 draggingEntered:, draggingUpdated:, prepareForDragOperation:, performDragOperation:, concludeDragOperation: 등의 함수로 구현하게 됩니다. 원래는 pasteBoard에서 파일정보를 얻어내야 하지만 TextView에서는 기본적으로 drag 받은 파일의 이름을 삽입하고 선택하게 되므로 concludeDragOperation만 오버라이드하였습니다.
    • super_concludeDragOperation: 을 먼저 호출했습니다. 단순히 super 함수를 호출하면 안 되고 super와 함수이름을 _ 로 결합한 것으로 super 함수를 호출합니다. Ruby 클래스의 super와 구분하기 위해서 인것으로 생각됩니다.
    • 코드내에 위와 같은 클래스를 정의해 놓으면 Interface Builder에서 Custom View를 만들고 이것의 클래스를 앞서 정의한 SubContent와 같은 것으로 지정할 수 있습니다. (똑똑한 놈…)
    • 단순히 Custom View만 만들면 윈도우의 크기가 변하거나 여러 행이 입력될때 view의 크기나 위치가 이상하게 이동하게 됩니다. ScrollView를 만들면 내부에 CustomView가 자동적으로 들어가 있어서 이것의 클래스를 지정할 수 있도록 되어 있습니다. (다시 똑똑한 놈…)