<?xml version="1.0" encoding="utf-8"?>
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" type="topic" id="image-viewer.vala" xml:lang="ko">

  <info>
  <title type="text">그림 보기(Vala)</title>
    <link type="guide" xref="vala#examples"/>

    <desc>간단한 "Hello world" GTK+ 프로그램에 약간의 무언가가 더 들어갑니다.</desc>

    <revision pkgversion="0.1" version="0.1" date="2011-03-18" status="review"/>
    <credit type="author">
      <name>그놈 문서 프로젝트</name>
      <email its:translate="no">gnome-doc-list@gnome.org</email>
    </credit>
    <credit type="author">
      <name>Johannes Schmid</name>
      <email its:translate="no">jhs@gnome.org</email>
    </credit>
    <credit type="author">
      <name>Philip Chimento</name>
      <email its:translate="no">philip.chimento@gmail.com</email>
    </credit>
    <credit type="editor">
     <name>Tiffany Antopolski</name>
     <email its:translate="no">tiffany.antopolski@gmail.com</email>
    </credit>
  <credit type="editor">
    <name>Marta Maria Casetti</name>
    <email its:translate="no">mmcasetti@gmail.com</email>
    <years>2013</years>
  </credit>
  
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
      <mal:name>조성호</mal:name>
      <mal:email>shcho@gnome.org</mal:email>
      <mal:years>2017, 2018</mal:years>
    </mal:credit>
  </info>

<title>그림 보기</title>
<synopsis>
  <p>이 따라하기 지침서에서는 그림 파일을 열고 보여주는 프로그램을 만듭니다. 다음을 배워나갑니다:</p>
  <list type="numbered">
    <item><p><link xref="getting-ready">안주타 IDE</link>로 기본 프로젝트를 설정하는 방법.</p></item>
    <item><p>Vala 프로그래밍 언어로 <link href="http://developer.gnome.org/platform-overview/stable/gtk">Gtk 프로그램</link>을 작성하는 방법</p></item>
    <item><p><link href="http://developer.gnome.org/gobject/stable/">GObject</link> 프로그래밍 일부 기본 개념</p></item>

  </list>
  <p>이 지침을 따라갈 수 있으려면 다음이 필요합니다:</p>
  <list>
    <item><p><link href="https://live.gnome.org/Vala/Tutorial">Vala</link> 프로그래밍 언어 기본 지식.</p></item>
    <item><p><app>안주타</app> 설치 사본.</p></item>
    <item><p>이 따라하기 지침서에선 별로 필요하지 않지만 쓸만한 <link href="http://valadoc.org/gtk+-3.0/">gtk+-3.0</link> API 참고서를 찾아보시는 것도 좋습니다.</p></item>
  </list>
</synopsis>

<media type="image" mime="image/png" src="media/image-viewer.png"/>

<section id="anjuta">
  <title>안주타에서 프로젝트 만들기</title>
  <p>코딩을 시작하기 전에 안주타에서 새 프로젝트를 설정해야합니다. 이 프로그램은 빌드에 필요한 모든 파일을 만들고 그 다음 코드를 실행합니다. 또한 이 모든 상태를 유지 관리하는데 쓸만합니다.</p>
  <steps>
    <item>
      <p><app>안주타</app> 를 시작하고 <gui>새 프로젝트 만들기</gui> 또는 <guiseq><gui>파일</gui><gui>새로 만들기</gui><gui>프로젝트</gui></guiseq> 를 눌러 프로젝트 마법사를 여십시오.</p>
    </item>
    <item>
      <p><gui>Vala</gui> 탭에서 <gui>GTK+ (단순)</gui>을 선택하고 <gui>계속</gui>을 누른 다음, 나타난 페이지에서 몇가지 자세한 내용을 입력하십시오. 프로젝트 이름과 디렉터리에 <file>image-viewer</file>를 입력하십시오.</p>
   	</item>
    <item>
      <p>따라하기 지침을 통해 사용자 인터페이스를 직접 만들 예정이므로 <gui>사용자 인터페이스에 GtkBuilder 사용</gui> 설정을 껐는지 확인하십시오.</p>
     <note><p><link xref="guitar-tuner.vala">기타 조율 프로그램</link> 따라하기 지침서에서 인터페이스 빌더 사용법을 배웁니다.</p></note>
    </item>
    <item>
      <p><gui>계속</gui>을 누르고 <gui>적용</gui>을 누르면 프로젝트를 만들어줍니다. <gui>프로젝트</gui>나 <gui>파일</gui>탭에서 <file>src/image_viewer.vala</file> 파일을 여십시오. 다음 코드가 나타납니다:</p>
      <code mime="text/x-csharp">
using GLib;
using Gtk;

public class Main : Object
{

