<?xml version="1.0" encoding="utf-8"?>
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" xmlns:xi="http://www.w3.org/2001/XInclude" type="guide" style="task" id="textview.js" xml:lang="ko">
<info>
<title type="text">TextView (JavaScript)</title>
<link type="guide" xref="beginner.js#multiline"/>
<link type="seealso" xref="button.js"/>
<link type="seealso" xref="grid.js"/>
<link type="seealso" xref="GtkApplicationWindow.js"/>
<link type="seealso" xref="label.js"/>
<revision version="0.1" date="2012-06-28" status="draft"/>
<credit type="author copyright">
<name>Taryn Fox</name>
<email its:translate="no">jewelfox@fursona.net</email>
<years>2012</years>
</credit>
<desc>다중 행 텍스트 편집기</desc>
<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</mal:years>
</mal:credit>
</info>
<title>TextView</title>
<media type="image" mime="image/png" src="media/textviewpenguinchat.png"/>
<p>TextView는 정말(아니면 최소한 보통) 세 객체의 모음으로 이루어져있습니다.</p>
<list>
<item><p>하단에는 <link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.TextBuffer.html">TextBuffer</link>가 있습니다. TextBuffer는 텍스트를 저장해둡니다.</p></item>
<item><p>가운데에는 <link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.TextView.html">TextView</link>가 있는데 버퍼의 텍스트를 보고 편집할 수 있게 하는 위젯입니다. 텍스트가 얼마나 있느냐에 따라 자동으로 크기 조절 합니다.</p></item>
<item><p>자동으로 크기 조절을 해서 TextView를 이상하게 보이지 않게 할 수 있으므로, 보통 ScrolledWindow의 안에 둡니다. 이름이 있는데도 불구, 제목 표시줄과 X 단추가 있는 실제 창이 아닙니다. 더 관리하기 쉬운 TextView에서 창처럼 동작하며, 여러분이 만들려는 프로그램에 넣을 수 있는 위젯입니다. 버퍼의 텍스트가 공간을 맞추기에 너무 많다면, 스크롤 표시줄이 나타납니다.</p></item>
</list>
<p>TextView에 나타난 텍스트를 바꾸려면 TextBuffer가 실제로 텍스트 내용을 가지고 있으니 TextBuffer에서 처리하십시오. 누가 어떤 텍스트를 입력하는지 여러분이 보려고 할 떄도 동일합니다. 여기 예제 프로그램에서는 펭귄으로 가장한 누군가와 대화하고, "fish" 단어가 어딘가에 있는지 TextBuffer를 확인합니다.</p>
<note><p>실제로 수많은 펭귄의 수가 빠르게 줄어가고 있는데, 기후가 바뀌어 펭귄이 살아갈 터전의 빙하가 녹고 펭귄이 먹는 물고기가 줄어가기 때문입니다. 이 전제를 기반으로 만든 (약간은 바보 같을지도 모르는) 그놈 게임을 즐겨보고 싶으시다면 <link href="http://pingus.seul.org/">핑구스</link>를 찾아보십시오.</p></note>
<links type="section"/>
<section id="imports">
<title>가져올 라이브러리</title>
<code mime="application/javascript">
#!/usr/bin/gjs
const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
</code>
<p>이 프로그램을 실행할 때 가져올 라이브러리입니다. 시작 부분에 항상 gjs가 필요함을 알리는 줄을 작성해야 함을 기억하십시오.</p>
</section>
<section id="applicationwindow">
<title>프로그램 창 만들기</title>
<code mime="application/javascript">
const TextViewExample = new Lang.Class ({
Name: 'TextView Example',
// Create the application itself
_init: function () {
this.application = new Gtk.Application ({
application_id: 'org.example.jstextview' });
// Connect 'activate' and 'startup' signals to the callback functions
this.application.connect('activate', Lang.bind(this, this._onActivate));
this.application.connect('startup', Lang.bind(this, this._onStartup));
},
// Callback function for 'activate' signal presents windows when active
_onActivate: function () {
this._window.present ();
},
// Callback function for 'startup' signal builds the UI
_onStartup: function () {
this._buildUI ();
},
</code>
<p>이 예제의 모든 코드는 TextViewExample 클래스에 들어갑니다. 위 코드는 위젯과 창이 들어가는 <link href="http://www.roojs.com/seed/gir-1.2-gtk-3.0/gjs/Gtk.Application.html">Gtk.Application</link>를 만듭니다.</p>
<code mime="application/javascript">
// Build the application's UI
_buildUI: function () {
// Create the application window
this._window = new Gtk.ApplicationWindow ({
application: this.application,
window_position: Gtk.WindowPosition.CENTER,
title: "Talk to a Penguin",
default_height: 400,
default_width: 440,
border_width: 20 });
</code>
<p>_buildUI 함수는 프로그램 사용자 인터페이스를 만드는 모든 코드를 넣는 곳입니다. 첫 단계에서는 모든 위젯을 우겨넣을 새 <link xref="GtkApplicationWindow.js">Gtk.ApplicationWindow</link>를 만듭니다.</p>
</section>
<section id="textview">
<title>TextView 만들기</title>
<code mime="application/javascript">
// Create a label for the penguin to talk to you
this._penguin = new Gtk.Label ({
height_request: 180,
width_request: 400,
label: "Squaaaak?",
wrap: true });
</code>
<p>이 예제의 첫단계에서는 펭귄이 여러분에게 무언가 할 말을 넣을 때 쓸 <link xref="label.js">Label</link>을 만듭니다. 줄바꿈 속성을 true로 설정하여 텍스트 줄을 알아서 바꾸게 한 채로 텍스트를 설정하겠지만, TextView 자체에서 더 세밀한 설정이 가능하기에 다른 방식으로 해보겠습니다.</p>
<code mime="application/javascript">
// Create a textview for you to talk to the penguin
this.buffer = new Gtk.TextBuffer();
this._textView = new Gtk.TextView ({
buffer: this.buffer,
editable: true,
wrap_mode: Gtk.WrapMode.WORD });
</code>
<p>첫 단계로 내용을 넣을 TextButter를 만듭니다. 그 다음 TextView를 만들고, 앞서 만든 TextButter를 버퍼로 활용하라고 지시하겠습니다. 또한 새로운 내용을 입력할 수 있게 할 목적으로 편집 가능하게 설정하겠습니다.</p>
<p>wrap_mode 속성은 네가지 각각의 <link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.WrapMode.html">WrapModes</link> 중 하나를 선택하게 합니다. 예로, Gtk.WrapMode.CHAR는 페이지 모서리에 줄 끝이 도달하면 단어 중간을 잘라 줄을 바꿉니다. 대부분 사람은 줄이 너무 길면 단어 단위로 자동으로 줄을 바꿔주는 Gtk.WrapMode.WORD 옵션을 사용할지도 모릅니다.</p>
<code mime="application/javascript">
// Create a "scrolled window" to put your textview in so it will scroll
this._scrolled = new Gtk.ScrolledWindow ({
hscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
shadow_type: Gtk.ShadowType.ETCHED_IN,
height_request: 180,
width_request: 400, });
// Put the textview into the scrolled window
this._scrolled.add_with_viewport (this._textView);
</code>
<p>ScrolledWindow를 만들고 수직 수평 방향으로 너무 크면 자동으로 스크롤하게 설정하겠습니다. 또한 멋들어지게 보이도록 잘 다듬은 테두리를 설정하겠습니다. 그 다음, TextView에 넣고 ScrolledWindow에 뷰포트를 제공하라고 지시하겠습니다.</p>
</section>
<section id="ui">
<title>사용자 인터페이스 나머지 부분 만들기</title>
<code mime="application/javascript">
// Create a grid to organize them in
this._grid = new Gtk.Grid ({
halign: Gtk.Align.CENTER,
valign: Gtk.Align.CENTER });
// Put the label and textview in the grid one on top of the other
this._grid.attach (this._penguin, 0, 0, 1, 1);
this._grid.attach (this._scrolled, 0, 1, 1, 1);
</code>
<p>처음 <link xref="grid.js">Grid</link> 부분에서 Label과 ScrolledWindow를 만들어넣겠습니다.</p>
<code mime="application/javascript">
// Create a button to send your message to the penguin
this._send = new Gtk.Button ({
halign: Gtk.Align.END,
margin_top: 20,
label: "Send" });
this._send.connect ('clicked', Lang.bind (this, this._chat));
// Create a grid that will have the other grid on top and the button on bottom
this._mainGrid = new Gtk.Grid ({
halign: Gtk.Align.CENTER,
valign: Gtk.Align.CENTER });
// Add the other grid and the button to the main grid
this._mainGrid.attach (this._grid, 0, 0, 1, 1);
this._mainGrid.attach (this._send, 0, 1, 1, 1);
</code>
<p>펭귄에게 메시지를 보낼 <link xref="button.js">Button</link>를 만들고, 상단에는 다른 새 Grid를 하단에는 Button을 넣겠습니다. 이 Button에는 상단에 여백을 주어 ScrolledWindow와 찰싹 붙어있지 않게 하겠습니다.</p>
<code mime="application/javascript">
// Attach the main grid to the window
this._window.add (this._mainGrid);
// Show the window and all child widgets
this._window.show_all();
},
</code>
<p>마지막으로 창에 메인 Grid를 붙이고, 프로그램을 실행할 때 창과 창 안에 있는 모든 요소를 나타내게 하겠습니다.</p>
</section>
<section id="function">
<title>펭귄의 응답을 처리하는 함수</title>
<code mime="application/javascript">
_chat: function () {
// Create a random number to determine what the penguin says
this.number = Math.floor ((Math.random() * 3) + 1);
// Did you actually say anything?
if (this.buffer.text) {
// Did you mention fish?
if (this.buffer.text.match (/fish/gi)) {
// Have the penguin squaak about fish
if (this.number == 1)
this._penguin.set_label ("FISH!");
else if (this.number == 2)
this._penguin.set_label ("Fish fish fish fish. Fish!");
else
this._penguin.set_label ("Fish? Fish fish fish. Fish fish. FISH!");
}
// I guess you didn't mention fish
else {
// Have the penguin talk about penguinny stuff
if (this.number == 1)
this._penguin.set_label ("SQUAAK!");
else if (this.number == 2)
this._penguin.set_label ("Ork ork ork ork squaak. Squaak squaak! *waves flippers*");
else
this._penguin.set_label ("Ork ork ork ork ork?");
}
}
// Clear the buffer
this.buffer.text = "";
// Give focus back to the textview so you don't have to click it again
this._textView.has_focus = true;
}
});
</code>
<p>여기에 펭귄이 아무렇게나 말하는 JavaScript 기본 함수를 사용합니다. 펭귄은 물고기를 좋아하니, 물고기를 언급하면 펭귄이 대답하게 하겠습니다. 따라서, TextBuffer에 내용을 반환하는 JavaScript 문자열 객체의 <file>this.buffer.text</file>에 있는 match 메서드를 사용하겠습니다.</p>
<p>보내기를 누를 떄마다 TextBuffer를 지울테니, 과정이 끝나면 <file>this.buffer.text</file> 값을 빈 문자열로 넣겠습니다. 그 다음 TextView에 포커스를 반환하여 입력하기 전에 굳이 누르지 않아도 계속 입력할 수 있게 하겠습니다.</p>
<code mime="application/javascript">
// Run the application
let app = new TextViewExample ();
app.application.run (ARGV);
</code>
<p>마지막으로 마무리한 TextViewExample 클래스의 새 인스턴스를 만들고 프로그램을 실행하도록 설정하겠습니다.</p>
</section>
<section id="complete">
<title>완전한 코드 예제</title>
<code mime="application/javascript" style="numbered">#!/usr/bin/gjs
imports.gi.versions.Gtk = '3.0';
const Gtk = imports.gi.Gtk;
class TextViewExample {
// Create the application itself
constructor() {
this.application = new Gtk.Application({
application_id: 'org.example.jstextview'
});
// Connect 'activate' and 'startup' signals to the callback functions
this.application.connect('activate', this._onActivate.bind(this));
this.application.connect('startup', this._onStartup.bind(this));
}
// Callback function for 'activate' signal presents windows when active
_onActivate() {
this._window.present();
}
// Callback function for 'startup' signal builds the UI
_onStartup() {
this._buildUI();
}
// Build the application's UI
_buildUI() {
// Create the application window
this._window = new Gtk.ApplicationWindow ({
application: this.application,
window_position: Gtk.WindowPosition.CENTER,
title: "Talk to a Penguin",
default_height: 400,
default_width: 440,
border_width: 20 });
// Create a label for the penguin to talk to you
this._penguin = new Gtk.Label ({
height_request: 180,
width_request: 400,
label: "Squaaaak?",
wrap: true });
// Create a textview for you to talk to the penguin
this.buffer = new Gtk.TextBuffer();
this._textView = new Gtk.TextView ({
buffer: this.buffer,
editable: true,
wrap_mode: Gtk.WrapMode.WORD });
// Create a "scrolled window" to put your textview in so it will scroll
this._scrolled = new Gtk.ScrolledWindow ({
hscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
shadow_type: Gtk.ShadowType.ETCHED_IN,
height_request: 180,
width_request: 400, });
// Put the textview into the scrolled window
this._scrolled.add_with_viewport (this._textView);
// Create a grid to organize them in
this._grid = new Gtk.Grid ({
halign: Gtk.Align.CENTER,
valign: Gtk.Align.CENTER });
// Put the label and textview in the grid one on top of the other
this._grid.attach (this._penguin, 0, 0, 1, 1);
this._grid.attach (this._scrolled, 0, 1, 1, 1);
// Create a button to send your message to the penguin
this._send = new Gtk.Button ({
halign: Gtk.Align.END,
margin_top: 20,
label: "Send" });
this._send.connect ('clicked', this._chat.bind(this));
// Create a grid that will have the other grid on top and the button on bottom
this._mainGrid = new Gtk.Grid ({
halign: Gtk.Align.CENTER,
valign: Gtk.Align.CENTER });
// Add the other grid and the button to the main grid
this._mainGrid.attach (this._grid, 0, 0, 1, 1);
this._mainGrid.attach (this._send, 0, 1, 1, 1);
// Attach the main grid to the window
this._window.add (this._mainGrid);
// Show the window and all child widgets
this._window.show_all();
}
_chat() {
// Create a random number to determine what the penguin says
this.number = Math.floor ((Math.random() * 3) + 1);
// Did you actually say anything?
if (this.buffer.text) {
// Did you mention fish?
if (this.buffer.text.match (/fish/gi)) {
// Have the penguin squaak about fish
if (this.number == 1)
this._penguin.set_label ("FISH!");
else if (this.number == 2)
this._penguin.set_label ("Fish fish fish fish. Fish!");
else
this._penguin.set_label ("Fish? Fish fish fish. Fish fish. FISH!");
}
// I guess you didn't mention fish
else {
// Have the penguin talk about penguinny stuff
if (this.number == 1)
this._penguin.set_label ("SQUAAK!");
else if (this.number == 2)
this._penguin.set_label ("Ork ork ork ork squaak. Squaak squaak! *waves flippers*");
else
this._penguin.set_label ("Ork ork ork ork ork?");
}
}
// Clear the buffer
this.buffer.text = "";
// Give focus back to the textview so you don't have to click it again
this._textView.has_focus = true;
}
};
// Run the application
let app = new TextViewExample ();
app.application.run (ARGV);
</code>
</section>
<section id="in-depth">
<title>자세한 문서</title>
<list>
<item><p><link href="http://www.roojs.com/seed/gir-1.2-gtk-3.0/gjs/Gtk.Application.html">Gtk.Application</link></p></item>
<item><p><link href="http://developer.gnome.org/gtk3/stable/GtkApplicationWindow.html">Gtk.ApplicationWindow</link></p></item>
<item><p><link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.Button.html">Gtk.Button</link></p></item>
<item><p><link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.Grid.html">Gtk.Grid</link></p></item>
<item><p><link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.Label.html">Gtk.Label</link></p></item>
<item><p><link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.RadioButton.html">Gtk.RadioButton</link></p></item>
<item><p><link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.ScrolledWindow.html">Gtk.ScrolledWindow</link></p></item>
<item><p><link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.TextBuffer.html">Gtk.TextBuffer</link></p></item>
<item><p><link href="http://www.roojs.org/seed/gir-1.2-gtk-3.0/gjs/Gtk.TextView.html">Gtk.TextView</link></p></item>
</list>
</section>
</page>