	public Main ()
	{
		Window window = new Window();
		window.set_title ("Hello World");
		window.show_all();
		window.destroy.connect(on_destroy);
	}

	public void on_destroy (Widget window)
	{
		Gtk.main_quit();
	}

	static int main (string[] args)
	{
		Gtk.init (ref args);
		var app = new Main ();

		Gtk.main ();

		return 0;
	}
}</code>
    </item>
  </steps>
</section>

<section id="build">
  <title>첫 코드 작성</title>
  <p>이 코드는 (빈) 창을 사용자 인터페이스 설명 파일에서 불러오고 화면에 나타냅니다. 자세한 내용은 아래에 있습니다. 기본을 이해하셨다면 이 부분은 넘어가셔도 됩니다:</p>

  <list>
    <item>
      <p>상단의 <code>using</code> 줄 두 줄에서는 이름 영역을 임포팅하여 해당 이름을 코드상에서 굳이 언급할 필요가 없게 해줍니다.</p>
    </item>
    <item>
      <p><code>Main</code> 클래스의 생성자는 (비어 있는) 새 창을 만들고 창을 닫을 때 프로그램을 빠져나갈 <link href="https://live.gnome.org/Vala/SignalsAndCallbacks">시그널</link>을 연결합니다.</p>
      <p>시그널 연결은 단추를 누르거나 어떤 동작을 취할 때 처리할 일을 정의하는 방식입니다. 여기서 창을 닫을 때 <code>destroy</code> 함수를 호출(하고 앱을 끝내기)합니다.</p>
    </item>
    <item>
      <p><code>static main</code> 함수는 Vala 프로그램을 시작할 때 기본으로 실행하는 함수입니다. <code>Main</code> 클래스를 만들고 설정한 다음 프로그램을 실행하는 몇가지 함수를 호출합니다. <link href="http://valadoc.org/gtk+-3.0/Gtk.main.html"><code>Gtk.main</code></link> 함수는 사용자 인터페이스를 실행하고 이벤트(마우스 단추 누름과 키 누름) 대기를 시작하는 GTK <link href="http://en.wikipedia.org/wiki/Event_loop">메인 루프</link>를 시작합니다.</p>
    </item>
  </list>

  <p>이 코드를 사용할 준비가 됐으니 <guiseq><gui>빌드</gui><gui>프로젝트 빌드</gui></guiseq>(또는 <keyseq><key>Shift</key><key>F7</key></keyseq> 키 누름)를 눌러 코드를 컴파일할 수 있습니다.</p>
  <p><gui>설정</gui>을 <gui>기본</gui>으로 바꾸고 <gui>실행</gui>을 눌러 빌드 디렉터리를 설정하십시오. 처음 빌드 때 한 번만 실행하면 됩니다.</p>
</section>

<section id="ui">
  <title>사용자 인터페이스 만들기</title>
  <p>이제 비어있는 창에 숨결을 불어넣겠습니다. GTK는 다른 위젯을 넣을 수 있고 다른 컨테이너도 넣을 수 있는 <link href="http://www.valadoc.org/gtk+-2.0/Gtk.Container.html"><code>Gtk.Container</code></link>로  사용자 인터페이스를 모아둡니다. 여기서는 여러가지 컨테이너 중 가장 간단한 <link href="http://unstable.valadoc.org/gtk+-2.0/Gtk.Box.html"><code>Gtk.Box</code></link>를 사용하겠습니다.</p>

<p><code>Main</code> 클래스 상단에 다음 줄을 추가하십시오:</p>
  <code mime="text/x-csharp">
private Window window;
private Image image;
</code>

<p>이제 현재 생성자를 아래 내용으로 바꾸겠습니다:</p>
<code mime="text/x-csharp">

public Main () {

	window = new Window ();
	window.set_title ("Image Viewer in Vala");

	// Set up the UI
	var box = new Box (Orientation.VERTICAL, 5);
	var button = new Button.with_label ("Open image");
	image = new Image ();

	box.pack_start (image, true, true, 0);
	box.pack_start (button, false, false, 0);
	window.add (box);

	// Show open dialog when opening a file
	button.clicked.connect (on_open_image);

	window.show_all ();
	window.destroy.connect (main_quit);
}
</code>
  <steps>
    <item>
      <p>처음 두 줄은 하나 이상의 메서드에서 접근할 GUI 부분입니다. 이 부분을 여기에 선언하여 메서드를 만든 부분에서만 쓰는게 아니라 전 클래스에 걸쳐 쓸 수 있게 합니다.</p>
    </item>
    <item>
      <p>생성자 처음 줄에서는 빈 창을 만듭니다. 다음 줄에서는 우리가 쓰려는 위젯을 만듭니다. 그림을 여는 단추, 그림 보기 위젯 자체, 컨테이너로 쓸 상자 위젯이 있습니다.</p>
    </item>
    <item>
      <p><link href="http://unstable.valadoc.org/gtk+-2.0/Gtk.Box.pack_start.html"><code>pack_start</code></link> 호출로 박스에 두 위젯을 추가하고 동작을 정의합니다. 그림은 활용 가능한 공간만큼 충분히 확장하고, 단추는 필요한 만큼만 커집니다. 위젯의 크기를 분명하게 설정하지 않음을 알아채셨을 겁니다. GTK에서는 창 크기가 달라져도 보기 좋은 배치를 쉽게하기에 직접 설정할 필요가 없습니다. 이 과정이 끝나면 박스를 창에 추가합니다.</p>
    </item>
    <item>
      <p>단추를 사용자가 눌렀을 때 어떤 일이 일어날 지 정해야합니다. GTK는 <em>시그널</em> 개념을 활용합니다.</p>
      <p><link href="http://valadoc.org/gtk+-3.0/Gtk.Button.html">Button</link>을 누르면, 어떤 동작(<link href="https://live.gnome.org/Vala/SignalsAndCallbacks">콜백</link> 메서드에 정의)을 연결할 수 있는 <link href="http://valadoc.org/gtk+-3.0/Gtk.Button.clicked.html"><code>clicked</code></link> 시그널을 내보냅니다.</p>
      <p>사용자가 단추를 누르면 (아직 정하지 않은) <code>on_image_open</code> 콜백 메서드를 호출하여 그림을 이 함수의 인자로 전달하라고 GTK에 지시할 때 <code>connect</code> 메서드를 사용하면 됩니다. 다음 섹션에서 <em>콜백</em>을 정의하겠습니디.</p>
      <p>콜백 함수에서 <code>window</code>위젯과 <code>image</code> 위젯에 접근해야합니다. 이게 바로 클래스 상단에서 전용 멤버 인스턴스로 설정한 이유입니다.</p>
    </item>
    <item>
      <p>마지막으로 <code>connect</code> 호출에서는 창을 닫았을 때 프로그램을 끝낼지 확인합니다. 안주타에서 만든 코드는 <link href="http://www.valadoc.org/gtk+-2.0/Gtk.main_quit.html"><code>Gtk.main_quit</code></link>를 호출하는 <code>on_destroy</code>  콜백 메서드를 호출하지만, 시그널을 <code>main_quit</code>에 바로 연결하는게 더 쉽습니다. <code>on_destroy</code> 메서드를 지울 수 있습니다.</p>
    </item>
  </steps>
</section>

<section id="image">
  <title>그림 표시</title>
  <p>앞서 언급한 단추의 <code>clicked</code> 시그널을 처리할 시그널 핸들러를 정의하겠습니다. 이 코드를 생성자 다음에 추가하십시오:</p>
  <code mime="text/x-csharp">
public void on_open_image (Button self) {
	var filter = new FileFilter ();
	var dialog = new FileChooserDialog ("Open image",
	                                    window,
	                                    FileChooserAction.OPEN,
	                                    Stock.OK,     ResponseType.ACCEPT,
	                                    Stock.CANCEL, ResponseType.CANCEL);
	filter.add_pixbuf_formats ();
	dialog.add_filter (filter);

	switch (dialog.run ())
	{
		case ResponseType.ACCEPT:
			var filename = dialog.get_filename ();
			image.set_from_file (filename);
			break;
		default:
			break;
	}
	dialog.destroy ();
}
</code>
  <p>좀 복잡하니 하나씩 살펴보도록 하죠:</p>
  <note><p>시그널 핸들러는 시그널을 어딘가에서 내보냈을 때 콜백 함수를 호출하게 하는 방식입니다. 이 용어는 서로 바꿔서 사용합니다.</p></note>
  <list>
    <item>
      <p>콜백 메서드의 첫번째 인자는 항상 시그널을 보낸 위젯입니다. 때로는 뒤 따라오는 다른 인자가 시그널에 관련이 있지만, <em>clicked</em>는 그렇지 않습니다.</p>
      <p>이 경우 <code>button</code>에서 <code>on_open_image</code> 콜백 함수에 연결한 <code>clicked</code>  시그널을 내보냅니다:</p>
<code mime="text/x-csharp">
        button.clicked.connect (on_open_image);
</code>

  <p><code>on_open_image</code> 메서드는 시그널을 방출한 단추를 인저로 취합니다:</p>
 <code mime="text/x-csharp">
        public void on_open_image (Button self)
</code>
    </item>
    <item>
      <p>다음 흥미로운 부분은 파일을 선택하는 대화상자를 만드는 부분입니다. <link href="http://www.valadoc.org/gtk+-3.0/Gtk.FileChooserDialog.html"><code>FileChooserDialog</code></link>의 생성자는 대화 상자 제목, 대화 상자의 상위 창, 단추 갯수와 각각의 값 같은 몇가지 옵션을 취합니다.</p>
      <p>직접 "취소" 또는 "열기"라고 입력하는 대신, Gtk에서 가져온 <link href="http://unstable.valadoc.org/gtk+-3.0/Gtk.Stock.html"><em>stock</em></link> 단추 이름을 사용하고 있음을 참고하십시오. 스톡 이름을 사용하면 사용자의 언어로 이미 번역한 단추 레이블을 사용합니다.</p>
    </item>
    <item>
      <p>다음 두 줄은 <gui>열기</gui> 대화 상자에서 <em>GtkImage</em>로만 열 수 있는 파일을 표시하도록 제한합니다. 필터 객체를 우선 만듭니다. 그 다음 <link href="http://www.valadoc.org/gdk-pixbuf-2.0/Gdk.Pixbuf.html"><code>Gdk.Pixbuf</code></link>에서 지원하는 파일 종류(PNG와 JPEG 같은 대부분의 그림 형식)를 필터에 추가합니다. 마지막으로 이 필터를 <gui>열기</gui> 대화 상자의 필터로 설정합니다.</p>
    </item>
    <item>
      <p><link href="http://www.valadoc.org/gtk+-3.0/Gtk.Dialog.run.html"><code>dialog.run</code></link>은 <gui>열기</gui> 대화 상자를 표시합니다. 대화 상자는 사용자의 그림 선택을 기다립니다. 사용자가 그림을 선택하면 <code>dialog.run</code> 에서 <code>ResponseType.ACCEPT</code> 값을 반환합니다(<gui>취소</gui>를 누르면 <code>ResponseType.CANCEL</code> 값을 반환합니다). <code>switch</code> 구문에서는 어떤 값을 반환했는지 확인합니다.</p>
    </item>
    <item>
      <p>사용자가 <gui>열기</gui>를 눌렀다고 한 상황에서, 다음 줄에서 사용자가 선택한 그림의 파일 이름을 가져오고,  <code>GtkImage</code> 위젯으로 선택한 그림을 불러오고 화면에 표시합니다.</p>
    </item>
    <item>
      <p>이 메서드의 마지막 줄에서는 <gui>열기</gui> 대화상자는 더 이상 필요 없으니 해체합니다.</p>
      <p>해체할 때는 대화상자를 자동으로 숨깁니다.</p>
    </item>
  </list>
</section>

<section id="run">
  <title>프로그램 빌드 및 실행</title>
  <p>모든 코드를 실행할 준비가 됐습니다. <guiseq><gui>빌드</gui><gui>프로젝트 빌드</gui></guiseq>를 눌러 프로젝트 전체를 다시 빌드하고, <guiseq><gui>실행</gui><gui>실행</gui></guiseq>을 눌러 프로그램을 시작하십시오.</p>
  <p>아직 끝나지 않았다면, 대화상자에 나타난 <file>src/image-viewer</file> 프로그램을 선택하십시오. 마지막으로 <gui>실행</gui>을 선택하고 즐기시지요!</p>
</section>

<section id="impl">
  <title>참조 구현체</title>
  <p>지침서를 따라하는 실행하는 과정에 문제가 있다면, <link href="image-viewer/image-viewer.vala">참조 코드</link>와 여러분의 코드를 비교해보십시오.</p>
</section>

<section id="next">
  <title>다음 단계</title>
  <p>여기 간단한 시험 프로그램에 여러분이 추가로 넣을 수 있는 몇가지 아이디어가 있습니다:</p>
  <list>
  <item><p>창을 열었을 때 지정 크기로 시작하도록 설정하십시오. 예를 들면 200 X 200 픽셀 크기입니다.</p></item>
   <item>
     <p>파일을 선택하기 보단 디렉터리를 선택하게 하고, 디렉터리의 모든 그림을 보여줄 수 있는 컨트롤을 제어 기능을 제공합니다.</p>
   </item>
   <item>
     <p>사용자가 그림을 불러오고 수정한 그림을 저장할 때 임의 필터와 효과를 그림에 적용하십시오.</p>
     <p><link href="http://www.gegl.org/api.html">GEGL</link>에서는 강력한 그림 편집 기능을 제공합니다.</p>
   </item>
   <item>
     <p>네트워크 공유, 스캐너, 다른 복잡한 공급원에서 그림을 불러올 수 있습니다.</p>
     <p>네트워크 파일 전송 같은 동작을 처리할 때 <link href="http://library.gnome.org/devel/gio/unstable/">GIO</link>를 사용할 수 있습니다. 그리고 스캐너를 다룰 때는 <link href="http://library.gnome.org/devel/gnome-scan/unstable/">그놈 스캔</link>을 활용하시면 됩니다.</p>
   </item>
  </list>
</section>

</page>
